~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/addins/AspNet/MonoDevelop.AspNet/MonoDevelop.AspNet.Parser/PageInfo.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
//
28
28
 
29
29
using System;
30
 
using MonoDevelop.AspNet.Parser.Dom;
31
30
using System.Collections.Generic;
32
31
using ICSharpCode.NRefactory.TypeSystem;
33
32
 
 
33
using MonoDevelop.AspNet.StateEngine;
 
34
using MonoDevelop.Xml.StateEngine;
 
35
 
34
36
namespace MonoDevelop.AspNet.Parser
35
37
{
36
38
        
59
61
                public IList<string> Imports { get { return imports; } }
60
62
                public IList<string> Implements { get { return imports; } }
61
63
                public IList<AssemblyDirective> Assemblies { get { return assemblies; } }
62
 
                
63
 
                public IEnumerable<Error> Populate (RootNode node, List<Error> errors)
64
 
                {
65
 
                        var visitor = new PageInfoVisitor (this, errors);
66
 
                        node.AcceptVisit (visitor);
67
 
                        return visitor.Errors;
68
 
                }
69
 
                
70
 
                private class PageInfoVisitor : Visitor
71
 
                {
72
 
                        PageInfo info;
73
 
                        List<Error> errors;
74
 
                        
75
 
                        public PageInfoVisitor (PageInfo info, List<Error> errors)
76
 
                        {
77
 
                                this.info = info;
78
 
                                this.errors = errors;
79
 
                        }
80
 
                        
81
 
                        public List<Error> Errors { get { return errors; } }
82
 
                        
83
 
                        public override void Visit (DirectiveNode node)
84
 
                        {
85
 
                                var atts = node.Attributes;
86
 
                                
87
 
                                switch (node.Name.ToLowerInvariant ()) {
88
 
                                case "page":
89
 
                                        SetSubtype (WebSubtype.WebForm, node);
90
 
                                        if (atts == null)
91
 
                                                return;
92
 
                                        info.MasterPageFile = atts ["masterpagefile"] as string;
93
 
                                        break;
94
 
                                case "control":
95
 
                                        SetSubtype (WebSubtype.WebControl, node);
96
 
                                        break;
97
 
                                case "webservice":
98
 
                                        SetSubtype (WebSubtype.WebService, node);
99
 
                                        break;
100
 
                                case "webhandler":
101
 
                                        SetSubtype (WebSubtype.WebHandler, node);
102
 
                                        break;
103
 
                                case "application":
104
 
                                        SetSubtype (WebSubtype.Global, node);
105
 
                                        break;
106
 
                                case "master":
107
 
                                        SetSubtype (WebSubtype.MasterPage, node);
108
 
                                        break;
109
 
                                case "mastertype":
110
 
                                        if (info.MasterPageTypeVPath != null || info.MasterPageTypeName != null) {
111
 
                                                Add (ErrorType.Error, node, "Unexpected second mastertype directive", node.Name);
112
 
                                                return;
113
 
                                        }
114
 
                                        if (atts == null)
115
 
                                                return;
116
 
                                        info.MasterPageTypeName = atts["typename"] as string;
117
 
                                        info.MasterPageTypeVPath = atts["virtualpath"] as string;
118
 
                                        if (string.IsNullOrEmpty (info.MasterPageTypeName) == string.IsNullOrEmpty (info.MasterPageTypeVPath))
119
 
                                                Add (ErrorType.Error, node, "Mastertype directive must have non-empty 'typename' or 'virtualpath' attribute");
120
 
                                        break;
121
 
                                case "register":
122
 
                                        if (atts == null)
123
 
                                                return;
124
 
                                        if (atts ["TagPrefix"] != null) {
125
 
                                                if ((atts ["TagName"] != null) && (atts ["Src"] != null))
126
 
                                                        info.registeredTags.Add (new ControlRegisterDirective (node));
127
 
                                                else if ((atts ["Namespace"] != null) && (atts ["Assembly"] != null))
128
 
                                                        info.registeredTags.Add (new AssemblyRegisterDirective (node));
129
 
                                        }
130
 
                                        break;
131
 
                                case "assembly":
132
 
                                        if (atts == null)
133
 
                                                return;
134
 
                                        var assembly = new AssemblyDirective (atts ["name"] as string, atts ["src"] as string);
135
 
                                        if (assembly.IsValid ())
136
 
                                                info.assemblies.Add (assembly);
137
 
                                        else
138
 
                                                Add (ErrorType.Error, node, "Assembly directive must have non-empty 'name' or 'src' attribute");
139
 
                                        break;
140
 
                                case "import":
141
 
                                        if (atts == null)
142
 
                                                return;
143
 
                                        var ns = atts ["namespace"] as string;
144
 
                                        if (!string.IsNullOrEmpty (ns))
145
 
                                                info.imports.Add (ns);
146
 
                                        else
147
 
                                                Add (ErrorType.Error, node, "Import directive must have non-empty 'namespace' attribute");
148
 
                                        break;
149
 
                                case "implements":
150
 
                                        if (atts == null)
151
 
                                                return;
152
 
                                        var interf = atts ["interface"] as string;
153
 
                                        if (!string.IsNullOrEmpty (interf))
154
 
                                                info.implements.Add (interf);
155
 
                                        else
156
 
                                                Add (ErrorType.Error, node, "Implements directive must have non-empty 'interface' attribute");
157
 
                                        break;
158
 
                                default:
159
 
                                        break;
160
 
                                }
161
 
                        }
162
 
                        
163
 
                        void Add (ErrorType type, Node node, string message, params object[] args)
164
 
                        {
165
 
                                errors.Add (new Error (type, string.Format (message, args), node.Location.BeginLine, node.Location.BeginColumn));
166
 
                        }
167
 
                        
168
 
                        void SetSubtype (WebSubtype type, DirectiveNode node)
169
 
                        {
170
 
                                if (info.Subtype != WebSubtype.None) {
171
 
                                        Add (ErrorType.Error, node, "Unexpected directive {0}", node.Name);
172
 
                                        return;
173
 
                                }
174
 
                                
175
 
                                info.Subtype = type;
176
 
                                
177
 
                                if (node.Attributes == null)
178
 
                                        return;
179
 
                                
180
 
                                info.InheritedClass = node.Attributes ["inherits"] as string;
181
 
                                if (info.ClassName == null)
182
 
                                        info.ClassName = node.Attributes ["classname"] as string;
183
 
                                info.CodeBehindFile = node.Attributes ["codebehind"] as string;
184
 
                                info.Language = node.Attributes ["language"] as string;
185
 
                                info.CodeFile = node.Attributes ["codefile"] as string;
186
 
                        }
187
 
                        
188
 
                        public override void Visit (TextNode node)
189
 
                        {
190
 
                                int start = node.Text.IndexOf ("<!DOCTYPE");
191
 
                                if (start < 0)
192
 
                                        return;
193
 
                                int end = node.Text.IndexOf (">", start);
194
 
                                info.DocType = node.Text.Substring (start, end - start + 1);
195
 
                                QuickExit = true;
196
 
                        }
197
 
        
198
 
                        
199
 
                        public override void Visit (TagNode node)
200
 
                        {
201
 
                                //as soon as tags are declared, doctypes and directives must been set
202
 
                                QuickExit = true;
203
 
                        }
204
 
                }
 
64
 
 
65
                #region XDocument parsing
 
66
 
 
67
                public void Populate (XDocument xDoc, List<Error> errors)
 
68
                {
 
69
                        foreach (XNode node in xDoc.AllDescendentNodes) {
 
70
                                if (node is AspNetDirective) {
 
71
                                        HandleDirective (node as AspNetDirective, errors);
 
72
                                } else if (node is XDocType) {
 
73
                                        HandleDocType (node as XDocType);
 
74
                                } else if (node is XElement) {
 
75
                                        // quit the parsing when reached the html nodes
 
76
                                        return;
 
77
                                }
 
78
                        }
 
79
                }
 
80
 
 
81
                string GetAttributeValueCI (XAttributeCollection attributes, string key)
 
82
                {
 
83
                        return attributes.GetValue (new XName (key), true) ?? string.Empty;
 
84
                }
 
85
 
 
86
                void HandleDirective (AspNetDirective directive, List<Error> errors)
 
87
                {
 
88
                        switch (directive.Name.Name.ToLowerInvariant ()) {
 
89
                        case "page":
 
90
                                MasterPageFile = GetAttributeValueCI (directive.Attributes, "masterpagefile");
 
91
                                SetSubtype (WebSubtype.WebForm, directive, errors);
 
92
                                break;
 
93
                        case "control":
 
94
                                SetSubtype (WebSubtype.WebControl, directive, errors);
 
95
                                break;
 
96
                        case "webservice":
 
97
                                SetSubtype (WebSubtype.WebService, directive, errors);
 
98
                                break;
 
99
                        case "webhandler":
 
100
                                SetSubtype (WebSubtype.WebHandler, directive, errors);
 
101
                                break;
 
102
                        case "application":
 
103
                                SetSubtype (WebSubtype.Global, directive, errors);
 
104
                                break;
 
105
                        case "master":
 
106
                                SetSubtype (WebSubtype.MasterPage, directive, errors);
 
107
                                break;
 
108
                        case "mastertype":
 
109
                                if (MasterPageTypeVPath != null || MasterPageTypeName != null) {
 
110
                                        errors.Add (new Error (ErrorType.Error, "Unexpected second mastertype directive", directive.Region));
 
111
                                        return;
 
112
                                }
 
113
                                MasterPageTypeName = GetAttributeValueCI (directive.Attributes, "typename");
 
114
                                MasterPageTypeVPath = GetAttributeValueCI (directive.Attributes, "virtualpath");
 
115
                                if (string.IsNullOrEmpty (MasterPageTypeName) == string.IsNullOrEmpty (MasterPageTypeVPath))
 
116
                                        errors.Add (new Error (
 
117
                                                ErrorType.Error,
 
118
                                                "Mastertype directive must have non-empty 'typename' or 'virtualpath' attribute",
 
119
                                                directive.Region
 
120
                                        )
 
121
                                        );
 
122
                                break;
 
123
                        case "register":
 
124
                                string tagPrefix = GetAttributeValueCI (directive.Attributes, "tagprefix");
 
125
                                string tagName = GetAttributeValueCI (directive.Attributes, "tagname");
 
126
                                string src = GetAttributeValueCI (directive.Attributes, "src");
 
127
                                string nspace = GetAttributeValueCI (directive.Attributes, "namespace");
 
128
                                string assembly = GetAttributeValueCI (directive.Attributes, "assembly");
 
129
                                if (!string.IsNullOrEmpty (tagPrefix)) {
 
130
                                        if (!string.IsNullOrEmpty (tagName) && !string.IsNullOrEmpty (src))
 
131
                                                registeredTags.Add (new ControlRegisterDirective (tagPrefix, tagName, src));
 
132
                                        else if (!string.IsNullOrEmpty (nspace) && !string.IsNullOrEmpty (assembly))
 
133
                                                registeredTags.Add (new AssemblyRegisterDirective (tagPrefix, nspace, assembly));
 
134
                                }
 
135
                                break;
 
136
                        case "assembly":
 
137
                                var assm = new AssemblyDirective (
 
138
                                        GetAttributeValueCI (directive.Attributes, "name"),
 
139
                                        GetAttributeValueCI (directive.Attributes, "src"));
 
140
                                if (assm.IsValid ())
 
141
                                        assemblies.Add (assm);
 
142
                                else
 
143
                                        errors.Add (new Error (
 
144
                                                ErrorType.Error,
 
145
                                                "Assembly directive must have non-empty 'name' or 'src' attribute",
 
146
                                                directive.Region
 
147
                                        )
 
148
                                        );
 
149
                                break;
 
150
                        case "import":
 
151
                                string ns = GetAttributeValueCI (directive.Attributes, "namespace");
 
152
                                if (!string.IsNullOrEmpty (ns))
 
153
                                        imports.Add (ns);
 
154
                                else
 
155
                                        errors.Add (new Error (
 
156
                                                ErrorType.Error,
 
157
                                                "Import directive must have non-empty 'namespace' attribute",
 
158
                                                directive.Region
 
159
                                        )
 
160
                                        );
 
161
                                break;
 
162
                        case "implements":
 
163
                                string interf = GetAttributeValueCI (directive.Attributes, "interface");
 
164
                                if (!string.IsNullOrEmpty (interf))
 
165
                                        implements.Add (interf);
 
166
                                else
 
167
                                        errors.Add (new Error (
 
168
                                                ErrorType.Error,
 
169
                                                "Implements directive must have non-empty 'interface' attribute",
 
170
                                                directive.Region
 
171
                                        )
 
172
                                        );
 
173
                                break;
 
174
                        default:
 
175
                                break;
 
176
                        }
 
177
                }
 
178
 
 
179
                void SetSubtype (WebSubtype type, AspNetDirective directive, List<Error> errors)
 
180
                {
 
181
                        if (Subtype != WebSubtype.None) {
 
182
                                errors.Add (new Error (ErrorType.Error, "Unexpected directive " + directive.Name.FullName, directive.Region));
 
183
                                return;
 
184
                        }
 
185
                        
 
186
                        Subtype = type;
 
187
                                                
 
188
                        InheritedClass = GetAttributeValueCI (directive.Attributes, "inherits");
 
189
                        if (ClassName == null)
 
190
                                ClassName = GetAttributeValueCI (directive.Attributes, "classname");
 
191
                        CodeBehindFile = GetAttributeValueCI (directive.Attributes, "codebehind");
 
192
                        Language = GetAttributeValueCI (directive.Attributes, "language");
 
193
                        CodeFile = GetAttributeValueCI (directive.Attributes, "codefile");
 
194
                }
 
195
 
 
196
                void HandleDocType (XDocType docType)
 
197
                {
 
198
                        DocType = "<!DOCTYPE html";
 
199
                        if (!string.IsNullOrEmpty (docType.PublicFpi))
 
200
                                DocType += " \"" + docType.PublicFpi + "\"";
 
201
                        if (!string.IsNullOrEmpty (docType.Uri))
 
202
                                DocType += " \"" + docType.Uri + "\"";
 
203
                        DocType += ">";
 
204
                }
 
205
 
 
206
                #endregion
205
207
        }
