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; } }
63
public IEnumerable<Error> Populate (RootNode node, List<Error> errors)
65
var visitor = new PageInfoVisitor (this, errors);
66
node.AcceptVisit (visitor);
67
return visitor.Errors;
70
private class PageInfoVisitor : Visitor
75
public PageInfoVisitor (PageInfo info, List<Error> errors)
81
public List<Error> Errors { get { return errors; } }
83
public override void Visit (DirectiveNode node)
85
var atts = node.Attributes;
87
switch (node.Name.ToLowerInvariant ()) {
89
SetSubtype (WebSubtype.WebForm, node);
92
info.MasterPageFile = atts ["masterpagefile"] as string;
95
SetSubtype (WebSubtype.WebControl, node);
98
SetSubtype (WebSubtype.WebService, node);
101
SetSubtype (WebSubtype.WebHandler, node);
104
SetSubtype (WebSubtype.Global, node);
107
SetSubtype (WebSubtype.MasterPage, node);
110
if (info.MasterPageTypeVPath != null || info.MasterPageTypeName != null) {
111
Add (ErrorType.Error, node, "Unexpected second mastertype directive", node.Name);
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");
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));
134
var assembly = new AssemblyDirective (atts ["name"] as string, atts ["src"] as string);
135
if (assembly.IsValid ())
136
info.assemblies.Add (assembly);
138
Add (ErrorType.Error, node, "Assembly directive must have non-empty 'name' or 'src' attribute");
143
var ns = atts ["namespace"] as string;
144
if (!string.IsNullOrEmpty (ns))
145
info.imports.Add (ns);
147
Add (ErrorType.Error, node, "Import directive must have non-empty 'namespace' attribute");
152
var interf = atts ["interface"] as string;
153
if (!string.IsNullOrEmpty (interf))
154
info.implements.Add (interf);
156
Add (ErrorType.Error, node, "Implements directive must have non-empty 'interface' attribute");
163
void Add (ErrorType type, Node node, string message, params object[] args)
165
errors.Add (new Error (type, string.Format (message, args), node.Location.BeginLine, node.Location.BeginColumn));
168
void SetSubtype (WebSubtype type, DirectiveNode node)
170
if (info.Subtype != WebSubtype.None) {
171
Add (ErrorType.Error, node, "Unexpected directive {0}", node.Name);
177
if (node.Attributes == null)
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;
188
public override void Visit (TextNode node)
190
int start = node.Text.IndexOf ("<!DOCTYPE");
193
int end = node.Text.IndexOf (">", start);
194
info.DocType = node.Text.Substring (start, end - start + 1);
199
public override void Visit (TagNode node)
201
//as soon as tags are declared, doctypes and directives must been set
65
#region XDocument parsing
67
public void Populate (XDocument xDoc, List<Error> errors)
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
81
string GetAttributeValueCI (XAttributeCollection attributes, string key)
83
return attributes.GetValue (new XName (key), true) ?? string.Empty;
86
void HandleDirective (AspNetDirective directive, List<Error> errors)
88
switch (directive.Name.Name.ToLowerInvariant ()) {
90
MasterPageFile = GetAttributeValueCI (directive.Attributes, "masterpagefile");
91
SetSubtype (WebSubtype.WebForm, directive, errors);
94
SetSubtype (WebSubtype.WebControl, directive, errors);
97
SetSubtype (WebSubtype.WebService, directive, errors);
100
SetSubtype (WebSubtype.WebHandler, directive, errors);
103
SetSubtype (WebSubtype.Global, directive, errors);
106
SetSubtype (WebSubtype.MasterPage, directive, errors);
109
if (MasterPageTypeVPath != null || MasterPageTypeName != null) {
110
errors.Add (new Error (ErrorType.Error, "Unexpected second mastertype directive", directive.Region));
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 (
118
"Mastertype directive must have non-empty 'typename' or 'virtualpath' attribute",
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));
137
var assm = new AssemblyDirective (
138
GetAttributeValueCI (directive.Attributes, "name"),
139
GetAttributeValueCI (directive.Attributes, "src"));
141
assemblies.Add (assm);
143
errors.Add (new Error (
145
"Assembly directive must have non-empty 'name' or 'src' attribute",
151
string ns = GetAttributeValueCI (directive.Attributes, "namespace");
152
if (!string.IsNullOrEmpty (ns))
155
errors.Add (new Error (
157
"Import directive must have non-empty 'namespace' attribute",
163
string interf = GetAttributeValueCI (directive.Attributes, "interface");
164
if (!string.IsNullOrEmpty (interf))
165
implements.Add (interf);
167
errors.Add (new Error (
169
"Implements directive must have non-empty 'interface' attribute",
179
void SetSubtype (WebSubtype type, AspNetDirective directive, List<Error> errors)
181
if (Subtype != WebSubtype.None) {
182
errors.Add (new Error (ErrorType.Error, "Unexpected directive " + directive.Name.FullName, directive.Region));
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");
196
void HandleDocType (XDocType docType)
198
DocType = "<!DOCTYPE html";
199
if (!string.IsNullOrEmpty (docType.PublicFpi))
200
DocType += " \"" + docType.PublicFpi + "\"";
201
if (!string.IsNullOrEmpty (docType.Uri))
202
DocType += " \"" + docType.Uri + "\"";
207
209
public abstract class RegisterDirective