Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/html.dart

Issue 17932005: New analyzer_experimental snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Disable resolver tests Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // This code was auto-generated, is not intended to be edited, and is subject to 1 // This code was auto-generated, is not intended to be edited, and is subject to
2 // significant change. Please see the README file for more information. 2 // significant change. Please see the README file for more information.
3 library engine.html; 3 library engine.html;
4 import 'dart:collection'; 4 import 'dart:collection';
5 import 'java_core.dart'; 5 import 'java_core.dart';
6 import 'java_engine.dart'; 6 import 'java_engine.dart';
7 import 'source.dart'; 7 import 'source.dart';
8 import 'error.dart'; 8 import 'error.dart';
9 import 'instrumentation.dart'; 9 import 'instrumentation.dart';
10 import 'element.dart' show HtmlElementImpl; 10 import 'element.dart' show HtmlElementImpl;
11 import 'engine.dart' show AnalysisEngine; 11 import 'engine.dart' show AnalysisEngine;
12 /** 12 /**
13 * Instances of the class `Token` represent a token that was scanned from the in put. Each 13 * Instances of the class `Token` represent a token that was scanned from the in put. Each
14 * token knows which token follows it, acting as the head of a linked list of to kens. 14 * token knows which token follows it, acting as the head of a linked list of to kens.
15 *
15 * @coverage dart.engine.html 16 * @coverage dart.engine.html
16 */ 17 */
17 class Token { 18 class Token {
18 19
19 /** 20 /**
20 * The offset from the beginning of the file to the first character in the tok en. 21 * The offset from the beginning of the file to the first character in the tok en.
21 */ 22 */
22 int _offset = 0; 23 int _offset = 0;
23 24
24 /** 25 /**
(...skipping 11 matching lines...) Expand all
36 */ 37 */
37 TokenType _type; 38 TokenType _type;
38 39
39 /** 40 /**
40 * The lexeme represented by this token. 41 * The lexeme represented by this token.
41 */ 42 */
42 String _value; 43 String _value;
43 44
44 /** 45 /**
45 * Initialize a newly created token. 46 * Initialize a newly created token.
47 *
46 * @param type the token type (not `null`) 48 * @param type the token type (not `null`)
47 * @param offset the offset from the beginning of the file to the first charac ter in the token 49 * @param offset the offset from the beginning of the file to the first charac ter in the token
48 */ 50 */
49 Token.con1(TokenType type, int offset) { 51 Token.con1(TokenType type, int offset) {
50 _jtd_constructor_155_impl(type, offset); 52 _jtd_constructor_155_impl(type, offset);
51 } 53 }
52 _jtd_constructor_155_impl(TokenType type, int offset) { 54 _jtd_constructor_155_impl(TokenType type, int offset) {
53 _jtd_constructor_156_impl(type, offset, type.lexeme); 55 _jtd_constructor_156_impl(type, offset, type.lexeme);
54 } 56 }
55 57
56 /** 58 /**
57 * Initialize a newly created token. 59 * Initialize a newly created token.
60 *
58 * @param type the token type (not `null`) 61 * @param type the token type (not `null`)
59 * @param offset the offset from the beginning of the file to the first charac ter in the token 62 * @param offset the offset from the beginning of the file to the first charac ter in the token
60 * @param value the lexeme represented by this token (not `null`) 63 * @param value the lexeme represented by this token (not `null`)
61 */ 64 */
62 Token.con2(TokenType type2, int offset2, String value2) { 65 Token.con2(TokenType type2, int offset2, String value2) {
63 _jtd_constructor_156_impl(type2, offset2, value2); 66 _jtd_constructor_156_impl(type2, offset2, value2);
64 } 67 }
65 _jtd_constructor_156_impl(TokenType type2, int offset2, String value2) { 68 _jtd_constructor_156_impl(TokenType type2, int offset2, String value2) {
66 this._type = type2; 69 this._type = type2;
67 this._value = StringUtilities.intern(value2); 70 this._value = StringUtilities.intern(value2);
68 this._offset = offset2; 71 this._offset = offset2;
69 } 72 }
70 73
71 /** 74 /**
72 * Return the offset from the beginning of the file to the character after las t character of the 75 * Return the offset from the beginning of the file to the character after las t character of the
73 * token. 76 * token.
77 *
74 * @return the offset from the beginning of the file to the first character af ter last character 78 * @return the offset from the beginning of the file to the first character af ter last character
75 * of the token 79 * of the token
76 */ 80 */
77 int get end => _offset + length; 81 int get end => _offset + length;
78 82
79 /** 83 /**
80 * Return the number of characters in the node's source range. 84 * Return the number of characters in the node's source range.
85 *
81 * @return the number of characters in the node's source range 86 * @return the number of characters in the node's source range
82 */ 87 */
83 int get length => lexeme.length; 88 int get length => lexeme.length;
84 89
85 /** 90 /**
86 * Return the lexeme that represents this token. 91 * Return the lexeme that represents this token.
92 *
87 * @return the lexeme (not `null`) 93 * @return the lexeme (not `null`)
88 */ 94 */
89 String get lexeme => _value; 95 String get lexeme => _value;
90 96
91 /** 97 /**
92 * Return the next token in the token stream. 98 * Return the next token in the token stream.
99 *
93 * @return the next token in the token stream 100 * @return the next token in the token stream
94 */ 101 */
95 Token get next => _next; 102 Token get next => _next;
96 103
97 /** 104 /**
98 * Return the offset from the beginning of the file to the first character in the token. 105 * Return the offset from the beginning of the file to the first character in the token.
106 *
99 * @return the offset from the beginning of the file to the first character in the token 107 * @return the offset from the beginning of the file to the first character in the token
100 */ 108 */
101 int get offset => _offset; 109 int get offset => _offset;
102 110
103 /** 111 /**
104 * Return the previous token in the token stream. 112 * Return the previous token in the token stream.
113 *
105 * @return the previous token in the token stream 114 * @return the previous token in the token stream
106 */ 115 */
107 Token get previous => _previous; 116 Token get previous => _previous;
108 117
109 /** 118 /**
110 * Answer the token type for the receiver. 119 * Answer the token type for the receiver.
120 *
111 * @return the token type (not `null`) 121 * @return the token type (not `null`)
112 */ 122 */
113 TokenType get type => _type; 123 TokenType get type => _type;
114 124
115 /** 125 /**
116 * Return `true` if this token is a synthetic token. A synthetic token is a to ken that was 126 * Return `true` if this token is a synthetic token. A synthetic token is a to ken that was
117 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always 127 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always
118 * have a length of zero (`0`). 128 * have a length of zero (`0`).
129 *
119 * @return `true` if this token is a synthetic token 130 * @return `true` if this token is a synthetic token
120 */ 131 */
121 bool get isSynthetic => length == 0; 132 bool get isSynthetic => length == 0;
122 133
123 /** 134 /**
124 * Set the next token in the token stream to the given token. This has the sid e-effect of setting 135 * Set the next token in the token stream to the given token. This has the sid e-effect of setting
125 * this token to be the previous token for the given token. 136 * this token to be the previous token for the given token.
137 *
126 * @param token the next token in the token stream 138 * @param token the next token in the token stream
127 * @return the token that was passed in 139 * @return the token that was passed in
128 */ 140 */
129 Token setNext(Token token) { 141 Token setNext(Token token) {
130 _next = token; 142 _next = token;
131 token.previous = this; 143 token.previous = this;
132 return token; 144 return token;
133 } 145 }
134 String toString() => lexeme; 146 String toString() => lexeme;
135 147
136 /** 148 /**
137 * Set the previous token in the token stream to the given token. 149 * Set the previous token in the token stream to the given token.
150 *
138 * @param previous the previous token in the token stream 151 * @param previous the previous token in the token stream
139 */ 152 */
140 void set previous(Token previous2) { 153 void set previous(Token previous2) {
141 this._previous = previous2; 154 this._previous = previous2;
142 } 155 }
143 } 156 }
144 /** 157 /**
145 * Instances of `HtmlParseResult` hold the result of parsing an HTML file. 158 * Instances of `HtmlParseResult` hold the result of parsing an HTML file.
159 *
146 * @coverage dart.engine.html 160 * @coverage dart.engine.html
147 */ 161 */
148 class HtmlParseResult extends HtmlScanResult { 162 class HtmlParseResult extends HtmlScanResult {
149 163
150 /** 164 /**
151 * The unit containing the parsed information (not `null`). 165 * The unit containing the parsed information (not `null`).
152 */ 166 */
153 HtmlUnit _unit; 167 HtmlUnit _unit;
154 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU nit unit) : super(modificationTime, token, lineStarts) { 168 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU nit unit) : super(modificationTime, token, lineStarts) {
155 this._unit = unit; 169 this._unit = unit;
156 } 170 }
157 171
158 /** 172 /**
159 * Answer the unit generated by parsing the source 173 * Answer the unit generated by parsing the source
174 *
160 * @return the unit (not `null`) 175 * @return the unit (not `null`)
161 */ 176 */
162 HtmlUnit get htmlUnit => _unit; 177 HtmlUnit get htmlUnit => _unit;
163 } 178 }
164 /** 179 /**
165 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi ll recursively 180 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi ll recursively
166 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit 181 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
167 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and[X mlTagNode]s to be visited. 182 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
183 * [XmlTagNode]s to be visited.
168 * 184 *
169 * Subclasses that override a visit method must either invoke the overridden vis it method or must 185 * Subclasses that override a visit method must either invoke the overridden vis it method or must
170 * explicitly ask the visited node to visit its children. Failure to do so will cause the children 186 * explicitly ask the visited node to visit its children. Failure to do so will cause the children
171 * of the visited node to not be visited. 187 * of the visited node to not be visited.
188 *
172 * @coverage dart.engine.html 189 * @coverage dart.engine.html
173 */ 190 */
174 class RecursiveXmlVisitor<R> implements XmlVisitor<R> { 191 class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
175 R visitHtmlUnit(HtmlUnit node) { 192 R visitHtmlUnit(HtmlUnit node) {
176 node.visitChildren(this); 193 node.visitChildren(this);
177 return null; 194 return null;
178 } 195 }
179 R visitXmlAttributeNode(XmlAttributeNode node) { 196 R visitXmlAttributeNode(XmlAttributeNode node) {
180 node.visitChildren(this); 197 node.visitChildren(this);
181 return null; 198 return null;
182 } 199 }
183 R visitXmlTagNode(XmlTagNode node) { 200 R visitXmlTagNode(XmlTagNode node) {
184 node.visitChildren(this); 201 node.visitChildren(this);
185 return null; 202 return null;
186 } 203 }
187 } 204 }
188 /** 205 /**
189 * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes. 206 * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
207 *
190 * @coverage dart.engine.html 208 * @coverage dart.engine.html
191 */ 209 */
192 abstract class XmlNode { 210 abstract class XmlNode {
193 211
194 /** 212 /**
195 * The parent of the node, or `null` if the node is the root of an AST structu re. 213 * The parent of the node, or `null` if the node is the root of an AST structu re.
196 */ 214 */
197 XmlNode _parent; 215 XmlNode _parent;
198 216
199 /** 217 /**
200 * Use the given visitor to visit this node. 218 * Use the given visitor to visit this node.
219 *
201 * @param visitor the visitor that will visit this node 220 * @param visitor the visitor that will visit this node
202 * @return the value returned by the visitor as a result of visiting this node 221 * @return the value returned by the visitor as a result of visiting this node
203 */ 222 */
204 accept(XmlVisitor visitor); 223 accept(XmlVisitor visitor);
205 224
206 /** 225 /**
207 * Return the first token included in this node's source range. 226 * Return the first token included in this node's source range.
227 *
208 * @return the first token or `null` if none 228 * @return the first token or `null` if none
209 */ 229 */
210 Token get beginToken; 230 Token get beginToken;
211 231
212 /** 232 /**
213 * Return the offset of the character immediately following the last character of this node's 233 * Return the offset of the character immediately following the last character of this node's
214 * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html 234 * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
215 * unit this will be equal to the length of the unit's source. 235 * unit this will be equal to the length of the unit's source.
236 *
216 * @return the offset of the character just past the node's source range 237 * @return the offset of the character just past the node's source range
217 */ 238 */
218 int get end => offset + length; 239 int get end => offset + length;
219 240
220 /** 241 /**
221 * Return the last token included in this node's source range. 242 * Return the last token included in this node's source range.
243 *
222 * @return the last token or `null` if none 244 * @return the last token or `null` if none
223 */ 245 */
224 Token get endToken; 246 Token get endToken;
225 247
226 /** 248 /**
227 * Return the number of characters in the node's source range. 249 * Return the number of characters in the node's source range.
250 *
228 * @return the number of characters in the node's source range 251 * @return the number of characters in the node's source range
229 */ 252 */
230 int get length { 253 int get length {
231 Token beginToken = this.beginToken; 254 Token beginToken = this.beginToken;
232 Token endToken = this.endToken; 255 Token endToken = this.endToken;
233 if (beginToken == null || endToken == null) { 256 if (beginToken == null || endToken == null) {
234 return -1; 257 return -1;
235 } 258 }
236 return endToken.offset + endToken.length - beginToken.offset; 259 return endToken.offset + endToken.length - beginToken.offset;
237 } 260 }
238 261
239 /** 262 /**
240 * Return the offset from the beginning of the file to the first character in the node's source 263 * Return the offset from the beginning of the file to the first character in the node's source
241 * range. 264 * range.
265 *
242 * @return the offset from the beginning of the file to the first character in the node's source 266 * @return the offset from the beginning of the file to the first character in the node's source
243 * range 267 * range
244 */ 268 */
245 int get offset { 269 int get offset {
246 Token beginToken = this.beginToken; 270 Token beginToken = this.beginToken;
247 if (beginToken == null) { 271 if (beginToken == null) {
248 return -1; 272 return -1;
249 } 273 }
250 return beginToken.offset; 274 return beginToken.offset;
251 } 275 }
252 276
253 /** 277 /**
254 * Return this node's parent node, or `null` if this node is the root of an AS T structure. 278 * Return this node's parent node, or `null` if this node is the root of an AS T structure.
255 * 279 *
256 * Note that the relationship between an AST node and its parent node may chan ge over the lifetime 280 * Note that the relationship between an AST node and its parent node may chan ge over the lifetime
257 * of a node. 281 * of a node.
282 *
258 * @return the parent of this node, or `null` if none 283 * @return the parent of this node, or `null` if none
259 */ 284 */
260 XmlNode get parent => _parent; 285 XmlNode get parent => _parent;
261 String toString() { 286 String toString() {
262 PrintStringWriter writer = new PrintStringWriter(); 287 PrintStringWriter writer = new PrintStringWriter();
263 accept(new ToSourceVisitor(writer)); 288 accept(new ToSourceVisitor(writer));
264 return writer.toString(); 289 return writer.toString();
265 } 290 }
266 291
267 /** 292 /**
268 * Use the given visitor to visit all of the children of this node. The childr en will be visited 293 * Use the given visitor to visit all of the children of this node. The childr en will be visited
269 * in source order. 294 * in source order.
295 *
270 * @param visitor the visitor that will be used to visit the children of this node 296 * @param visitor the visitor that will be used to visit the children of this node
271 */ 297 */
272 void visitChildren(XmlVisitor<Object> visitor); 298 void visitChildren(XmlVisitor<Object> visitor);
273 299
274 /** 300 /**
275 * Make this node the parent of the given child nodes. 301 * Make this node the parent of the given child nodes.
302 *
276 * @param children the nodes that will become the children of this node 303 * @param children the nodes that will become the children of this node
277 * @return the nodes that were made children of this node 304 * @return the nodes that were made children of this node
278 */ 305 */
279 List becomeParentOf(List children) { 306 List becomeParentOf(List children) {
280 if (children != null) { 307 if (children != null) {
281 for (JavaIterator iter = new JavaIterator(children); iter.hasNext;) { 308 for (JavaIterator iter = new JavaIterator(children); iter.hasNext;) {
282 XmlNode node = iter.next(); 309 XmlNode node = iter.next();
283 node.parent = this; 310 node.parent = this;
284 } 311 }
285 return new List.from(children); 312 return new List.from(children);
286 } 313 }
287 return children; 314 return children;
288 } 315 }
289 316
290 /** 317 /**
291 * Make this node the parent of the given child node. 318 * Make this node the parent of the given child node.
319 *
292 * @param child the node that will become a child of this node 320 * @param child the node that will become a child of this node
293 * @return the node that was made a child of this node 321 * @return the node that was made a child of this node
294 */ 322 */
295 XmlNode becomeParentOf2(XmlNode child) { 323 XmlNode becomeParentOf2(XmlNode child) {
296 if (child != null) { 324 if (child != null) {
297 XmlNode node = child; 325 XmlNode node = child;
298 node.parent = this; 326 node.parent = this;
299 } 327 }
300 return child; 328 return child;
301 } 329 }
(...skipping 29 matching lines...) Expand all
331 } else { 359 } else {
332 appendIdentifier(builder, current); 360 appendIdentifier(builder, current);
333 } 361 }
334 current = current.parent; 362 current = current.parent;
335 } 363 }
336 return builder.toString(); 364 return builder.toString();
337 } 365 }
338 366
339 /** 367 /**
340 * Set the parent of this node to the given node. 368 * Set the parent of this node to the given node.
369 *
341 * @param newParent the node that is to be made the parent of this node 370 * @param newParent the node that is to be made the parent of this node
342 */ 371 */
343 void set parent(XmlNode newParent) { 372 void set parent(XmlNode newParent) {
344 XmlNode current = newParent; 373 XmlNode current = newParent;
345 while (current != null) { 374 while (current != null) {
346 if (identical(current, this)) { 375 if (identical(current, this)) {
347 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu ildRecursiveStructureMessage(newParent))); 376 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu ildRecursiveStructureMessage(newParent)));
348 return; 377 return;
349 } 378 }
350 current = current.parent; 379 current = current.parent;
351 } 380 }
352 _parent = newParent; 381 _parent = newParent;
353 } 382 }
354 } 383 }
355 /** 384 /**
356 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing 385 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
357 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor 386 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
358 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel y visit a whole 387 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel y visit a whole
359 * structure) and that only need to visit a small number of node types. 388 * structure) and that only need to visit a small number of node types.
360 */ 389 */
361 class SimpleXmlVisitor<R> implements XmlVisitor<R> { 390 class SimpleXmlVisitor<R> implements XmlVisitor<R> {
362 R visitHtmlUnit(HtmlUnit htmlUnit) => null; 391 R visitHtmlUnit(HtmlUnit htmlUnit) => null;
363 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null; 392 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
364 R visitXmlTagNode(XmlTagNode xmlTagNode) => null; 393 R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
365 } 394 }
366 /** 395 /**
367 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc lasses are 396 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc lasses are
368 * required to implement the interface used to access the characters being scann ed. 397 * required to implement the interface used to access the characters being scann ed.
398 *
369 * @coverage dart.engine.html 399 * @coverage dart.engine.html
370 */ 400 */
371 abstract class AbstractScanner { 401 abstract class AbstractScanner {
372 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; 402 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
373 403
374 /** 404 /**
375 * The source being scanned. 405 * The source being scanned.
376 */ 406 */
377 Source _source; 407 Source _source;
378 408
(...skipping 12 matching lines...) Expand all
391 */ 421 */
392 List<int> _lineStarts = new List<int>(); 422 List<int> _lineStarts = new List<int>();
393 423
394 /** 424 /**
395 * An array of element tags for which the content between tags should be consi der a single token. 425 * An array of element tags for which the content between tags should be consi der a single token.
396 */ 426 */
397 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; 427 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
398 428
399 /** 429 /**
400 * Initialize a newly created scanner. 430 * Initialize a newly created scanner.
431 *
401 * @param source the source being scanned 432 * @param source the source being scanned
402 */ 433 */
403 AbstractScanner(Source source) { 434 AbstractScanner(Source source) {
404 this._source = source; 435 this._source = source;
405 _tokens = new Token.con1(TokenType.EOF, -1); 436 _tokens = new Token.con1(TokenType.EOF, -1);
406 _tokens.setNext(_tokens); 437 _tokens.setNext(_tokens);
407 _tail = _tokens; 438 _tail = _tokens;
408 recordStartOfLine(); 439 recordStartOfLine();
409 } 440 }
410 441
411 /** 442 /**
412 * Return an array containing the offsets of the first character of each line in the source code. 443 * Return an array containing the offsets of the first character of each line in the source code.
444 *
413 * @return an array containing the offsets of the first character of each line in the source code 445 * @return an array containing the offsets of the first character of each line in the source code
414 */ 446 */
415 List<int> get lineStarts => _lineStarts; 447 List<int> get lineStarts => _lineStarts;
416 448
417 /** 449 /**
418 * Return the current offset relative to the beginning of the file. Return the initial offset if 450 * Return the current offset relative to the beginning of the file. Return the initial offset if
419 * the scanner has not yet scanned the source code, and one (1) past the end o f the source code if 451 * the scanner has not yet scanned the source code, and one (1) past the end o f the source code if
420 * the source code has been scanned. 452 * the source code has been scanned.
453 *
421 * @return the current offset of the scanner in the source 454 * @return the current offset of the scanner in the source
422 */ 455 */
423 int get offset; 456 int get offset;
424 457
425 /** 458 /**
426 * Answer the source being scanned. 459 * Answer the source being scanned.
460 *
427 * @return the source or `null` if undefined 461 * @return the source or `null` if undefined
428 */ 462 */
429 Source get source => _source; 463 Source get source => _source;
430 464
431 /** 465 /**
432 * Set array of element tags for which the content between tags should be cons ider a single token. 466 * Set array of element tags for which the content between tags should be cons ider a single token.
433 */ 467 */
434 void set passThroughElements(List<String> passThroughElements2) { 468 void set passThroughElements(List<String> passThroughElements2) {
435 this._passThroughElements = passThroughElements2 != null ? passThroughElemen ts2 : _NO_PASS_THROUGH_ELEMENTS; 469 this._passThroughElements = passThroughElements2 != null ? passThroughElemen ts2 : _NO_PASS_THROUGH_ELEMENTS;
436 } 470 }
437 471
438 /** 472 /**
439 * Scan the source code to produce a list of tokens representing the source. 473 * Scan the source code to produce a list of tokens representing the source.
474 *
440 * @return the first token in the list of tokens that were produced 475 * @return the first token in the list of tokens that were produced
441 */ 476 */
442 Token tokenize() { 477 Token tokenize() {
443 scan(); 478 scan();
444 appendEofToken(); 479 appendEofToken();
445 return firstToken(); 480 return firstToken();
446 } 481 }
447 482
448 /** 483 /**
449 * Advance the current position and return the character at the new current po sition. 484 * Advance the current position and return the character at the new current po sition.
485 *
450 * @return the character at the new current position 486 * @return the character at the new current position
451 */ 487 */
452 int advance(); 488 int advance();
453 489
454 /** 490 /**
455 * Return the substring of the source code between the start offset and the mo dified current 491 * Return the substring of the source code between the start offset and the mo dified current
456 * position. The current position is modified by adding the end delta. 492 * position. The current position is modified by adding the end delta.
493 *
457 * @param start the offset to the beginning of the string, relative to the sta rt of the file 494 * @param start the offset to the beginning of the string, relative to the sta rt of the file
458 * @param endDelta the number of character after the current location to be in cluded in the 495 * @param endDelta the number of character after the current location to be in cluded in the
459 * string, or the number of characters before the current location to be exclu ded if the 496 * string, or the number of characters before the current location to be excluded if the
460 * offset is negative 497 * offset is negative
461 * @return the specified substring of the source code 498 * @return the specified substring of the source code
462 */ 499 */
463 String getString(int start, int endDelta); 500 String getString(int start, int endDelta);
464 501
465 /** 502 /**
466 * Return the character at the current position without changing the current p osition. 503 * Return the character at the current position without changing the current p osition.
504 *
467 * @return the character at the current position 505 * @return the character at the current position
468 */ 506 */
469 int peek(); 507 int peek();
470 508
471 /** 509 /**
472 * Record the fact that we are at the beginning of a new line in the source. 510 * Record the fact that we are at the beginning of a new line in the source.
473 */ 511 */
474 void recordStartOfLine() { 512 void recordStartOfLine() {
475 _lineStarts.add(offset); 513 _lineStarts.add(offset);
476 } 514 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 emit3(TokenType.TAG, start, -1); 670 emit3(TokenType.TAG, start, -1);
633 } else { 671 } else {
634 emit3(TokenType.TEXT, start, 0); 672 emit3(TokenType.TEXT, start, 0);
635 c = advance(); 673 c = advance();
636 } 674 }
637 } 675 }
638 } 676 }
639 } 677 }
640 /** 678 /**
641 * Instances of `HtmlScanResult` hold the result of scanning an HTML file. 679 * Instances of `HtmlScanResult` hold the result of scanning an HTML file.
680 *
642 * @coverage dart.engine.html 681 * @coverage dart.engine.html
643 */ 682 */
644 class HtmlScanResult { 683 class HtmlScanResult {
645 684
646 /** 685 /**
647 * The time at which the contents of the source were last set. 686 * The time at which the contents of the source were last set.
648 */ 687 */
649 int _modificationTime = 0; 688 int _modificationTime = 0;
650 689
651 /** 690 /**
652 * The first token in the token stream (not `null`). 691 * The first token in the token stream (not `null`).
653 */ 692 */
654 Token _token; 693 Token _token;
655 694
656 /** 695 /**
657 * The line start information that was produced. 696 * The line start information that was produced.
658 */ 697 */
659 List<int> _lineStarts; 698 List<int> _lineStarts;
660 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { 699 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) {
661 this._modificationTime = modificationTime; 700 this._modificationTime = modificationTime;
662 this._token = token; 701 this._token = token;
663 this._lineStarts = lineStarts; 702 this._lineStarts = lineStarts;
664 } 703 }
665 704
666 /** 705 /**
667 * Answer the line start information that was produced. 706 * Answer the line start information that was produced.
707 *
668 * @return an array of line starts (not `null`) 708 * @return an array of line starts (not `null`)
669 */ 709 */
670 List<int> get lineStarts => _lineStarts; 710 List<int> get lineStarts => _lineStarts;
671 711
672 /** 712 /**
673 * Return the time at which the contents of the source were last set. 713 * Return the time at which the contents of the source were last set.
714 *
674 * @return the time at which the contents of the source were last set 715 * @return the time at which the contents of the source were last set
675 */ 716 */
676 int get modificationTime => _modificationTime; 717 int get modificationTime => _modificationTime;
677 718
678 /** 719 /**
679 * Answer the first token in the token stream. 720 * Answer the first token in the token stream.
721 *
680 * @return the token (not `null`) 722 * @return the token (not `null`)
681 */ 723 */
682 Token get token => _token; 724 Token get token => _token;
683 } 725 }
684 /** 726 /**
685 * Instances of the class `StringScanner` implement a scanner that reads from a string. The 727 * Instances of the class `StringScanner` implement a scanner that reads from a string. The
686 * scanning logic is in the superclass. 728 * scanning logic is in the superclass.
729 *
687 * @coverage dart.engine.html 730 * @coverage dart.engine.html
688 */ 731 */
689 class StringScanner extends AbstractScanner { 732 class StringScanner extends AbstractScanner {
690 733
691 /** 734 /**
692 * The string from which characters will be read. 735 * The string from which characters will be read.
693 */ 736 */
694 String _string; 737 String _string;
695 738
696 /** 739 /**
697 * The number of characters in the string. 740 * The number of characters in the string.
698 */ 741 */
699 int _stringLength = 0; 742 int _stringLength = 0;
700 743
701 /** 744 /**
702 * The index, relative to the string, of the last character that was read. 745 * The index, relative to the string, of the last character that was read.
703 */ 746 */
704 int _charOffset = 0; 747 int _charOffset = 0;
705 748
706 /** 749 /**
707 * Initialize a newly created scanner to scan the characters in the given stri ng. 750 * Initialize a newly created scanner to scan the characters in the given stri ng.
751 *
708 * @param source the source being scanned 752 * @param source the source being scanned
709 * @param string the string from which characters will be read 753 * @param string the string from which characters will be read
710 */ 754 */
711 StringScanner(Source source, String string) : super(source) { 755 StringScanner(Source source, String string) : super(source) {
712 this._string = string; 756 this._string = string;
713 this._stringLength = string.length; 757 this._stringLength = string.length;
714 this._charOffset = -1; 758 this._charOffset = -1;
715 } 759 }
716 int get offset => _charOffset; 760 int get offset => _charOffset;
717 void set offset(int offset2) { 761 void set offset(int offset2) {
(...skipping 10 matching lines...) Expand all
728 int peek() { 772 int peek() {
729 if (_charOffset + 1 < _stringLength) { 773 if (_charOffset + 1 < _stringLength) {
730 return _string.codeUnitAt(_charOffset + 1); 774 return _string.codeUnitAt(_charOffset + 1);
731 } 775 }
732 return -1; 776 return -1;
733 } 777 }
734 } 778 }
735 /** 779 /**
736 * Instances of the class `CharBufferScanner` implement a scanner that reads fro m a character 780 * Instances of the class `CharBufferScanner` implement a scanner that reads fro m a character
737 * buffer. The scanning logic is in the superclass. 781 * buffer. The scanning logic is in the superclass.
782 *
738 * @coverage dart.engine.html 783 * @coverage dart.engine.html
739 */ 784 */
740 class CharBufferScanner extends AbstractScanner { 785 class CharBufferScanner extends AbstractScanner {
741 786
742 /** 787 /**
743 * The buffer from which characters will be read. 788 * The buffer from which characters will be read.
744 */ 789 */
745 CharSequence _buffer; 790 CharSequence _buffer;
746 791
747 /** 792 /**
748 * The number of characters in the buffer. 793 * The number of characters in the buffer.
749 */ 794 */
750 int _bufferLength = 0; 795 int _bufferLength = 0;
751 796
752 /** 797 /**
753 * The index of the last character that was read. 798 * The index of the last character that was read.
754 */ 799 */
755 int _charOffset = 0; 800 int _charOffset = 0;
756 801
757 /** 802 /**
758 * Initialize a newly created scanner to scan the characters in the given char acter buffer. 803 * Initialize a newly created scanner to scan the characters in the given char acter buffer.
804 *
759 * @param source the source being scanned 805 * @param source the source being scanned
760 * @param buffer the buffer from which characters will be read 806 * @param buffer the buffer from which characters will be read
761 */ 807 */
762 CharBufferScanner(Source source, CharSequence buffer) : super(source) { 808 CharBufferScanner(Source source, CharSequence buffer) : super(source) {
763 this._buffer = buffer; 809 this._buffer = buffer;
764 this._bufferLength = buffer.length(); 810 this._bufferLength = buffer.length();
765 this._charOffset = -1; 811 this._charOffset = -1;
766 } 812 }
767 int get offset => _charOffset; 813 int get offset => _charOffset;
768 int advance() { 814 int advance() {
769 if (++_charOffset < _bufferLength) { 815 if (++_charOffset < _bufferLength) {
770 return _buffer.charAt(_charOffset); 816 return _buffer.charAt(_charOffset);
771 } 817 }
772 _charOffset = _bufferLength; 818 _charOffset = _bufferLength;
773 return -1; 819 return -1;
774 } 820 }
775 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString(); 821 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString();
776 int peek() { 822 int peek() {
777 if (_charOffset + 1 < _bufferLength) { 823 if (_charOffset + 1 < _bufferLength) {
778 return _buffer.charAt(_charOffset + 1); 824 return _buffer.charAt(_charOffset + 1);
779 } 825 }
780 return -1; 826 return -1;
781 } 827 }
782 } 828 }
783 /** 829 /**
784 * Instances of the class `ToSourceVisitor` write a source representation of a v isited XML 830 * Instances of the class `ToSourceVisitor` write a source representation of a v isited XML
785 * node (and all of it's children) to a writer. 831 * node (and all of it's children) to a writer.
832 *
786 * @coverage dart.engine.html 833 * @coverage dart.engine.html
787 */ 834 */
788 class ToSourceVisitor implements XmlVisitor<Object> { 835 class ToSourceVisitor implements XmlVisitor<Object> {
789 836
790 /** 837 /**
791 * The writer to which the source is to be written. 838 * The writer to which the source is to be written.
792 */ 839 */
793 PrintWriter _writer; 840 PrintWriter _writer;
794 841
795 /** 842 /**
796 * Initialize a newly created visitor to write source code representing the vi sited nodes to the 843 * Initialize a newly created visitor to write source code representing the vi sited nodes to the
797 * given writer. 844 * given writer.
845 *
798 * @param writer the writer to which the source is to be written 846 * @param writer the writer to which the source is to be written
799 */ 847 */
800 ToSourceVisitor(PrintWriter writer) { 848 ToSourceVisitor(PrintWriter writer) {
801 this._writer = writer; 849 this._writer = writer;
802 } 850 }
803 Object visitHtmlUnit(HtmlUnit node) { 851 Object visitHtmlUnit(HtmlUnit node) {
804 for (XmlTagNode child in node.tagNodes) { 852 for (XmlTagNode child in node.tagNodes) {
805 visit(child); 853 visit(child);
806 } 854 }
807 return null; 855 return null;
(...skipping 29 matching lines...) Expand all
837 } 885 }
838 _writer.print("</"); 886 _writer.print("</");
839 _writer.print(tagName); 887 _writer.print(tagName);
840 _writer.print(">"); 888 _writer.print(">");
841 } 889 }
842 return null; 890 return null;
843 } 891 }
844 892
845 /** 893 /**
846 * Safely visit the given node. 894 * Safely visit the given node.
895 *
847 * @param node the node to be visited 896 * @param node the node to be visited
848 */ 897 */
849 void visit(XmlNode node) { 898 void visit(XmlNode node) {
850 if (node != null) { 899 if (node != null) {
851 node.accept(this); 900 node.accept(this);
852 } 901 }
853 } 902 }
854 } 903 }
855 /** 904 /**
856 * The enumeration `TokenType` defines the types of tokens that can be returned by the 905 * The enumeration `TokenType` defines the types of tokens that can be returned by the
857 * scanner. 906 * scanner.
907 *
858 * @coverage dart.engine.html 908 * @coverage dart.engine.html
859 */ 909 */
860 class TokenType implements Comparable<TokenType> { 910 class TokenType implements Comparable<TokenType> {
861 911
862 /** 912 /**
863 * The type of the token that marks the end of the input. 913 * The type of the token that marks the end of the input.
864 */ 914 */
865 static final TokenType EOF = new TokenType_EOF('EOF', 0, ""); 915 static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
866 static final TokenType EQ = new TokenType('EQ', 1, "="); 916 static final TokenType EQ = new TokenType('EQ', 1, "=");
867 static final TokenType GT = new TokenType('GT', 2, ">"); 917 static final TokenType GT = new TokenType('GT', 2, ">");
(...skipping 19 matching lines...) Expand all
887 * lexeme for this type of token. 937 * lexeme for this type of token.
888 */ 938 */
889 String _lexeme; 939 String _lexeme;
890 TokenType(this.name, this.ordinal, String lexeme) { 940 TokenType(this.name, this.ordinal, String lexeme) {
891 this._lexeme = lexeme; 941 this._lexeme = lexeme;
892 } 942 }
893 943
894 /** 944 /**
895 * Return the lexeme that defines this type of token, or `null` if there is mo re than one 945 * Return the lexeme that defines this type of token, or `null` if there is mo re than one
896 * possible lexeme for this type of token. 946 * possible lexeme for this type of token.
947 *
897 * @return the lexeme that defines this type of token 948 * @return the lexeme that defines this type of token
898 */ 949 */
899 String get lexeme => _lexeme; 950 String get lexeme => _lexeme;
900 int compareTo(TokenType other) => ordinal - other.ordinal; 951 int compareTo(TokenType other) => ordinal - other.ordinal;
901 int get hashCode => ordinal; 952 int get hashCode => ordinal;
902 String toString() => name; 953 String toString() => name;
903 } 954 }
904 class TokenType_EOF extends TokenType { 955 class TokenType_EOF extends TokenType {
905 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar g0); 956 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar g0);
906 String toString() => "-eof-"; 957 String toString() => "-eof-";
907 } 958 }
908 /** 959 /**
909 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa gNode]. 960 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa gNode].
961 *
910 * @coverage dart.engine.html 962 * @coverage dart.engine.html
911 */ 963 */
912 class XmlAttributeNode extends XmlNode { 964 class XmlAttributeNode extends XmlNode {
913 Token _name; 965 Token _name;
914 Token _equals; 966 Token _equals;
915 Token _value; 967 Token _value;
916 968
917 /** 969 /**
918 * Construct a new instance representing an XML attribute. 970 * Construct a new instance representing an XML attribute.
971 *
919 * @param name the name token (not `null`). This may be a zero length token if the attribute 972 * @param name the name token (not `null`). This may be a zero length token if the attribute
920 * is badly formed. 973 * is badly formed.
921 * @param equals the equals sign or `null` if none 974 * @param equals the equals sign or `null` if none
922 * @param value the value token (not `null`) 975 * @param value the value token (not `null`)
923 */ 976 */
924 XmlAttributeNode(Token name, Token equals, Token value) { 977 XmlAttributeNode(Token name, Token equals, Token value) {
925 this._name = name; 978 this._name = name;
926 this._equals = equals; 979 this._equals = equals;
927 this._value = value; 980 this._value = value;
928 } 981 }
929 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); 982 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
930 Token get beginToken => _name; 983 Token get beginToken => _name;
931 Token get endToken => _value; 984 Token get endToken => _value;
932 985
933 /** 986 /**
934 * Answer the equals sign token that appears between the name and value tokens . This may be`null` if the attribute is badly formed. 987 * Answer the equals sign token that appears between the name and value tokens . This may be
988 * `null` if the attribute is badly formed.
989 *
935 * @return the token or `null` if there is no equals sign between the name and value 990 * @return the token or `null` if there is no equals sign between the name and value
936 */ 991 */
937 Token get equals => _equals; 992 Token get equals => _equals;
938 993
939 /** 994 /**
940 * Answer the attribute name. This may be a zero length token if the attribute is badly formed. 995 * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
996 *
941 * @return the name (not `null`) 997 * @return the name (not `null`)
942 */ 998 */
943 Token get name => _name; 999 Token get name => _name;
944 1000
945 /** 1001 /**
946 * Answer the lexeme for the value token without the leading and trailing quot es. 1002 * Answer the lexeme for the value token without the leading and trailing quot es.
1003 *
947 * @return the text or `null` if the value is not specified 1004 * @return the text or `null` if the value is not specified
948 */ 1005 */
949 String get text { 1006 String get text {
950 if (_value == null) { 1007 if (_value == null) {
951 return null; 1008 return null;
952 } 1009 }
953 String text = _value.lexeme; 1010 String text = _value.lexeme;
954 int len = text.length; 1011 int len = text.length;
955 if (len > 0) { 1012 if (len > 0) {
956 if (text.codeUnitAt(0) == 0x22) { 1013 if (text.codeUnitAt(0) == 0x22) {
957 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) { 1014 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
958 return text.substring(1, len - 1); 1015 return text.substring(1, len - 1);
959 } else { 1016 } else {
960 return text.substring(1); 1017 return text.substring(1);
961 } 1018 }
962 } else if (text.codeUnitAt(0) == 0x27) { 1019 } else if (text.codeUnitAt(0) == 0x27) {
963 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { 1020 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
964 return text.substring(1, len - 1); 1021 return text.substring(1, len - 1);
965 } else { 1022 } else {
966 return text.substring(1); 1023 return text.substring(1);
967 } 1024 }
968 } 1025 }
969 } 1026 }
970 return text; 1027 return text;
971 } 1028 }
972 1029
973 /** 1030 /**
974 * Answer the attribute value. A properly formed value will start and end with matching quote 1031 * Answer the attribute value. A properly formed value will start and end with matching quote
975 * characters, but the value returned may not be properly formed. 1032 * characters, but the value returned may not be properly formed.
1033 *
976 * @return the value or `null` if this represents a badly formed attribute 1034 * @return the value or `null` if this represents a badly formed attribute
977 */ 1035 */
978 Token get value => _value; 1036 Token get value => _value;
979 void visitChildren(XmlVisitor<Object> visitor) { 1037 void visitChildren(XmlVisitor<Object> visitor) {
980 } 1038 }
981 } 1039 }
982 /** 1040 /**
983 * The interface `XmlVisitor` defines the behavior of objects that can be used t o visit an[XmlNode] structure. 1041 * The interface `XmlVisitor` defines the behavior of objects that can be used t o visit an
1042 * [XmlNode] structure.
1043 *
984 * @coverage dart.engine.html 1044 * @coverage dart.engine.html
985 */ 1045 */
986 abstract class XmlVisitor<R> { 1046 abstract class XmlVisitor<R> {
987 R visitHtmlUnit(HtmlUnit htmlUnit); 1047 R visitHtmlUnit(HtmlUnit htmlUnit);
988 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode); 1048 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
989 R visitXmlTagNode(XmlTagNode xmlTagNode); 1049 R visitXmlTagNode(XmlTagNode xmlTagNode);
990 } 1050 }
991 /** 1051 /**
992 * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/ > 1052 * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/ >
993 * For example, the following code scans HTML source and returns the result: 1053 * For example, the following code scans HTML source and returns the result:
1054 *
994 * <pre> 1055 * <pre>
995 * HtmlScanner scanner = new HtmlScanner(source); 1056 * HtmlScanner scanner = new HtmlScanner(source);
996 * source.getContents(scanner); 1057 * source.getContents(scanner);
997 * return scanner.getResult(); 1058 * return scanner.getResult();
998 * </pre> 1059 * </pre>
1060 *
999 * @coverage dart.engine.html 1061 * @coverage dart.engine.html
1000 */ 1062 */
1001 class HtmlScanner implements Source_ContentReceiver { 1063 class HtmlScanner implements Source_ContentReceiver {
1002 List<String> _SCRIPT_TAG = <String> ["script"]; 1064 List<String> _SCRIPT_TAG = <String> ["script"];
1003 1065
1004 /** 1066 /**
1005 * The source being scanned (not `null`) 1067 * The source being scanned (not `null`)
1006 */ 1068 */
1007 Source _source; 1069 Source _source;
1008 1070
1009 /** 1071 /**
1010 * The time at which the contents of the source were last set. 1072 * The time at which the contents of the source were last set.
1011 */ 1073 */
1012 int _modificationTime = 0; 1074 int _modificationTime = 0;
1013 1075
1014 /** 1076 /**
1015 * The scanner used to scan the source 1077 * The scanner used to scan the source
1016 */ 1078 */
1017 AbstractScanner _scanner; 1079 AbstractScanner _scanner;
1018 1080
1019 /** 1081 /**
1020 * The first token in the token stream. 1082 * The first token in the token stream.
1021 */ 1083 */
1022 Token _token; 1084 Token _token;
1023 1085
1024 /** 1086 /**
1025 * Construct a new instance to scan the specified source. 1087 * Construct a new instance to scan the specified source.
1088 *
1026 * @param source the source to be scanned (not `null`) 1089 * @param source the source to be scanned (not `null`)
1027 */ 1090 */
1028 HtmlScanner(Source source) { 1091 HtmlScanner(Source source) {
1029 this._source = source; 1092 this._source = source;
1030 } 1093 }
1031 void accept(CharBuffer contents, int modificationTime2) { 1094 void accept(CharBuffer contents, int modificationTime2) {
1032 this._modificationTime = modificationTime2; 1095 this._modificationTime = modificationTime2;
1033 _scanner = new CharBufferScanner(_source, contents); 1096 _scanner = new CharBufferScanner(_source, contents);
1034 _scanner.passThroughElements = _SCRIPT_TAG; 1097 _scanner.passThroughElements = _SCRIPT_TAG;
1035 _token = _scanner.tokenize(); 1098 _token = _scanner.tokenize();
1036 } 1099 }
1037 void accept2(String contents, int modificationTime2) { 1100 void accept2(String contents, int modificationTime2) {
1038 this._modificationTime = modificationTime2; 1101 this._modificationTime = modificationTime2;
1039 _scanner = new StringScanner(_source, contents); 1102 _scanner = new StringScanner(_source, contents);
1040 _scanner.passThroughElements = _SCRIPT_TAG; 1103 _scanner.passThroughElements = _SCRIPT_TAG;
1041 _token = _scanner.tokenize(); 1104 _token = _scanner.tokenize();
1042 } 1105 }
1043 1106
1044 /** 1107 /**
1045 * Answer the result of scanning the source 1108 * Answer the result of scanning the source
1109 *
1046 * @return the result (not `null`) 1110 * @return the result (not `null`)
1047 */ 1111 */
1048 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc anner.lineStarts); 1112 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc anner.lineStarts);
1049 } 1113 }
1050 /** 1114 /**
1051 * Instances of the class `XmlParser` are used to parse tokens into a AST struct ure comprised 1115 * Instances of the class `XmlParser` are used to parse tokens into a AST struct ure comprised
1052 * of [XmlNode]s. 1116 * of [XmlNode]s.
1117 *
1053 * @coverage dart.engine.html 1118 * @coverage dart.engine.html
1054 */ 1119 */
1055 class XmlParser { 1120 class XmlParser {
1056 1121
1057 /** 1122 /**
1058 * The source being parsed. 1123 * The source being parsed.
1059 */ 1124 */
1060 Source _source; 1125 Source _source;
1061 1126
1062 /** 1127 /**
1063 * The next token to be parsed. 1128 * The next token to be parsed.
1064 */ 1129 */
1065 Token _currentToken; 1130 Token _currentToken;
1066 1131
1067 /** 1132 /**
1068 * Construct a parser for the specified source. 1133 * Construct a parser for the specified source.
1134 *
1069 * @param source the source being parsed 1135 * @param source the source being parsed
1070 */ 1136 */
1071 XmlParser(Source source) { 1137 XmlParser(Source source) {
1072 this._source = source; 1138 this._source = source;
1073 } 1139 }
1074 1140
1075 /** 1141 /**
1076 * Answer the source being parsed. 1142 * Answer the source being parsed.
1143 *
1077 * @return the source 1144 * @return the source
1078 */ 1145 */
1079 Source get source => _source; 1146 Source get source => _source;
1080 1147
1081 /** 1148 /**
1082 * Answer `true` if the specified tag is self closing and thus should never ha ve content or 1149 * Answer `true` if the specified tag is self closing and thus should never ha ve content or
1083 * child tag nodes. 1150 * child tag nodes.
1151 *
1084 * @param tag the tag (not `null`) 1152 * @param tag the tag (not `null`)
1085 * @return `true` if self closing 1153 * @return `true` if self closing
1086 */ 1154 */
1087 bool isSelfClosing(Token tag) => false; 1155 bool isSelfClosing(Token tag) => false;
1088 1156
1089 /** 1157 /**
1090 * Parse the entire token stream and in the process, advance the current token to the end of the 1158 * Parse the entire token stream and in the process, advance the current token to the end of the
1091 * token stream. 1159 * token stream.
1160 *
1092 * @return the list of tag nodes found (not `null`, contains no `null`) 1161 * @return the list of tag nodes found (not `null`, contains no `null`)
1093 */ 1162 */
1094 List<XmlTagNode> parseTopTagNodes(Token firstToken) { 1163 List<XmlTagNode> parseTopTagNodes(Token firstToken) {
1095 _currentToken = firstToken; 1164 _currentToken = firstToken;
1096 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); 1165 List<XmlTagNode> tagNodes = new List<XmlTagNode>();
1097 while (true) { 1166 while (true) {
1098 while (true) { 1167 while (true) {
1099 if (_currentToken.type == TokenType.LT) { 1168 if (_currentToken.type == TokenType.LT) {
1100 tagNodes.add(parseTagNode()); 1169 tagNodes.add(parseTagNode());
1101 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken. type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) { 1170 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken. type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
1102 _currentToken = _currentToken.next; 1171 _currentToken = _currentToken.next;
1103 } else if (_currentToken.type == TokenType.EOF) { 1172 } else if (_currentToken.type == TokenType.EOF) {
1104 return tagNodes; 1173 return tagNodes;
1105 } else { 1174 } else {
1106 reportUnexpectedToken(); 1175 reportUnexpectedToken();
1107 _currentToken = _currentToken.next; 1176 _currentToken = _currentToken.next;
1108 } 1177 }
1109 break; 1178 break;
1110 } 1179 }
1111 } 1180 }
1112 } 1181 }
1113 1182
1114 /** 1183 /**
1115 * Answer the current token. 1184 * Answer the current token.
1185 *
1116 * @return the current token 1186 * @return the current token
1117 */ 1187 */
1118 Token get currentToken => _currentToken; 1188 Token get currentToken => _currentToken;
1119 1189
1120 /** 1190 /**
1121 * Insert a synthetic token of the specified type before the current token 1191 * Insert a synthetic token of the specified type before the current token
1192 *
1122 * @param type the type of token to be inserted (not `null`) 1193 * @param type the type of token to be inserted (not `null`)
1123 * @return the synthetic token that was inserted (not `null`) 1194 * @return the synthetic token that was inserted (not `null`)
1124 */ 1195 */
1125 Token insertSyntheticToken(TokenType type) { 1196 Token insertSyntheticToken(TokenType type) {
1126 Token token = new Token.con2(type, _currentToken.offset, ""); 1197 Token token = new Token.con2(type, _currentToken.offset, "");
1127 _currentToken.previous.setNext(token); 1198 _currentToken.previous.setNext(token);
1128 token.setNext(_currentToken); 1199 token.setNext(_currentToken);
1129 return token; 1200 return token;
1130 } 1201 }
1131 1202
1132 /** 1203 /**
1133 * Parse the token stream for an attribute. This method advances the current t oken over the 1204 * Parse the token stream for an attribute. This method advances the current t oken over the
1134 * attribute, but should not be called if the [currentToken] is not [TokenType #TAG]. 1205 * attribute, but should not be called if the [currentToken] is not [TokenType #TAG].
1206 *
1135 * @return the attribute (not `null`) 1207 * @return the attribute (not `null`)
1136 */ 1208 */
1137 XmlAttributeNode parseAttribute() { 1209 XmlAttributeNode parseAttribute() {
1138 Token name = _currentToken; 1210 Token name = _currentToken;
1139 _currentToken = _currentToken.next; 1211 _currentToken = _currentToken.next;
1140 Token equals; 1212 Token equals;
1141 if (identical(_currentToken.type, TokenType.EQ)) { 1213 if (identical(_currentToken.type, TokenType.EQ)) {
1142 equals = _currentToken; 1214 equals = _currentToken;
1143 _currentToken = _currentToken.next; 1215 _currentToken = _currentToken.next;
1144 } else { 1216 } else {
1145 reportUnexpectedToken(); 1217 reportUnexpectedToken();
1146 equals = insertSyntheticToken(TokenType.EQ); 1218 equals = insertSyntheticToken(TokenType.EQ);
1147 } 1219 }
1148 Token value; 1220 Token value;
1149 if (identical(_currentToken.type, TokenType.STRING)) { 1221 if (identical(_currentToken.type, TokenType.STRING)) {
1150 value = _currentToken; 1222 value = _currentToken;
1151 _currentToken = _currentToken.next; 1223 _currentToken = _currentToken.next;
1152 } else { 1224 } else {
1153 reportUnexpectedToken(); 1225 reportUnexpectedToken();
1154 value = insertSyntheticToken(TokenType.STRING); 1226 value = insertSyntheticToken(TokenType.STRING);
1155 } 1227 }
1156 return new XmlAttributeNode(name, equals, value); 1228 return new XmlAttributeNode(name, equals, value);
1157 } 1229 }
1158 1230
1159 /** 1231 /**
1160 * Parse the stream for a sequence of attributes. This method advances the cur rent token to the 1232 * Parse the stream for a sequence of attributes. This method advances the cur rent token to the
1161 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF]. 1233 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF].
1234 *
1162 * @return a collection of zero or more attributes (not `null`, contains no `n ull`s) 1235 * @return a collection of zero or more attributes (not `null`, contains no `n ull`s)
1163 */ 1236 */
1164 List<XmlAttributeNode> parseAttributes() { 1237 List<XmlAttributeNode> parseAttributes() {
1165 TokenType type = _currentToken.type; 1238 TokenType type = _currentToken.type;
1166 if (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) || identical(type, TokenType.EOF)) { 1239 if (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) || identical(type, TokenType.EOF)) {
1167 return XmlTagNode.NO_ATTRIBUTES; 1240 return XmlTagNode.NO_ATTRIBUTES;
1168 } 1241 }
1169 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); 1242 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
1170 while (true) { 1243 while (true) {
1171 while (true) { 1244 while (true) {
1172 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp e.SLASH_GT || _currentToken.type == TokenType.EOF) { 1245 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp e.SLASH_GT || _currentToken.type == TokenType.EOF) {
1173 return attributes; 1246 return attributes;
1174 } else if (_currentToken.type == TokenType.TAG) { 1247 } else if (_currentToken.type == TokenType.TAG) {
1175 attributes.add(parseAttribute()); 1248 attributes.add(parseAttribute());
1176 } else { 1249 } else {
1177 reportUnexpectedToken(); 1250 reportUnexpectedToken();
1178 _currentToken = _currentToken.next; 1251 _currentToken = _currentToken.next;
1179 } 1252 }
1180 break; 1253 break;
1181 } 1254 }
1182 } 1255 }
1183 } 1256 }
1184 1257
1185 /** 1258 /**
1186 * Parse the stream for a sequence of tag nodes existing within a parent tag n ode. This method 1259 * Parse the stream for a sequence of tag nodes existing within a parent tag n ode. This method
1187 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E OF]. 1260 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E OF].
1261 *
1188 * @return a list of nodes (not `null`, contains no `null`s) 1262 * @return a list of nodes (not `null`, contains no `null`s)
1189 */ 1263 */
1190 List<XmlTagNode> parseChildTagNodes() { 1264 List<XmlTagNode> parseChildTagNodes() {
1191 TokenType type = _currentToken.type; 1265 TokenType type = _currentToken.type;
1192 if (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) { 1266 if (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) {
1193 return XmlTagNode.NO_TAG_NODES; 1267 return XmlTagNode.NO_TAG_NODES;
1194 } 1268 }
1195 List<XmlTagNode> nodes = new List<XmlTagNode>(); 1269 List<XmlTagNode> nodes = new List<XmlTagNode>();
1196 while (true) { 1270 while (true) {
1197 while (true) { 1271 while (true) {
1198 if (_currentToken.type == TokenType.LT) { 1272 if (_currentToken.type == TokenType.LT) {
1199 nodes.add(parseTagNode()); 1273 nodes.add(parseTagNode());
1200 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ e == TokenType.EOF) { 1274 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ e == TokenType.EOF) {
1201 return nodes; 1275 return nodes;
1202 } else if (_currentToken.type == TokenType.COMMENT) { 1276 } else if (_currentToken.type == TokenType.COMMENT) {
1203 _currentToken = _currentToken.next; 1277 _currentToken = _currentToken.next;
1204 } else { 1278 } else {
1205 reportUnexpectedToken(); 1279 reportUnexpectedToken();
1206 _currentToken = _currentToken.next; 1280 _currentToken = _currentToken.next;
1207 } 1281 }
1208 break; 1282 break;
1209 } 1283 }
1210 } 1284 }
1211 } 1285 }
1212 1286
1213 /** 1287 /**
1214 * Parse the token stream for the next tag node. This method advances current token over the 1288 * Parse the token stream for the next tag node. This method advances current token over the
1215 * parsed tag node, but should only be called if the current token is [TokenTy pe#LT] 1289 * parsed tag node, but should only be called if the current token is [TokenTy pe#LT]
1290 *
1216 * @return the tag node or `null` if none found 1291 * @return the tag node or `null` if none found
1217 */ 1292 */
1218 XmlTagNode parseTagNode() { 1293 XmlTagNode parseTagNode() {
1219 Token nodeStart = _currentToken; 1294 Token nodeStart = _currentToken;
1220 _currentToken = _currentToken.next; 1295 _currentToken = _currentToken.next;
1221 Token tag; 1296 Token tag;
1222 if (identical(_currentToken.type, TokenType.TAG)) { 1297 if (identical(_currentToken.type, TokenType.TAG)) {
1223 tag = _currentToken; 1298 tag = _currentToken;
1224 _currentToken = _currentToken.next; 1299 _currentToken = _currentToken.next;
1225 } else { 1300 } else {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co ntentEnd, closingTag, nodeEnd); 1341 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co ntentEnd, closingTag, nodeEnd);
1267 } 1342 }
1268 1343
1269 /** 1344 /**
1270 * Report the current token as unexpected 1345 * Report the current token as unexpected
1271 */ 1346 */
1272 void reportUnexpectedToken() { 1347 void reportUnexpectedToken() {
1273 } 1348 }
1274 } 1349 }
1275 /** 1350 /**
1276 * Instances of `XmlTagNode` represent XML or HTML elements such as `` and`<body foo="bar"> ... </body>`. 1351 * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
1352 * `<body foo="bar"> ... </body>`.
1353 *
1277 * @coverage dart.engine.html 1354 * @coverage dart.engine.html
1278 */ 1355 */
1279 class XmlTagNode extends XmlNode { 1356 class XmlTagNode extends XmlNode {
1280 1357
1281 /** 1358 /**
1282 * Constant representing empty list of attributes. 1359 * Constant representing empty list of attributes.
1283 */ 1360 */
1284 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis t<XmlAttributeNode>()); 1361 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis t<XmlAttributeNode>());
1285 1362
1286 /** 1363 /**
(...skipping 10 matching lines...) Expand all
1297 * The [TokenType#TAG] token after the starting '&lt;' (not `null`). 1374 * The [TokenType#TAG] token after the starting '&lt;' (not `null`).
1298 */ 1375 */
1299 Token _tag; 1376 Token _tag;
1300 1377
1301 /** 1378 /**
1302 * The attributes contained by the receiver (not `null`, contains no `null`s). 1379 * The attributes contained by the receiver (not `null`, contains no `null`s).
1303 */ 1380 */
1304 List<XmlAttributeNode> _attributes; 1381 List<XmlAttributeNode> _attributes;
1305 1382
1306 /** 1383 /**
1307 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not` null`). The token may be the same token as [nodeEnd] if there are no child[tagNo des]. 1384 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not
1385 * `null`). The token may be the same token as [nodeEnd] if there are no child
1386 * [tagNodes].
1308 */ 1387 */
1309 Token _attributeEnd; 1388 Token _attributeEnd;
1310 1389
1311 /** 1390 /**
1312 * The tag nodes contained in the receiver (not `null`, contains no `null`s). 1391 * The tag nodes contained in the receiver (not `null`, contains no `null`s).
1313 */ 1392 */
1314 List<XmlTagNode> _tagNodes; 1393 List<XmlTagNode> _tagNodes;
1315 1394
1316 /** 1395 /**
1317 * The token (not `null`) after the content, which may be 1396 * The token (not `null`) after the content, which may be
(...skipping 14 matching lines...) Expand all
1332 */ 1411 */
1333 Token _closingTag; 1412 Token _closingTag;
1334 1413
1335 /** 1414 /**
1336 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). 1415 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`).
1337 */ 1416 */
1338 Token _nodeEnd; 1417 Token _nodeEnd;
1339 1418
1340 /** 1419 /**
1341 * Construct a new instance representing an XML or HTML element 1420 * Construct a new instance representing an XML or HTML element
1421 *
1342 * @param nodeStart the starting [TokenType#LT] token (not `null`) 1422 * @param nodeStart the starting [TokenType#LT] token (not `null`)
1343 * @param tag the [TokenType#TAG] token after the starting '&lt;' (not `null`) . 1423 * @param tag the [TokenType#TAG] token after the starting '&lt;' (not `null`) .
1344 * @param attributes the attributes associated with this element or [NO_ATTRIB UTES] (not`null`, contains no `null`s) 1424 * @param attributes the attributes associated with this element or [NO_ATTRIB UTES] (not
1425 * `null`, contains no `null`s)
1345 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after the 1426 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after the
1346 * attributes (not `null`). The token may be the same token as [nodeEnd] if 1427 * attributes (not `null`). The token may be the same token as [nodeE nd] if
1347 * there are no child [tagNodes]. 1428 * there are no child [tagNodes].
1348 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul l`, 1429 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul l`,
1349 * contains no `null`s) 1430 * contains no `null`s)
1350 * @param contentEnd the token (not `null`) after the content, which may be 1431 * @param contentEnd the token (not `null`) after the content, which may be
1351 * 1432 *
1352 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or 1433 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or
1353 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is 1434 * * (2) the [TokenType#LT] nodeStart of the next sibling node if thi s node is
1354 * self closing or the attributeEnd is [TokenType#SLASH_GT], or 1435 * self closing or the attributeEnd is [TokenType#SLASH_GT], or
1355 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la st 1436 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the last
1356 * node in the stream [TokenType#LT_SLASH] token after the content, or `null`i f there is no content and the attributes ended with [TokenType#SLASH_GT]. 1437 * node in the stream [TokenType#LT_SLASH] token after the content, o r `null`
1438 * if there is no content and the attributes ended with [TokenType#SL ASH_GT].
1357 * 1439 *
1358 * @param closingTag the closing [TokenType#TAG] after the child elements or ` null` if 1440 * @param closingTag the closing [TokenType#TAG] after the child elements or ` null` if
1359 * there is no content and the attributes ended with [TokenType#SLASH_GT] 1441 * there is no content and the attributes ended with [TokenType#SLASH _GT]
1360 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`) 1442 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not
1443 * `null`)
1361 */ 1444 */
1362 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T oken nodeEnd) { 1445 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T oken nodeEnd) {
1363 this._nodeStart = nodeStart; 1446 this._nodeStart = nodeStart;
1364 this._tag = tag; 1447 this._tag = tag;
1365 this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); 1448 this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES);
1366 this._attributeEnd = attributeEnd; 1449 this._attributeEnd = attributeEnd;
1367 this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); 1450 this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES);
1368 this._contentEnd = contentEnd; 1451 this._contentEnd = contentEnd;
1369 this._closingTag = closingTag; 1452 this._closingTag = closingTag;
1370 this._nodeEnd = nodeEnd; 1453 this._nodeEnd = nodeEnd;
1371 } 1454 }
1372 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); 1455 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
1373 1456
1374 /** 1457 /**
1375 * Answer the attribute with the specified name. 1458 * Answer the attribute with the specified name.
1459 *
1376 * @param name the attribute name 1460 * @param name the attribute name
1377 * @return the attribute or `null` if no matching attribute is found 1461 * @return the attribute or `null` if no matching attribute is found
1378 */ 1462 */
1379 XmlAttributeNode getAttribute(String name2) { 1463 XmlAttributeNode getAttribute(String name2) {
1380 for (XmlAttributeNode attribute in _attributes) { 1464 for (XmlAttributeNode attribute in _attributes) {
1381 if (attribute.name.lexeme == name2) { 1465 if (attribute.name.lexeme == name2) {
1382 return attribute; 1466 return attribute;
1383 } 1467 }
1384 } 1468 }
1385 return null; 1469 return null;
1386 } 1470 }
1387 1471
1388 /** 1472 /**
1389 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not` null`). The token may be the same token as [nodeEnd] if there are no child[tagNo des]. 1473 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not
1474 * `null`). The token may be the same token as [nodeEnd] if there are no child
1475 * [tagNodes].
1476 *
1390 * @return the token (not `null`) 1477 * @return the token (not `null`)
1391 */ 1478 */
1392 Token get attributeEnd => _attributeEnd; 1479 Token get attributeEnd => _attributeEnd;
1393 1480
1394 /** 1481 /**
1395 * Answer the receiver's attributes. Callers should not manipulate the returne d list to edit the 1482 * Answer the receiver's attributes. Callers should not manipulate the returne d list to edit the
1396 * AST structure. 1483 * AST structure.
1484 *
1397 * @return the attributes (not `null`, contains no `null`s) 1485 * @return the attributes (not `null`, contains no `null`s)
1398 */ 1486 */
1399 List<XmlAttributeNode> get attributes => _attributes; 1487 List<XmlAttributeNode> get attributes => _attributes;
1400 1488
1401 /** 1489 /**
1402 * Find the attribute with the given name (see [getAttribute] and answer the l exeme 1490 * Find the attribute with the given name (see [getAttribute] and answer the l exeme
1403 * for the attribute's value token without the leading and trailing quotes (se e[XmlAttributeNode#getText]). 1491 * for the attribute's value token without the leading and trailing quotes (se e
1492 * [XmlAttributeNode#getText]).
1493 *
1404 * @param name the attribute name 1494 * @param name the attribute name
1405 * @return the attribute text or `null` if no matching attribute is found 1495 * @return the attribute text or `null` if no matching attribute is found
1406 */ 1496 */
1407 String getAttributeText(String name) { 1497 String getAttributeText(String name) {
1408 XmlAttributeNode attribute = getAttribute(name); 1498 XmlAttributeNode attribute = getAttribute(name);
1409 return attribute != null ? attribute.text : null; 1499 return attribute != null ? attribute.text : null;
1410 } 1500 }
1411 Token get beginToken => _nodeStart; 1501 Token get beginToken => _nodeStart;
1412 1502
1413 /** 1503 /**
1414 * The the closing [TokenType#TAG] after the child elements or `null` if there is no 1504 * The the closing [TokenType#TAG] after the child elements or `null` if there is no
1415 * content and the attributes ended with [TokenType#SLASH_GT] 1505 * content and the attributes ended with [TokenType#SLASH_GT]
1506 *
1416 * @return the closing tag or `null` 1507 * @return the closing tag or `null`
1417 */ 1508 */
1418 Token get closingTag => _closingTag; 1509 Token get closingTag => _closingTag;
1419 1510
1420 /** 1511 /**
1421 * Answer a string representing the content contained in the receiver. This in cludes the textual 1512 * Answer a string representing the content contained in the receiver. This in cludes the textual
1422 * representation of any child tag nodes ([getTagNodes]). Whitespace between ' &lt;', 1513 * representation of any child tag nodes ([getTagNodes]). Whitespace between ' &lt;',
1423 * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved. 1514 * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
1515 *
1424 * @return the content (not `null`) 1516 * @return the content (not `null`)
1425 */ 1517 */
1426 String get content { 1518 String get content {
1427 Token token = _attributeEnd.next; 1519 Token token = _attributeEnd.next;
1428 if (identical(token, _contentEnd)) { 1520 if (identical(token, _contentEnd)) {
1429 return ""; 1521 return "";
1430 } 1522 }
1431 String content = token.lexeme; 1523 String content = token.lexeme;
1432 token = token.next; 1524 token = token.next;
1433 if (identical(token, _contentEnd)) { 1525 if (identical(token, _contentEnd)) {
(...skipping 10 matching lines...) Expand all
1444 /** 1536 /**
1445 * Answer the token (not `null`) after the content, which may be 1537 * Answer the token (not `null`) after the content, which may be
1446 * 1538 *
1447 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or 1539 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or
1448 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is self 1540 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is self
1449 * closing or the attributeEnd is [TokenType#SLASH_GT], or 1541 * closing or the attributeEnd is [TokenType#SLASH_GT], or
1450 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la st node in 1542 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la st node in
1451 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there is no 1543 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there is no
1452 * content and the attributes ended with [TokenType#SLASH_GT]. 1544 * content and the attributes ended with [TokenType#SLASH_GT].
1453 * 1545 *
1546 *
1454 * @return the token (not `null`) 1547 * @return the token (not `null`)
1455 */ 1548 */
1456 Token get contentEnd => _contentEnd; 1549 Token get contentEnd => _contentEnd;
1457 Token get endToken { 1550 Token get endToken {
1458 if (_nodeEnd != null) { 1551 if (_nodeEnd != null) {
1459 return _nodeEnd; 1552 return _nodeEnd;
1460 } 1553 }
1461 if (_closingTag != null) { 1554 if (_closingTag != null) {
1462 return _closingTag; 1555 return _closingTag;
1463 } 1556 }
1464 if (_contentEnd != null) { 1557 if (_contentEnd != null) {
1465 return _contentEnd; 1558 return _contentEnd;
1466 } 1559 }
1467 if (!_tagNodes.isEmpty) { 1560 if (!_tagNodes.isEmpty) {
1468 return _tagNodes[_tagNodes.length - 1].endToken; 1561 return _tagNodes[_tagNodes.length - 1].endToken;
1469 } 1562 }
1470 if (_attributeEnd != null) { 1563 if (_attributeEnd != null) {
1471 return _attributeEnd; 1564 return _attributeEnd;
1472 } 1565 }
1473 if (!_attributes.isEmpty) { 1566 if (!_attributes.isEmpty) {
1474 return _attributes[_attributes.length - 1].endToken; 1567 return _attributes[_attributes.length - 1].endToken;
1475 } 1568 }
1476 return _tag; 1569 return _tag;
1477 } 1570 }
1478 1571
1479 /** 1572 /**
1480 * Answer the ending [TokenType#GT] or [TokenType#SLASH_GT] token. 1573 * Answer the ending [TokenType#GT] or [TokenType#SLASH_GT] token.
1574 *
1481 * @return the token (not `null`) 1575 * @return the token (not `null`)
1482 */ 1576 */
1483 Token get nodeEnd => _nodeEnd; 1577 Token get nodeEnd => _nodeEnd;
1484 1578
1485 /** 1579 /**
1486 * Answer the starting [TokenType#LT] token. 1580 * Answer the starting [TokenType#LT] token.
1581 *
1487 * @return the token (not `null`) 1582 * @return the token (not `null`)
1488 */ 1583 */
1489 Token get nodeStart => _nodeStart; 1584 Token get nodeStart => _nodeStart;
1490 1585
1491 /** 1586 /**
1492 * Answer the [TokenType#TAG] token after the starting '&lt;'. 1587 * Answer the [TokenType#TAG] token after the starting '&lt;'.
1588 *
1493 * @return the token (not `null`) 1589 * @return the token (not `null`)
1494 */ 1590 */
1495 Token get tag => _tag; 1591 Token get tag => _tag;
1496 1592
1497 /** 1593 /**
1498 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list 1594 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1499 * to edit the AST structure. 1595 * to edit the AST structure.
1596 *
1500 * @return the children (not `null`, contains no `null`s) 1597 * @return the children (not `null`, contains no `null`s)
1501 */ 1598 */
1502 List<XmlTagNode> get tagNodes => _tagNodes; 1599 List<XmlTagNode> get tagNodes => _tagNodes;
1503 void visitChildren(XmlVisitor<Object> visitor) { 1600 void visitChildren(XmlVisitor<Object> visitor) {
1504 for (XmlAttributeNode node in _attributes) { 1601 for (XmlAttributeNode node in _attributes) {
1505 node.accept(visitor); 1602 node.accept(visitor);
1506 } 1603 }
1507 for (XmlTagNode node in _tagNodes) { 1604 for (XmlTagNode node in _tagNodes) {
1508 node.accept(visitor); 1605 node.accept(visitor);
1509 } 1606 }
1510 } 1607 }
1511 1608
1512 /** 1609 /**
1513 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt y 1610 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt y
1514 */ 1611 */
1515 List becomeParentOfEmpty(List children, List ifEmpty) { 1612 List becomeParentOfEmpty(List children, List ifEmpty) {
1516 if (children != null && children.isEmpty) { 1613 if (children != null && children.isEmpty) {
1517 return ifEmpty; 1614 return ifEmpty;
1518 } 1615 }
1519 return becomeParentOf(children); 1616 return becomeParentOf(children);
1520 } 1617 }
1521 } 1618 }
1522 /** 1619 /**
1523 * Instances of the class `HtmlParser` are used to parse tokens into a AST struc ture comprised 1620 * Instances of the class `HtmlParser` are used to parse tokens into a AST struc ture comprised
1524 * of [XmlNode]s. 1621 * of [XmlNode]s.
1622 *
1525 * @coverage dart.engine.html 1623 * @coverage dart.engine.html
1526 */ 1624 */
1527 class HtmlParser extends XmlParser { 1625 class HtmlParser extends XmlParser {
1528 static Set<String> SELF_CLOSING = new Set<String>(); 1626 static Set<String> SELF_CLOSING = new Set<String>();
1529 1627
1530 /** 1628 /**
1531 * Construct a parser for the specified source. 1629 * Construct a parser for the specified source.
1630 *
1532 * @param source the source being parsed 1631 * @param source the source being parsed
1533 */ 1632 */
1534 HtmlParser(Source source) : super(source) { 1633 HtmlParser(Source source) : super(source) {
1535 } 1634 }
1536 1635
1537 /** 1636 /**
1538 * Parse the tokens specified by the given scan result. 1637 * Parse the tokens specified by the given scan result.
1638 *
1539 * @param scanResult the result of scanning an HTML source (not `null`) 1639 * @param scanResult the result of scanning an HTML source (not `null`)
1540 * @return the parse result (not `null`) 1640 * @return the parse result (not `null`)
1541 */ 1641 */
1542 HtmlParseResult parse(HtmlScanResult scanResult) { 1642 HtmlParseResult parse(HtmlScanResult scanResult) {
1543 Token firstToken = scanResult.token; 1643 Token firstToken = scanResult.token;
1544 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken); 1644 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
1545 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken); 1645 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
1546 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu lt.lineStarts, unit); 1646 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu lt.lineStarts, unit);
1547 } 1647 }
1548 1648
1549 /** 1649 /**
1550 * Scan then parse the specified source. 1650 * Scan then parse the specified source.
1651 *
1551 * @param source the source to be scanned and parsed (not `null`) 1652 * @param source the source to be scanned and parsed (not `null`)
1552 * @return the parse result (not `null`) 1653 * @return the parse result (not `null`)
1553 */ 1654 */
1554 HtmlParseResult parse2(Source source) { 1655 HtmlParseResult parse2(Source source) {
1555 HtmlScanner scanner = new HtmlScanner(source); 1656 HtmlScanner scanner = new HtmlScanner(source);
1556 source.getContents(scanner); 1657 source.getContents(scanner);
1557 return parse(scanner.result); 1658 return parse(scanner.result);
1558 } 1659 }
1559 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); 1660 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
1560 } 1661 }
1561 /** 1662 /**
1562 * Instances of the class `HtmlUnit` represent the contents of an HTML file. 1663 * Instances of the class `HtmlUnit` represent the contents of an HTML file.
1664 *
1563 * @coverage dart.engine.html 1665 * @coverage dart.engine.html
1564 */ 1666 */
1565 class HtmlUnit extends XmlNode { 1667 class HtmlUnit extends XmlNode {
1566 1668
1567 /** 1669 /**
1568 * The first token in the token stream that was parsed to form this HTML unit. 1670 * The first token in the token stream that was parsed to form this HTML unit.
1569 */ 1671 */
1570 Token _beginToken; 1672 Token _beginToken;
1571 1673
1572 /** 1674 /**
1573 * The last token in the token stream that was parsed to form this compilation unit. This token 1675 * The last token in the token stream that was parsed to form this compilation unit. This token
1574 * should always have a type of [TokenType.EOF]. 1676 * should always have a type of [TokenType.EOF].
1575 */ 1677 */
1576 Token _endToken; 1678 Token _endToken;
1577 1679
1578 /** 1680 /**
1579 * The tag nodes contained in the receiver (not `null`, contains no `null`s). 1681 * The tag nodes contained in the receiver (not `null`, contains no `null`s).
1580 */ 1682 */
1581 List<XmlTagNode> _tagNodes; 1683 List<XmlTagNode> _tagNodes;
1582 1684
1583 /** 1685 /**
1584 * The element associated with this HTML unit or `null` if the receiver is not resolved. 1686 * The element associated with this HTML unit or `null` if the receiver is not resolved.
1585 */ 1687 */
1586 HtmlElementImpl _element; 1688 HtmlElementImpl _element;
1587 1689
1588 /** 1690 /**
1589 * Construct a new instance representing the content of an HTML file. 1691 * Construct a new instance representing the content of an HTML file.
1692 *
1590 * @param beginToken the first token in the file (not `null`) 1693 * @param beginToken the first token in the file (not `null`)
1591 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n ull`s) 1694 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n ull`s)
1592 * @param endToken the last token in the token stream which should be of type[ TokenType.EOF] 1695 * @param endToken the last token in the token stream which should be of type
1696 * [TokenType.EOF]
1593 */ 1697 */
1594 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { 1698 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
1595 this._beginToken = beginToken; 1699 this._beginToken = beginToken;
1596 this._tagNodes = becomeParentOf(tagNodes); 1700 this._tagNodes = becomeParentOf(tagNodes);
1597 this._endToken = endToken; 1701 this._endToken = endToken;
1598 } 1702 }
1599 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); 1703 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
1600 Token get beginToken => _beginToken; 1704 Token get beginToken => _beginToken;
1601 1705
1602 /** 1706 /**
1603 * Return the element associated with this HTML unit. 1707 * Return the element associated with this HTML unit.
1708 *
1604 * @return the element or `null` if the receiver is not resolved 1709 * @return the element or `null` if the receiver is not resolved
1605 */ 1710 */
1606 HtmlElementImpl get element => _element; 1711 HtmlElementImpl get element => _element;
1607 Token get endToken => _endToken; 1712 Token get endToken => _endToken;
1608 1713
1609 /** 1714 /**
1610 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list 1715 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1611 * to edit the AST structure. 1716 * to edit the AST structure.
1717 *
1612 * @return the children (not `null`, contains no `null`s) 1718 * @return the children (not `null`, contains no `null`s)
1613 */ 1719 */
1614 List<XmlTagNode> get tagNodes => _tagNodes; 1720 List<XmlTagNode> get tagNodes => _tagNodes;
1615 1721
1616 /** 1722 /**
1617 * Set the element associated with this HTML unit. 1723 * Set the element associated with this HTML unit.
1724 *
1618 * @param element the element 1725 * @param element the element
1619 */ 1726 */
1620 void set element(HtmlElementImpl element2) { 1727 void set element(HtmlElementImpl element2) {
1621 this._element = element2; 1728 this._element = element2;
1622 } 1729 }
1623 void visitChildren(XmlVisitor<Object> visitor) { 1730 void visitChildren(XmlVisitor<Object> visitor) {
1624 for (XmlTagNode node in _tagNodes) { 1731 for (XmlTagNode node in _tagNodes) {
1625 node.accept(visitor); 1732 node.accept(visitor);
1626 } 1733 }
1627 } 1734 }
1628 } 1735 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698