206
208
        
207
209
        public abstract class RegisterDirective
209
211
                public RegisterDirective (string tagPrefix)
210
212
                {
211
213
                        this.TagPrefix = tagPrefix;
212
 
                }               
213
 
                
214
 
                public RegisterDirective (DirectiveNode node)
215
 
                {
216
 
                        TagPrefix = (string) node.Attributes ["TagPrefix"];
217
214
                }
218
215
                
219
216
                public string TagPrefix { get; private set; }
239
236
                        this.Assembly = assembly;
240
237
                }
241
238
                
242
 
                public AssemblyRegisterDirective (DirectiveNode node)
243
 
                        : base (node)
244
 
                {
245
 
                        Namespace = (string) node.Attributes ["Namespace"];
246
 
                        Assembly = (string) node.Attributes ["Assembly"];
247
 
                }
248
 
                
249
239
                public string Namespace { get; private set; }
250
240
                public string Assembly { get; private set; }
251
241
                
270
260
                        this.Src = src;
271
261
                }
272
262
                
273
 
                public ControlRegisterDirective (DirectiveNode node)
274
 
                        : base (node)
275
 
                {
276
 
                        TagName = (string) node.Attributes ["TagName"];
277
 
                        Src = (string) node.Attributes ["Src"];
278
 
                }
279
 
                
280
263
                public string TagName { get; private set; }
281
264
                public string Src { get; private set; }
282
265