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

Side by Side Diff: pkg/analyzer-experimental/lib/src/generated/html.dart

Issue 12838003: Rename analyzer-experimental to analyzer_experimental. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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
(Empty)
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.
3
4 library engine.html;
5
6 import 'dart:collection';
7 import 'java_core.dart';
8 import 'source.dart';
9 import 'error.dart';
10 import 'instrumentation.dart';
11 import 'element.dart' show HtmlElementImpl;
12
13 /**
14 * Instances of the class {@code Token} represent a token that was scanned from the input. Each
15 * token knows which token follows it, acting as the head of a linked list of to kens.
16 * @coverage dart.engine.html
17 */
18 class Token {
19 /**
20 * The offset from the beginning of the file to the first character in the tok en.
21 */
22 int _offset = 0;
23 /**
24 * The previous token in the token stream.
25 */
26 Token _previous;
27 /**
28 * The next token in the token stream.
29 */
30 Token _next;
31 /**
32 * The type of the token.
33 */
34 TokenType _type;
35 /**
36 * The lexeme represented by this token.
37 */
38 String _value;
39 /**
40 * Initialize a newly created token.
41 * @param type the token type (not {@code null})
42 * @param offset the offset from the beginning of the file to the first charac ter in the token
43 */
44 Token.con1(TokenType type, int offset) {
45 _jtd_constructor_145_impl(type, offset);
46 }
47 _jtd_constructor_145_impl(TokenType type, int offset) {
48 _jtd_constructor_146_impl(type, offset, type.lexeme);
49 }
50 /**
51 * Initialize a newly created token.
52 * @param type the token type (not {@code null})
53 * @param offset the offset from the beginning of the file to the first charac ter in the token
54 * @param value the lexeme represented by this token (not {@code null})
55 */
56 Token.con2(TokenType type4, int offset3, String value7) {
57 _jtd_constructor_146_impl(type4, offset3, value7);
58 }
59 _jtd_constructor_146_impl(TokenType type4, int offset3, String value7) {
60 this._type = type4;
61 this._value = value7;
62 this._offset = offset3;
63 }
64 /**
65 * Return the offset from the beginning of the file to the character after las t character of the
66 * token.
67 * @return the offset from the beginning of the file to the first character af ter last character
68 * of the token
69 */
70 int get end => _offset + length;
71 /**
72 * Return the number of characters in the node's source range.
73 * @return the number of characters in the node's source range
74 */
75 int get length => lexeme.length;
76 /**
77 * Return the lexeme that represents this token.
78 * @return the lexeme (not {@code null})
79 */
80 String get lexeme => _value;
81 /**
82 * Return the next token in the token stream.
83 * @return the next token in the token stream
84 */
85 Token get next => _next;
86 /**
87 * Return the offset from the beginning of the file to the first character in the token.
88 * @return the offset from the beginning of the file to the first character in the token
89 */
90 int get offset => _offset;
91 /**
92 * Return the previous token in the token stream.
93 * @return the previous token in the token stream
94 */
95 Token get previous => _previous;
96 /**
97 * Answer the token type for the receiver.
98 * @return the token type (not {@code null})
99 */
100 TokenType get type => _type;
101 /**
102 * Return {@code true} if this token is a synthetic token. A synthetic token i s a token that was
103 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always
104 * have a length of zero ({@code 0}).
105 * @return {@code true} if this token is a synthetic token
106 */
107 bool isSynthetic() => length == 0;
108 /**
109 * Set the next token in the token stream to the given token. This has the sid e-effect of setting
110 * this token to be the previous token for the given token.
111 * @param token the next token in the token stream
112 * @return the token that was passed in
113 */
114 Token setNext(Token token) {
115 _next = token;
116 token.previous = this;
117 return token;
118 }
119 String toString() => lexeme;
120 /**
121 * Set the previous token in the token stream to the given token.
122 * @param previous the previous token in the token stream
123 */
124 void set previous(Token previous2) {
125 this._previous = previous2;
126 }
127 }
128 /**
129 * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file.
130 * @coverage dart.engine.html
131 */
132 class HtmlParseResult extends HtmlScanResult {
133 /**
134 * The unit containing the parsed information (not {@code null}).
135 */
136 HtmlUnit _unit;
137 HtmlParseResult(Token token, List<int> lineStarts, HtmlUnit unit) : super(toke n, lineStarts) {
138 this._unit = unit;
139 }
140 /**
141 * Answer the unit generated by parsing the source
142 * @return the unit (not {@code null})
143 */
144 HtmlUnit get htmlUnit => _unit;
145 }
146 /**
147 * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor t hat will recursively
148 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
149 * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttribute Node}s and{@link XmlTagNode}s to be visited.
150 * <p>
151 * Subclasses that override a visit method must either invoke the overridden vis it method or must
152 * explicitly ask the visited node to visit its children. Failure to do so will cause the children
153 * of the visited node to not be visited.
154 * @coverage dart.engine.html
155 */
156 class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
157 R visitHtmlUnit(HtmlUnit node) {
158 node.visitChildren(this);
159 return null;
160 }
161 R visitXmlAttributeNode(XmlAttributeNode node) {
162 node.visitChildren(this);
163 return null;
164 }
165 R visitXmlTagNode(XmlTagNode node) {
166 node.visitChildren(this);
167 return null;
168 }
169 }
170 /**
171 * The abstract class {@code XmlNode} defines behavior common to all XML/HTML no des.
172 * @coverage dart.engine.html
173 */
174 abstract class XmlNode {
175 /**
176 * The parent of the node, or {@code null} if the node is the root of an AST s tructure.
177 */
178 XmlNode _parent;
179 /**
180 * Use the given visitor to visit this node.
181 * @param visitor the visitor that will visit this node
182 * @return the value returned by the visitor as a result of visiting this node
183 */
184 accept(XmlVisitor visitor);
185 /**
186 * Return the first token included in this node's source range.
187 * @return the first token or {@code null} if none
188 */
189 Token get beginToken;
190 /**
191 * Return the offset of the character immediately following the last character of this node's
192 * source range. This is equivalent to {@code node.getOffset() + node.getLengt h()}. For an html
193 * unit this will be equal to the length of the unit's source.
194 * @return the offset of the character just past the node's source range
195 */
196 int get end => offset + length;
197 /**
198 * Return the last token included in this node's source range.
199 * @return the last token or {@code null} if none
200 */
201 Token get endToken;
202 /**
203 * Return the number of characters in the node's source range.
204 * @return the number of characters in the node's source range
205 */
206 int get length {
207 Token beginToken4 = beginToken;
208 Token endToken4 = endToken;
209 if (beginToken4 == null || endToken4 == null) {
210 return -1;
211 }
212 return endToken4.offset + endToken4.length - beginToken4.offset;
213 }
214 /**
215 * Return the offset from the beginning of the file to the first character in the node's source
216 * range.
217 * @return the offset from the beginning of the file to the first character in the node's source
218 * range
219 */
220 int get offset {
221 Token beginToken5 = beginToken;
222 if (beginToken5 == null) {
223 return -1;
224 }
225 return beginToken.offset;
226 }
227 /**
228 * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
229 * <p>
230 * Note that the relationship between an AST node and its parent node may chan ge over the lifetime
231 * of a node.
232 * @return the parent of this node, or {@code null} if none
233 */
234 XmlNode get parent => _parent;
235 /**
236 * Use the given visitor to visit all of the children of this node. The childr en will be visited
237 * in source order.
238 * @param visitor the visitor that will be used to visit the children of this node
239 */
240 void visitChildren(XmlVisitor<Object> visitor);
241 /**
242 * Make this node the parent of the given child nodes.
243 * @param children the nodes that will become the children of this node
244 * @return the nodes that were made children of this node
245 */
246 List<XmlNode> becomeParentOf(List<XmlNode> children) {
247 if (children != null) {
248 for (JavaIterator<XmlNode> iter = new JavaIterator(children); iter.hasNext ;) {
249 XmlNode node = iter.next();
250 node.parent = this;
251 }
252 }
253 return children;
254 }
255 /**
256 * Make this node the parent of the given child node.
257 * @param child the node that will become a child of this node
258 * @return the node that was made a child of this node
259 */
260 XmlNode becomeParentOf2(XmlNode child) {
261 if (child != null) {
262 XmlNode node = child;
263 node.parent = this;
264 }
265 return child;
266 }
267 /**
268 * Set the parent of this node to the given node.
269 * @param newParent the node that is to be made the parent of this node
270 */
271 void set parent(XmlNode newParent) {
272 _parent = newParent;
273 }
274 }
275 /**
276 * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing
277 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
278 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel y visit a whole
279 * structure) and that only need to visit a small number of node types.
280 */
281 class SimpleXmlVisitor<R> implements XmlVisitor<R> {
282 R visitHtmlUnit(HtmlUnit htmlUnit) => null;
283 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
284 R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
285 }
286 /**
287 * The abstract class {@code AbstractScanner} implements a scanner for HTML code . Subclasses are
288 * required to implement the interface used to access the characters being scann ed.
289 * @coverage dart.engine.html
290 */
291 abstract class AbstractScanner {
292 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
293 /**
294 * The source being scanned.
295 */
296 Source _source;
297 /**
298 * The token pointing to the head of the linked list of tokens.
299 */
300 Token _tokens;
301 /**
302 * The last token that was scanned.
303 */
304 Token _tail;
305 /**
306 * A list containing the offsets of the first character of each line in the so urce code.
307 */
308 List<int> _lineStarts = new List<int>();
309 /**
310 * An array of element tags for which the content between tags should be consi der a single token.
311 */
312 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
313 /**
314 * Initialize a newly created scanner.
315 * @param source the source being scanned
316 */
317 AbstractScanner(Source source) {
318 this._source = source;
319 _tokens = new Token.con1(TokenType.EOF, -1);
320 _tokens.setNext(_tokens);
321 _tail = _tokens;
322 recordStartOfLine();
323 }
324 /**
325 * Return an array containing the offsets of the first character of each line in the source code.
326 * @return an array containing the offsets of the first character of each line in the source code
327 */
328 List<int> get lineStarts => _lineStarts;
329 /**
330 * Return the current offset relative to the beginning of the file. Return the initial offset if
331 * the scanner has not yet scanned the source code, and one (1) past the end o f the source code if
332 * the source code has been scanned.
333 * @return the current offset of the scanner in the source
334 */
335 int get offset;
336 /**
337 * Answer the source being scanned.
338 * @return the source or {@code null} if undefined
339 */
340 Source get source => _source;
341 /**
342 * Set array of element tags for which the content between tags should be cons ider a single token.
343 */
344 void set passThroughElements(List<String> passThroughElements2) {
345 this._passThroughElements = passThroughElements2 != null ? passThroughElemen ts2 : _NO_PASS_THROUGH_ELEMENTS;
346 }
347 /**
348 * Scan the source code to produce a list of tokens representing the source.
349 * @return the first token in the list of tokens that were produced
350 */
351 Token tokenize() {
352 scan();
353 appendEofToken();
354 return firstToken();
355 }
356 /**
357 * Advance the current position and return the character at the new current po sition.
358 * @return the character at the new current position
359 */
360 int advance();
361 /**
362 * Return the substring of the source code between the start offset and the mo dified current
363 * position. The current position is modified by adding the end delta.
364 * @param start the offset to the beginning of the string, relative to the sta rt of the file
365 * @param endDelta the number of character after the current location to be in cluded in the
366 * string, or the number of characters before the current location to be exclu ded if the
367 * offset is negative
368 * @return the specified substring of the source code
369 */
370 String getString(int start, int endDelta);
371 /**
372 * Return the character at the current position without changing the current p osition.
373 * @return the character at the current position
374 */
375 int peek();
376 /**
377 * Record the fact that we are at the beginning of a new line in the source.
378 */
379 void recordStartOfLine() {
380 _lineStarts.add(offset);
381 }
382 void appendEofToken() {
383 Token eofToken = new Token.con1(TokenType.EOF, offset);
384 eofToken.setNext(eofToken);
385 _tail = _tail.setNext(eofToken);
386 }
387 Token emit(Token token) {
388 _tail.setNext(token);
389 _tail = token;
390 return token;
391 }
392 Token emit2(TokenType type, int start) => emit(new Token.con1(type, start));
393 Token emit3(TokenType type, int start, int count) => emit(new Token.con2(type, start, getString(start, count)));
394 Token firstToken() => _tokens.next;
395 int recordStartOfLineAndAdvance(int c) {
396 if (c == 0xD) {
397 c = advance();
398 if (c == 0xA) {
399 c = advance();
400 }
401 recordStartOfLine();
402 } else if (c == 0xA) {
403 c = advance();
404 recordStartOfLine();
405 } else {
406 c = advance();
407 }
408 return c;
409 }
410 void scan() {
411 bool inBrackets = false;
412 bool passThrough = false;
413 int c = advance();
414 while (c >= 0) {
415 int start = offset;
416 if (c == 0x3C) {
417 c = advance();
418 if (c == 0x21) {
419 c = advance();
420 if (c == 0x2D && peek() == 0x2D) {
421 c = advance();
422 int dashCount = 1;
423 while (c >= 0) {
424 if (c == 0x2D) {
425 dashCount++;
426 } else if (c == 0x3E && dashCount >= 2) {
427 c = advance();
428 break;
429 } else {
430 dashCount = 0;
431 }
432 c = recordStartOfLineAndAdvance(c);
433 }
434 emit3(TokenType.COMMENT, start, -1);
435 if (_tail.length < 7) {
436 }
437 } else {
438 while (c >= 0) {
439 if (c == 0x3E) {
440 c = advance();
441 break;
442 }
443 c = recordStartOfLineAndAdvance(c);
444 }
445 emit3(TokenType.DECLARATION, start, -1);
446 if (!_tail.lexeme.endsWith(">")) {
447 }
448 }
449 } else if (c == 0x3F) {
450 while (c >= 0) {
451 if (c == 0x3F) {
452 c = advance();
453 if (c == 0x3E) {
454 c = advance();
455 break;
456 }
457 } else {
458 c = recordStartOfLineAndAdvance(c);
459 }
460 }
461 emit3(TokenType.DIRECTIVE, start, -1);
462 if (_tail.length < 4) {
463 }
464 } else if (c == 0x2F) {
465 emit2(TokenType.LT_SLASH, start);
466 inBrackets = true;
467 c = advance();
468 } else {
469 inBrackets = true;
470 emit2(TokenType.LT, start);
471 while (Character.isWhitespace(c)) {
472 c = recordStartOfLineAndAdvance(c);
473 }
474 if (Character.isLetterOrDigit(c)) {
475 int tagStart = offset;
476 c = advance();
477 while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
478 c = advance();
479 }
480 emit3(TokenType.TAG, tagStart, -1);
481 String tag = _tail.lexeme;
482 for (String str in _passThroughElements) {
483 if (str == tag) {
484 passThrough = true;
485 break;
486 }
487 }
488 }
489 }
490 } else if (c == 0x3E) {
491 emit2(TokenType.GT, start);
492 inBrackets = false;
493 c = advance();
494 if (passThrough) {
495 while (c >= 0 && (c != 0x3C || peek() != 0x2F)) {
496 c = recordStartOfLineAndAdvance(c);
497 }
498 if (start + 1 < offset) {
499 emit3(TokenType.TEXT, start + 1, -1);
500 }
501 passThrough = false;
502 }
503 } else if (c == 0x2F && peek() == 0x3E) {
504 advance();
505 emit2(TokenType.SLASH_GT, start);
506 inBrackets = false;
507 c = advance();
508 } else if (!inBrackets) {
509 c = recordStartOfLineAndAdvance(c);
510 while (c != 0x3C && c >= 0) {
511 c = recordStartOfLineAndAdvance(c);
512 }
513 emit3(TokenType.TEXT, start, -1);
514 } else if (c == 0x22 || c == 0x27) {
515 int endQuote = c;
516 c = advance();
517 while (c >= 0) {
518 if (c == endQuote) {
519 c = advance();
520 break;
521 }
522 c = recordStartOfLineAndAdvance(c);
523 }
524 emit3(TokenType.STRING, start, -1);
525 } else if (c == 0x3D) {
526 emit2(TokenType.EQ, start);
527 c = advance();
528 } else if (Character.isWhitespace(c)) {
529 do {
530 c = recordStartOfLineAndAdvance(c);
531 } while (Character.isWhitespace(c));
532 } else if (Character.isLetterOrDigit(c)) {
533 c = advance();
534 while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
535 c = advance();
536 }
537 emit3(TokenType.TAG, start, -1);
538 } else {
539 emit3(TokenType.TEXT, start, 0);
540 c = advance();
541 }
542 }
543 }
544 }
545 /**
546 * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file.
547 * @coverage dart.engine.html
548 */
549 class HtmlScanResult {
550 /**
551 * The first token in the token stream (not {@code null}).
552 */
553 Token _token;
554 /**
555 * The line start information that was produced.
556 */
557 List<int> _lineStarts;
558 HtmlScanResult(Token token, List<int> lineStarts) {
559 this._token = token;
560 this._lineStarts = lineStarts;
561 }
562 /**
563 * Answer the line start information that was produced.
564 * @return an array of line starts (not {@code null})
565 */
566 List<int> get lineStarts => _lineStarts;
567 /**
568 * Answer the first token in the token stream.
569 * @return the token (not {@code null})
570 */
571 Token get token => _token;
572 }
573 /**
574 * Instances of the class {@code StringScanner} implement a scanner that reads f rom a string. The
575 * scanning logic is in the superclass.
576 * @coverage dart.engine.html
577 */
578 class StringScanner extends AbstractScanner {
579 /**
580 * The string from which characters will be read.
581 */
582 String _string;
583 /**
584 * The number of characters in the string.
585 */
586 int _stringLength = 0;
587 /**
588 * The index, relative to the string, of the last character that was read.
589 */
590 int _charOffset = 0;
591 /**
592 * Initialize a newly created scanner to scan the characters in the given stri ng.
593 * @param source the source being scanned
594 * @param string the string from which characters will be read
595 */
596 StringScanner(Source source, String string) : super(source) {
597 this._string = string;
598 this._stringLength = string.length;
599 this._charOffset = -1;
600 }
601 int get offset => _charOffset;
602 void set offset(int offset12) {
603 _charOffset = offset12;
604 }
605 int advance() {
606 if (++_charOffset < _stringLength) {
607 return _string.codeUnitAt(_charOffset);
608 }
609 _charOffset = _stringLength;
610 return -1;
611 }
612 String getString(int start, int endDelta) => _string.substring(start, _charOff set + 1 + endDelta);
613 int peek() {
614 if (_charOffset + 1 < _stringLength) {
615 return _string.codeUnitAt(_charOffset + 1);
616 }
617 return -1;
618 }
619 }
620 /**
621 * Instances of the class {@code CharBufferScanner} implement a scanner that rea ds from a character
622 * buffer. The scanning logic is in the superclass.
623 * @coverage dart.engine.html
624 */
625 class CharBufferScanner extends AbstractScanner {
626 /**
627 * The buffer from which characters will be read.
628 */
629 CharBuffer _buffer;
630 /**
631 * The number of characters in the buffer.
632 */
633 int _bufferLength = 0;
634 /**
635 * The index of the last character that was read.
636 */
637 int _charOffset = 0;
638 /**
639 * Initialize a newly created scanner to scan the characters in the given char acter buffer.
640 * @param source the source being scanned
641 * @param buffer the buffer from which characters will be read
642 */
643 CharBufferScanner(Source source, CharBuffer buffer) : super(source) {
644 this._buffer = buffer;
645 this._bufferLength = buffer.length();
646 this._charOffset = -1;
647 }
648 int get offset => _charOffset;
649 int advance() {
650 if (++_charOffset < _bufferLength) {
651 return _buffer.charAt(_charOffset);
652 }
653 _charOffset = _bufferLength;
654 return -1;
655 }
656 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString();
657 int peek() {
658 if (_charOffset + 1 < _bufferLength) {
659 return _buffer.charAt(_charOffset + 1);
660 }
661 return -1;
662 }
663 }
664 /**
665 * The enumeration {@code TokenType} defines the types of tokens that can be ret urned by the
666 * scanner.
667 * @coverage dart.engine.html
668 */
669 class TokenType {
670 /**
671 * The type of the token that marks the end of the input.
672 */
673 static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
674 static final TokenType EQ = new TokenType('EQ', 1, "=");
675 static final TokenType GT = new TokenType('GT', 2, ">");
676 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</");
677 static final TokenType LT = new TokenType('LT', 4, "<");
678 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>");
679 static final TokenType COMMENT = new TokenType('COMMENT', 6, null);
680 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null);
681 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null);
682 static final TokenType STRING = new TokenType('STRING', 9, null);
683 static final TokenType TAG = new TokenType('TAG', 10, null);
684 static final TokenType TEXT = new TokenType('TEXT', 11, null);
685 static final List<TokenType> values = [EOF, EQ, GT, LT_SLASH, LT, SLASH_GT, CO MMENT, DECLARATION, DIRECTIVE, STRING, TAG, TEXT];
686 final String __name;
687 final int __ordinal;
688 int get ordinal => __ordinal;
689 /**
690 * The lexeme that defines this type of token, or {@code null} if there is mor e than one possible
691 * lexeme for this type of token.
692 */
693 String _lexeme;
694 TokenType(this.__name, this.__ordinal, String lexeme) {
695 this._lexeme = lexeme;
696 }
697 /**
698 * Return the lexeme that defines this type of token, or {@code null} if there is more than one
699 * possible lexeme for this type of token.
700 * @return the lexeme that defines this type of token
701 */
702 String get lexeme => _lexeme;
703 String toString() => __name;
704 }
705 class TokenType_EOF extends TokenType {
706 TokenType_EOF(String ___name, int ___ordinal, String arg0) : super(___name, __ _ordinal, arg0);
707 String toString() => "-eof-";
708 }
709 /**
710 * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}.
711 * @coverage dart.engine.html
712 */
713 class XmlAttributeNode extends XmlNode {
714 Token _name;
715 Token _equals;
716 Token _value;
717 /**
718 * Construct a new instance representing an XML attribute.
719 * @param name the name token (not {@code null}). This may be a zero length to ken if the attribute
720 * is badly formed.
721 * @param equals the equals sign or {@code null} if none
722 * @param value the value token (not {@code null})
723 */
724 XmlAttributeNode(Token name, Token equals, Token value) {
725 this._name = name;
726 this._equals = equals;
727 this._value = value;
728 }
729 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
730 Token get beginToken => _name;
731 Token get endToken => _value;
732 /**
733 * Answer the equals sign token that appears between the name and value tokens . This may be{@code null} if the attribute is badly formed.
734 * @return the token or {@code null} if there is no equals sign between the na me and value
735 */
736 Token get equals => _equals;
737 /**
738 * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
739 * @return the name (not {@code null})
740 */
741 Token get name => _name;
742 /**
743 * Answer the lexeme for the value token without the leading and trailing quot es.
744 * @return the text or {@code null} if the value is not specified
745 */
746 String get text {
747 if (_value == null) {
748 return null;
749 }
750 String text = _value.lexeme;
751 int len = text.length;
752 if (len > 0) {
753 if (text.codeUnitAt(0) == 0x22) {
754 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
755 return text.substring(1, len - 1);
756 } else {
757 return text.substring(1);
758 }
759 } else if (text.codeUnitAt(0) == 0x27) {
760 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
761 return text.substring(1, len - 1);
762 } else {
763 return text.substring(1);
764 }
765 }
766 }
767 return text;
768 }
769 /**
770 * Answer the attribute value. A properly formed value will start and end with matching quote
771 * characters, but the value returned may not be properly formed.
772 * @return the value or {@code null} if this represents a badly formed attribu te
773 */
774 Token get value => _value;
775 void visitChildren(XmlVisitor<Object> visitor) {
776 }
777 }
778 /**
779 * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure.
780 * @coverage dart.engine.html
781 */
782 abstract class XmlVisitor<R> {
783 R visitHtmlUnit(HtmlUnit htmlUnit);
784 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
785 R visitXmlTagNode(XmlTagNode xmlTagNode);
786 }
787 /**
788 * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/>
789 * For example, the following code scans HTML source and returns the result:
790 * <pre>
791 * HtmlScanner scanner = new HtmlScanner(source);
792 * source.getContents(scanner);
793 * return scanner.getResult();
794 * </pre>
795 * @coverage dart.engine.html
796 */
797 class HtmlScanner implements Source_ContentReceiver {
798 List<String> _SCRIPT_TAG = <String> ["script"];
799 /**
800 * The source being scanned (not {@code null})
801 */
802 Source _source;
803 /**
804 * The scanner used to scan the source
805 */
806 AbstractScanner _scanner;
807 /**
808 * The first token in the token stream.
809 */
810 Token _token;
811 /**
812 * Construct a new instance to scan the specified source.
813 * @param source the source to be scanned (not {@code null})
814 */
815 HtmlScanner(Source source) {
816 this._source = source;
817 }
818 accept(CharBuffer contents) {
819 _scanner = new CharBufferScanner(_source, contents);
820 _scanner.passThroughElements = _SCRIPT_TAG;
821 _token = _scanner.tokenize();
822 }
823 void accept2(String contents) {
824 _scanner = new StringScanner(_source, contents);
825 _scanner.passThroughElements = _SCRIPT_TAG;
826 _token = _scanner.tokenize();
827 }
828 /**
829 * Answer the result of scanning the source
830 * @return the result (not {@code null})
831 */
832 HtmlScanResult get result => new HtmlScanResult(_token, _scanner.lineStarts);
833 }
834 /**
835 * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised
836 * of {@link XmlNode}s.
837 * @coverage dart.engine.html
838 */
839 class XmlParser {
840 /**
841 * The source being parsed.
842 */
843 Source _source;
844 /**
845 * The next token to be parsed.
846 */
847 Token _currentToken;
848 /**
849 * Construct a parser for the specified source.
850 * @param source the source being parsed
851 */
852 XmlParser(Source source) {
853 this._source = source;
854 }
855 /**
856 * Answer the source being parsed.
857 * @return the source
858 */
859 Source get source => _source;
860 /**
861 * Answer {@code true} if the specified tag is self closing and thus should ne ver have content or
862 * child tag nodes.
863 * @param tag the tag (not {@code null})
864 * @return {@code true} if self closing
865 */
866 bool isSelfClosing(Token tag) => false;
867 /**
868 * Parse the entire token stream and in the process, advance the current token to the end of the
869 * token stream.
870 * @return the list of tag nodes found (not {@code null}, contains no {@code n ull})
871 */
872 List<XmlTagNode> parseTopTagNodes(Token firstToken) {
873 _currentToken = firstToken;
874 List<XmlTagNode> tagNodes = new List<XmlTagNode>();
875 while (true) {
876 while (true) {
877 if (_currentToken.type == TokenType.LT) {
878 tagNodes.add(parseTagNode());
879 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken. type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
880 _currentToken = _currentToken.next;
881 } else if (_currentToken.type == TokenType.EOF) {
882 return tagNodes;
883 } else {
884 reportUnexpectedToken();
885 _currentToken = _currentToken.next;
886 }
887 break;
888 }
889 }
890 }
891 /**
892 * Answer the current token.
893 * @return the current token
894 */
895 Token get currentToken => _currentToken;
896 /**
897 * Insert a synthetic token of the specified type before the current token
898 * @param type the type of token to be inserted (not {@code null})
899 * @return the synthetic token that was inserted (not {@code null})
900 */
901 Token insertSyntheticToken(TokenType type) {
902 Token token = new Token.con2(type, _currentToken.offset, "");
903 _currentToken.previous.setNext(token);
904 token.setNext(_currentToken);
905 return token;
906 }
907 /**
908 * Parse the token stream for an attribute. This method advances the current t oken over the
909 * attribute, but should not be called if the {@link #currentToken} is not {@l ink TokenType#TAG}.
910 * @return the attribute (not {@code null})
911 */
912 XmlAttributeNode parseAttribute() {
913 Token name = _currentToken;
914 _currentToken = _currentToken.next;
915 Token equals;
916 if (identical(_currentToken.type, TokenType.EQ)) {
917 equals = _currentToken;
918 _currentToken = _currentToken.next;
919 } else {
920 reportUnexpectedToken();
921 equals = insertSyntheticToken(TokenType.EQ);
922 }
923 Token value;
924 if (identical(_currentToken.type, TokenType.STRING)) {
925 value = _currentToken;
926 _currentToken = _currentToken.next;
927 } else {
928 reportUnexpectedToken();
929 value = insertSyntheticToken(TokenType.STRING);
930 }
931 return new XmlAttributeNode(name, equals, value);
932 }
933 /**
934 * Parse the stream for a sequence of attributes. This method advances the cur rent token to the
935 * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType# EOF}.
936 * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s)
937 */
938 List<XmlAttributeNode> parseAttributes() {
939 TokenType type11 = _currentToken.type;
940 if (identical(type11, TokenType.GT) || identical(type11, TokenType.SLASH_GT) || identical(type11, TokenType.EOF)) {
941 return XmlTagNode.NO_ATTRIBUTES;
942 }
943 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
944 while (true) {
945 while (true) {
946 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp e.SLASH_GT || _currentToken.type == TokenType.EOF) {
947 return attributes;
948 } else if (_currentToken.type == TokenType.TAG) {
949 attributes.add(parseAttribute());
950 } else {
951 reportUnexpectedToken();
952 _currentToken = _currentToken.next;
953 }
954 break;
955 }
956 }
957 }
958 /**
959 * Parse the stream for a sequence of tag nodes existing within a parent tag n ode. This method
960 * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}.
961 * @return a list of nodes (not {@code null}, contains no {@code null}s)
962 */
963 List<XmlTagNode> parseChildTagNodes() {
964 TokenType type12 = _currentToken.type;
965 if (identical(type12, TokenType.LT_SLASH) || identical(type12, TokenType.EOF )) {
966 return XmlTagNode.NO_TAG_NODES;
967 }
968 List<XmlTagNode> nodes = new List<XmlTagNode>();
969 while (true) {
970 while (true) {
971 if (_currentToken.type == TokenType.LT) {
972 nodes.add(parseTagNode());
973 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ e == TokenType.EOF) {
974 return nodes;
975 } else if (_currentToken.type == TokenType.COMMENT) {
976 _currentToken = _currentToken.next;
977 } else {
978 reportUnexpectedToken();
979 _currentToken = _currentToken.next;
980 }
981 break;
982 }
983 }
984 }
985 /**
986 * Parse the token stream for the next tag node. This method advances current token over the
987 * parsed tag node, but should only be called if the current token is {@link T okenType#LT}
988 * @return the tag node or {@code null} if none found
989 */
990 XmlTagNode parseTagNode() {
991 Token nodeStart = _currentToken;
992 _currentToken = _currentToken.next;
993 Token tag;
994 if (identical(_currentToken.type, TokenType.TAG)) {
995 tag = _currentToken;
996 _currentToken = _currentToken.next;
997 } else {
998 reportUnexpectedToken();
999 tag = insertSyntheticToken(TokenType.TAG);
1000 }
1001 List<XmlAttributeNode> attributes = parseAttributes();
1002 Token attributeEnd;
1003 if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.t ype, TokenType.SLASH_GT)) {
1004 attributeEnd = _currentToken;
1005 _currentToken = _currentToken.next;
1006 } else {
1007 reportUnexpectedToken();
1008 attributeEnd = insertSyntheticToken(TokenType.SLASH_GT);
1009 }
1010 if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag)) {
1011 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode .NO_TAG_NODES, _currentToken, null, attributeEnd);
1012 }
1013 List<XmlTagNode> tagNodes = parseChildTagNodes();
1014 Token contentEnd;
1015 if (identical(_currentToken.type, TokenType.LT_SLASH)) {
1016 contentEnd = _currentToken;
1017 _currentToken = _currentToken.next;
1018 } else {
1019 reportUnexpectedToken();
1020 contentEnd = insertSyntheticToken(TokenType.LT_SLASH);
1021 }
1022 Token closingTag;
1023 if (identical(_currentToken.type, TokenType.TAG)) {
1024 closingTag = _currentToken;
1025 _currentToken = _currentToken.next;
1026 } else {
1027 reportUnexpectedToken();
1028 closingTag = insertSyntheticToken(TokenType.TAG);
1029 }
1030 Token nodeEnd;
1031 if (identical(_currentToken.type, TokenType.GT)) {
1032 nodeEnd = _currentToken;
1033 _currentToken = _currentToken.next;
1034 } else {
1035 reportUnexpectedToken();
1036 nodeEnd = insertSyntheticToken(TokenType.GT);
1037 }
1038 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co ntentEnd, closingTag, nodeEnd);
1039 }
1040 /**
1041 * Report the current token as unexpected
1042 */
1043 void reportUnexpectedToken() {
1044 }
1045 }
1046 /**
1047 * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}.
1048 * @coverage dart.engine.html
1049 */
1050 class XmlTagNode extends XmlNode {
1051 /**
1052 * Constant representing empty list of attributes.
1053 */
1054 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis t<XmlAttributeNode>());
1055 /**
1056 * Constant representing empty list of tag nodes.
1057 */
1058 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa gNode>());
1059 /**
1060 * The starting {@link TokenType#LT} token (not {@code null}).
1061 */
1062 Token _nodeStart;
1063 /**
1064 * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null} ).
1065 */
1066 Token _tag;
1067 /**
1068 * The attributes contained by the receiver (not {@code null}, contains no {@c ode null}s).
1069 */
1070 List<XmlAttributeNode> _attributes;
1071 /**
1072 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
1073 */
1074 Token _attributeEnd;
1075 /**
1076 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s).
1077 */
1078 List<XmlTagNode> _tagNodes;
1079 /**
1080 * The token (not {@code null}) after the content, which may be
1081 * <ul>
1082 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li>
1083 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
1084 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
1085 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in
1086 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no
1087 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
1088 * </ul>
1089 */
1090 Token _contentEnd;
1091 /**
1092 * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
1093 * content and the attributes ended with {@link TokenType#SLASH_GT}
1094 */
1095 Token _closingTag;
1096 /**
1097 * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@ code null}).
1098 */
1099 Token _nodeEnd;
1100 /**
1101 * Construct a new instance representing an XML or HTML element
1102 * @param nodeStart the starting {@link TokenType#LT} token (not {@code null})
1103 * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not { @code null}).
1104 * @param attributes the attributes associated with this element or {@link #NO _ATTRIBUTES} (not{@code null}, contains no {@code null}s)
1105 * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the
1106 * attributes (not {@code null}). The token may be the same token as {@link #n odeEnd} if
1107 * there are no child {@link #tagNodes}.
1108 * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (n ot {@code null},
1109 * contains no {@code null}s)
1110 * @param contentEnd the token (not {@code null}) after the content, which may be
1111 * <ul>
1112 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li>
1113 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is
1114 * self closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
1115 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last
1116 * node in the stream {@link TokenType#LT_SLASH} token after the content, or { @code null}if there is no content and the attributes ended with {@link TokenType #SLASH_GT}.</li>
1117 * </ul>
1118 * @param closingTag the closing {@link TokenType#TAG} after the child element s or {@code null} if
1119 * there is no content and the attributes ended with {@link TokenType#SLASH_GT }
1120 * @param nodeEnd the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT } token (not{@code null})
1121 */
1122 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T oken nodeEnd) {
1123 this._nodeStart = nodeStart;
1124 this._tag = tag;
1125 this._attributes = becomeParentOf(attributes);
1126 this._attributeEnd = attributeEnd;
1127 this._tagNodes = becomeParentOf(tagNodes);
1128 this._contentEnd = contentEnd;
1129 this._closingTag = closingTag;
1130 this._nodeEnd = nodeEnd;
1131 }
1132 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
1133 /**
1134 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
1135 * @return the token (not {@code null})
1136 */
1137 Token get attributeEnd => _attributeEnd;
1138 /**
1139 * Answer the receiver's attributes. Callers should not manipulate the returne d list to edit the
1140 * AST structure.
1141 * @return the attributes (not {@code null}, contains no {@code null}s)
1142 */
1143 List<XmlAttributeNode> get attributes => _attributes;
1144 Token get beginToken => _nodeStart;
1145 /**
1146 * The the closing {@link TokenType#TAG} after the child elements or {@code nu ll} if there is no
1147 * content and the attributes ended with {@link TokenType#SLASH_GT}
1148 * @return the closing tag or {@code null}
1149 */
1150 Token get closingTag => _closingTag;
1151 /**
1152 * Answer a string representing the content contained in the receiver. This in cludes the textual
1153 * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;',
1154 * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
1155 * @return the content (not {@code null})
1156 */
1157 String get content {
1158 Token token = _attributeEnd.next;
1159 if (identical(token, _contentEnd)) {
1160 return "";
1161 }
1162 String content = token.lexeme;
1163 token = token.next;
1164 if (identical(token, _contentEnd)) {
1165 return content;
1166 }
1167 JavaStringBuilder buffer = new JavaStringBuilder();
1168 while (token != _contentEnd) {
1169 buffer.append(token.lexeme);
1170 token = token.next;
1171 }
1172 return buffer.toString();
1173 }
1174 /**
1175 * Answer the token (not {@code null}) after the content, which may be
1176 * <ul>
1177 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li>
1178 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
1179 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
1180 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in
1181 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no
1182 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
1183 * </ul>
1184 * @return the token (not {@code null})
1185 */
1186 Token get contentEnd => _contentEnd;
1187 Token get endToken {
1188 if (_nodeEnd != null) {
1189 return _nodeEnd;
1190 }
1191 if (_closingTag != null) {
1192 return _closingTag;
1193 }
1194 if (_contentEnd != null) {
1195 return _contentEnd;
1196 }
1197 if (!_tagNodes.isEmpty) {
1198 return _tagNodes[_tagNodes.length - 1].endToken;
1199 }
1200 if (_attributeEnd != null) {
1201 return _attributeEnd;
1202 }
1203 if (!_attributes.isEmpty) {
1204 return _attributes[_attributes.length - 1].endToken;
1205 }
1206 return _tag;
1207 }
1208 /**
1209 * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token.
1210 * @return the token (not {@code null})
1211 */
1212 Token get nodeEnd => _nodeEnd;
1213 /**
1214 * Answer the starting {@link TokenType#LT} token.
1215 * @return the token (not {@code null})
1216 */
1217 Token get nodeStart => _nodeStart;
1218 /**
1219 * Answer the {@link TokenType#TAG} token after the starting '&lt;'.
1220 * @return the token (not {@code null})
1221 */
1222 Token get tag => _tag;
1223 /**
1224 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1225 * to edit the AST structure.
1226 * @return the children (not {@code null}, contains no {@code null}s)
1227 */
1228 List<XmlTagNode> get tagNodes => _tagNodes;
1229 void visitChildren(XmlVisitor<Object> visitor) {
1230 for (XmlAttributeNode node in _attributes) {
1231 node.accept(visitor);
1232 }
1233 for (XmlTagNode node in _tagNodes) {
1234 node.accept(visitor);
1235 }
1236 }
1237 }
1238 /**
1239 * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised
1240 * of {@link XmlNode}s.
1241 * @coverage dart.engine.html
1242 */
1243 class HtmlParser extends XmlParser {
1244 static Set<String> SELF_CLOSING = new Set<String>();
1245 /**
1246 * Construct a parser for the specified source.
1247 * @param source the source being parsed
1248 */
1249 HtmlParser(Source source) : super(source) {
1250 }
1251 /**
1252 * Parse the tokens specified by the given scan result.
1253 * @param scanResult the result of scanning an HTML source (not {@code null})
1254 * @return the parse result (not {@code null})
1255 */
1256 HtmlParseResult parse(HtmlScanResult scanResult) {
1257 Token firstToken = scanResult.token;
1258 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
1259 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
1260 return new HtmlParseResult(firstToken, scanResult.lineStarts, unit);
1261 }
1262 /**
1263 * Scan then parse the specified source.
1264 * @param source the source to be scanned and parsed (not {@code null})
1265 * @return the parse result (not {@code null})
1266 */
1267 HtmlParseResult parse2(Source source) {
1268 HtmlScanner scanner = new HtmlScanner(source);
1269 source.getContents(scanner);
1270 return parse(scanner.result);
1271 }
1272 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
1273 }
1274 /**
1275 * Instances of the class {@code HtmlUnit} represent the contents of an HTML fil e.
1276 * @coverage dart.engine.html
1277 */
1278 class HtmlUnit extends XmlNode {
1279 /**
1280 * The first token in the token stream that was parsed to form this HTML unit.
1281 */
1282 Token _beginToken;
1283 /**
1284 * The last token in the token stream that was parsed to form this compilation unit. This token
1285 * should always have a type of {@link TokenType.EOF}.
1286 */
1287 Token _endToken;
1288 /**
1289 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s).
1290 */
1291 List<XmlTagNode> _tagNodes;
1292 /**
1293 * The element associated with this HTML unit or {@code null} if the receiver is not resolved.
1294 */
1295 HtmlElementImpl _element;
1296 /**
1297 * Construct a new instance representing the content of an HTML file.
1298 * @param beginToken the first token in the file (not {@code null})
1299 * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s)
1300 * @param endToken the last token in the token stream which should be of type{ @link TokenType.EOF}
1301 */
1302 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
1303 this._beginToken = beginToken;
1304 this._tagNodes = becomeParentOf(tagNodes);
1305 this._endToken = endToken;
1306 }
1307 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
1308 Token get beginToken => _beginToken;
1309 /**
1310 * Return the element associated with this HTML unit.
1311 * @return the element or {@code null} if the receiver is not resolved
1312 */
1313 HtmlElementImpl get element => _element;
1314 Token get endToken => _endToken;
1315 /**
1316 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1317 * to edit the AST structure.
1318 * @return the children (not {@code null}, contains no {@code null}s)
1319 */
1320 List<XmlTagNode> get tagNodes => _tagNodes;
1321 /**
1322 * Set the element associated with this HTML unit.
1323 * @param element the element
1324 */
1325 void set element(HtmlElementImpl element18) {
1326 this._element = element18;
1327 }
1328 void visitChildren(XmlVisitor<Object> visitor) {
1329 for (XmlTagNode node in _tagNodes) {
1330 node.accept(visitor);
1331 }
1332 }
1333 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698