| OLD | NEW |
| 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 |
| 3 library engine.html; | 4 library engine.html; |
| 5 |
| 4 import 'dart:collection'; | 6 import 'dart:collection'; |
| 5 import 'java_core.dart'; | 7 import 'java_core.dart'; |
| 6 import 'java_engine.dart'; | 8 import 'java_engine.dart'; |
| 7 import 'source.dart'; | 9 import 'source.dart'; |
| 8 import 'element.dart' show HtmlElementImpl; | 10 import 'element.dart' show HtmlElementImpl; |
| 9 import 'engine.dart' show AnalysisEngine; | 11 import 'engine.dart' show AnalysisEngine; |
| 12 |
| 10 /** | 13 /** |
| 11 * Instances of the class `Token` represent a token that was scanned from the in
put. Each | 14 * Instances of the class `Token` represent a token that was scanned from the in
put. Each |
| 12 * token knows which token follows it, acting as the head of a linked list of to
kens. | 15 * token knows which token follows it, acting as the head of a linked list of to
kens. |
| 13 * | 16 * |
| 14 * @coverage dart.engine.html | 17 * @coverage dart.engine.html |
| 15 */ | 18 */ |
| 16 class Token { | 19 class Token { |
| 17 | |
| 18 /** | 20 /** |
| 19 * 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. |
| 20 */ | 22 */ |
| 21 int offset = 0; | 23 int offset = 0; |
| 22 | 24 |
| 23 /** | 25 /** |
| 24 * The previous token in the token stream. | 26 * The previous token in the token stream. |
| 25 */ | 27 */ |
| 26 Token previous; | 28 Token previous; |
| 27 | 29 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 * this token to be the previous token for the given token. | 93 * this token to be the previous token for the given token. |
| 92 * | 94 * |
| 93 * @param token the next token in the token stream | 95 * @param token the next token in the token stream |
| 94 * @return the token that was passed in | 96 * @return the token that was passed in |
| 95 */ | 97 */ |
| 96 Token setNext(Token token) { | 98 Token setNext(Token token) { |
| 97 next = token; | 99 next = token; |
| 98 token.previous = this; | 100 token.previous = this; |
| 99 return token; | 101 return token; |
| 100 } | 102 } |
| 103 |
| 101 String toString() => lexeme; | 104 String toString() => lexeme; |
| 102 } | 105 } |
| 106 |
| 103 /** | 107 /** |
| 104 * Instances of `HtmlParseResult` hold the result of parsing an HTML file. | 108 * Instances of `HtmlParseResult` hold the result of parsing an HTML file. |
| 105 * | 109 * |
| 106 * @coverage dart.engine.html | 110 * @coverage dart.engine.html |
| 107 */ | 111 */ |
| 108 class HtmlParseResult extends HtmlScanResult { | 112 class HtmlParseResult extends HtmlScanResult { |
| 109 | |
| 110 /** | 113 /** |
| 111 * The unit containing the parsed information (not `null`). | 114 * The unit containing the parsed information (not `null`). |
| 112 */ | 115 */ |
| 113 HtmlUnit htmlUnit; | 116 HtmlUnit htmlUnit; |
| 117 |
| 114 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU
nit unit) : super(modificationTime, token, lineStarts) { | 118 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU
nit unit) : super(modificationTime, token, lineStarts) { |
| 115 this.htmlUnit = unit; | 119 this.htmlUnit = unit; |
| 116 } | 120 } |
| 117 } | 121 } |
| 122 |
| 118 /** | 123 /** |
| 119 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively | 124 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively |
| 120 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit | 125 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit |
| 121 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and | 126 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and |
| 122 * [XmlTagNode]s to be visited. | 127 * [XmlTagNode]s to be visited. |
| 123 * | 128 * |
| 124 * Subclasses that override a visit method must either invoke the overridden vis
it method or must | 129 * Subclasses that override a visit method must either invoke the overridden vis
it method or must |
| 125 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children | 130 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children |
| 126 * of the visited node to not be visited. | 131 * of the visited node to not be visited. |
| 127 * | 132 * |
| 128 * @coverage dart.engine.html | 133 * @coverage dart.engine.html |
| 129 */ | 134 */ |
| 130 class RecursiveXmlVisitor<R> implements XmlVisitor<R> { | 135 class RecursiveXmlVisitor<R> implements XmlVisitor<R> { |
| 131 R visitHtmlUnit(HtmlUnit node) { | 136 R visitHtmlUnit(HtmlUnit node) { |
| 132 node.visitChildren(this); | 137 node.visitChildren(this); |
| 133 return null; | 138 return null; |
| 134 } | 139 } |
| 140 |
| 135 R visitXmlAttributeNode(XmlAttributeNode node) { | 141 R visitXmlAttributeNode(XmlAttributeNode node) { |
| 136 node.visitChildren(this); | 142 node.visitChildren(this); |
| 137 return null; | 143 return null; |
| 138 } | 144 } |
| 145 |
| 139 R visitXmlTagNode(XmlTagNode node) { | 146 R visitXmlTagNode(XmlTagNode node) { |
| 140 node.visitChildren(this); | 147 node.visitChildren(this); |
| 141 return null; | 148 return null; |
| 142 } | 149 } |
| 143 } | 150 } |
| 151 |
| 144 /** | 152 /** |
| 145 * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes. | 153 * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes. |
| 146 * | 154 * |
| 147 * @coverage dart.engine.html | 155 * @coverage dart.engine.html |
| 148 */ | 156 */ |
| 149 abstract class XmlNode { | 157 abstract class XmlNode { |
| 150 | |
| 151 /** | 158 /** |
| 152 * The parent of the node, or `null` if the node is the root of an AST structu
re. | 159 * The parent of the node, or `null` if the node is the root of an AST structu
re. |
| 153 */ | 160 */ |
| 154 XmlNode _parent; | 161 XmlNode _parent; |
| 155 | 162 |
| 156 /** | 163 /** |
| 157 * Use the given visitor to visit this node. | 164 * Use the given visitor to visit this node. |
| 158 * | 165 * |
| 159 * @param visitor the visitor that will visit this node | 166 * @param visitor the visitor that will visit this node |
| 160 * @return the value returned by the visitor as a result of visiting this node | 167 * @return the value returned by the visitor as a result of visiting this node |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 222 |
| 216 /** | 223 /** |
| 217 * Return this node's parent node, or `null` if this node is the root of an AS
T structure. | 224 * Return this node's parent node, or `null` if this node is the root of an AS
T structure. |
| 218 * | 225 * |
| 219 * Note that the relationship between an AST node and its parent node may chan
ge over the lifetime | 226 * Note that the relationship between an AST node and its parent node may chan
ge over the lifetime |
| 220 * of a node. | 227 * of a node. |
| 221 * | 228 * |
| 222 * @return the parent of this node, or `null` if none | 229 * @return the parent of this node, or `null` if none |
| 223 */ | 230 */ |
| 224 XmlNode get parent => _parent; | 231 XmlNode get parent => _parent; |
| 232 |
| 225 String toString() { | 233 String toString() { |
| 226 PrintStringWriter writer = new PrintStringWriter(); | 234 PrintStringWriter writer = new PrintStringWriter(); |
| 227 accept(new ToSourceVisitor(writer)); | 235 accept(new ToSourceVisitor(writer)); |
| 228 return writer.toString(); | 236 return writer.toString(); |
| 229 } | 237 } |
| 230 | 238 |
| 231 /** | 239 /** |
| 232 * Use the given visitor to visit all of the children of this node. The childr
en will be visited | 240 * Use the given visitor to visit all of the children of this node. The childr
en will be visited |
| 233 * in source order. | 241 * in source order. |
| 234 * | 242 * |
| (...skipping 30 matching lines...) Expand all Loading... |
| 265 node.parent = this; | 273 node.parent = this; |
| 266 } | 274 } |
| 267 return child; | 275 return child; |
| 268 } | 276 } |
| 269 | 277 |
| 270 /** | 278 /** |
| 271 * This method exists for debugging purposes only. | 279 * This method exists for debugging purposes only. |
| 272 */ | 280 */ |
| 273 void appendIdentifier(JavaStringBuilder builder, XmlNode node) { | 281 void appendIdentifier(JavaStringBuilder builder, XmlNode node) { |
| 274 if (node is XmlTagNode) { | 282 if (node is XmlTagNode) { |
| 275 builder.append(((node as XmlTagNode)).tag.lexeme); | 283 builder.append((node as XmlTagNode).tag.lexeme); |
| 276 } else if (node is XmlAttributeNode) { | 284 } else if (node is XmlAttributeNode) { |
| 277 builder.append(((node as XmlAttributeNode)).name.lexeme); | 285 builder.append((node as XmlAttributeNode).name.lexeme); |
| 278 } else { | 286 } else { |
| 279 builder.append("htmlUnit"); | 287 builder.append("htmlUnit"); |
| 280 } | 288 } |
| 281 } | 289 } |
| 282 | 290 |
| 283 /** | 291 /** |
| 284 * This method exists for debugging purposes only. | 292 * This method exists for debugging purposes only. |
| 285 */ | 293 */ |
| 286 String buildRecursiveStructureMessage(XmlNode newParent) { | 294 String buildRecursiveStructureMessage(XmlNode newParent) { |
| 287 JavaStringBuilder builder = new JavaStringBuilder(); | 295 JavaStringBuilder builder = new JavaStringBuilder(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 313 while (current != null) { | 321 while (current != null) { |
| 314 if (identical(current, this)) { | 322 if (identical(current, this)) { |
| 315 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu
ildRecursiveStructureMessage(newParent))); | 323 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu
ildRecursiveStructureMessage(newParent))); |
| 316 return; | 324 return; |
| 317 } | 325 } |
| 318 current = current.parent; | 326 current = current.parent; |
| 319 } | 327 } |
| 320 _parent = newParent; | 328 _parent = newParent; |
| 321 } | 329 } |
| 322 } | 330 } |
| 331 |
| 323 /** | 332 /** |
| 324 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will
do nothing | 333 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will
do nothing |
| 325 * when visiting an AST node. It is intended to be a superclass for classes that
use the visitor | 334 * when visiting an AST node. It is intended to be a superclass for classes that
use the visitor |
| 326 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel
y visit a whole | 335 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel
y visit a whole |
| 327 * structure) and that only need to visit a small number of node types. | 336 * structure) and that only need to visit a small number of node types. |
| 328 */ | 337 */ |
| 329 class SimpleXmlVisitor<R> implements XmlVisitor<R> { | 338 class SimpleXmlVisitor<R> implements XmlVisitor<R> { |
| 330 R visitHtmlUnit(HtmlUnit htmlUnit) => null; | 339 R visitHtmlUnit(HtmlUnit htmlUnit) => null; |
| 340 |
| 331 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null; | 341 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null; |
| 342 |
| 332 R visitXmlTagNode(XmlTagNode xmlTagNode) => null; | 343 R visitXmlTagNode(XmlTagNode xmlTagNode) => null; |
| 333 } | 344 } |
| 345 |
| 334 /** | 346 /** |
| 335 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc
lasses are | 347 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc
lasses are |
| 336 * required to implement the interface used to access the characters being scann
ed. | 348 * required to implement the interface used to access the characters being scann
ed. |
| 337 * | 349 * |
| 338 * @coverage dart.engine.html | 350 * @coverage dart.engine.html |
| 339 */ | 351 */ |
| 340 abstract class AbstractScanner { | 352 abstract class AbstractScanner { |
| 341 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; | 353 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; |
| 342 | 354 |
| 343 /** | 355 /** |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 * @return the character at the current position | 449 * @return the character at the current position |
| 438 */ | 450 */ |
| 439 int peek(); | 451 int peek(); |
| 440 | 452 |
| 441 /** | 453 /** |
| 442 * Record the fact that we are at the beginning of a new line in the source. | 454 * Record the fact that we are at the beginning of a new line in the source. |
| 443 */ | 455 */ |
| 444 void recordStartOfLine() { | 456 void recordStartOfLine() { |
| 445 _lineStarts.add(offset); | 457 _lineStarts.add(offset); |
| 446 } | 458 } |
| 459 |
| 447 void appendEofToken() { | 460 void appendEofToken() { |
| 448 Token eofToken = new Token.con1(TokenType.EOF, offset); | 461 Token eofToken = new Token.con1(TokenType.EOF, offset); |
| 449 eofToken.setNext(eofToken); | 462 eofToken.setNext(eofToken); |
| 450 _tail = _tail.setNext(eofToken); | 463 _tail = _tail.setNext(eofToken); |
| 451 } | 464 } |
| 465 |
| 452 Token emit(Token token) { | 466 Token emit(Token token) { |
| 453 _tail.setNext(token); | 467 _tail.setNext(token); |
| 454 _tail = token; | 468 _tail = token; |
| 455 return token; | 469 return token; |
| 456 } | 470 } |
| 471 |
| 457 Token emit2(TokenType type, int start) => emit(new Token.con1(type, start)); | 472 Token emit2(TokenType type, int start) => emit(new Token.con1(type, start)); |
| 473 |
| 458 Token emit3(TokenType type, int start, int count) => emit(new Token.con2(type,
start, getString(start, count))); | 474 Token emit3(TokenType type, int start, int count) => emit(new Token.con2(type,
start, getString(start, count))); |
| 475 |
| 459 Token firstToken() => _tokens.next; | 476 Token firstToken() => _tokens.next; |
| 477 |
| 460 int recordStartOfLineAndAdvance(int c) { | 478 int recordStartOfLineAndAdvance(int c) { |
| 461 if (c == 0xD) { | 479 if (c == 0xD) { |
| 462 c = advance(); | 480 c = advance(); |
| 463 if (c == 0xA) { | 481 if (c == 0xA) { |
| 464 c = advance(); | 482 c = advance(); |
| 465 } | 483 } |
| 466 recordStartOfLine(); | 484 recordStartOfLine(); |
| 467 } else if (c == 0xA) { | 485 } else if (c == 0xA) { |
| 468 c = advance(); | 486 c = advance(); |
| 469 recordStartOfLine(); | 487 recordStartOfLine(); |
| 470 } else { | 488 } else { |
| 471 c = advance(); | 489 c = advance(); |
| 472 } | 490 } |
| 473 return c; | 491 return c; |
| 474 } | 492 } |
| 493 |
| 475 void scan() { | 494 void scan() { |
| 476 bool inBrackets = false; | 495 bool inBrackets = false; |
| 477 String endPassThrough = null; | 496 String endPassThrough = null; |
| 478 int c = advance(); | 497 int c = advance(); |
| 479 while (c >= 0) { | 498 while (c >= 0) { |
| 480 int start = offset; | 499 int start = offset; |
| 481 if (c == 0x3C) { | 500 if (c == 0x3C) { |
| 482 c = advance(); | 501 c = advance(); |
| 483 if (c == 0x21) { | 502 if (c == 0x21) { |
| 484 c = advance(); | 503 c = advance(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 c = advance(); | 644 c = advance(); |
| 626 } | 645 } |
| 627 emit3(TokenType.TAG, start, -1); | 646 emit3(TokenType.TAG, start, -1); |
| 628 } else { | 647 } else { |
| 629 emit3(TokenType.TEXT, start, 0); | 648 emit3(TokenType.TEXT, start, 0); |
| 630 c = advance(); | 649 c = advance(); |
| 631 } | 650 } |
| 632 } | 651 } |
| 633 } | 652 } |
| 634 } | 653 } |
| 654 |
| 635 /** | 655 /** |
| 636 * Instances of `HtmlScanResult` hold the result of scanning an HTML file. | 656 * Instances of `HtmlScanResult` hold the result of scanning an HTML file. |
| 637 * | 657 * |
| 638 * @coverage dart.engine.html | 658 * @coverage dart.engine.html |
| 639 */ | 659 */ |
| 640 class HtmlScanResult { | 660 class HtmlScanResult { |
| 641 | |
| 642 /** | 661 /** |
| 643 * The time at which the contents of the source were last set. | 662 * The time at which the contents of the source were last set. |
| 644 */ | 663 */ |
| 645 int modificationTime = 0; | 664 int modificationTime = 0; |
| 646 | 665 |
| 647 /** | 666 /** |
| 648 * The first token in the token stream (not `null`). | 667 * The first token in the token stream (not `null`). |
| 649 */ | 668 */ |
| 650 Token token; | 669 Token token; |
| 651 | 670 |
| 652 /** | 671 /** |
| 653 * The line start information that was produced. | 672 * The line start information that was produced. |
| 654 */ | 673 */ |
| 655 List<int> lineStarts; | 674 List<int> lineStarts; |
| 675 |
| 656 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { | 676 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { |
| 657 this.modificationTime = modificationTime; | 677 this.modificationTime = modificationTime; |
| 658 this.token = token; | 678 this.token = token; |
| 659 this.lineStarts = lineStarts; | 679 this.lineStarts = lineStarts; |
| 660 } | 680 } |
| 661 } | 681 } |
| 682 |
| 662 /** | 683 /** |
| 663 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The | 684 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The |
| 664 * scanning logic is in the superclass. | 685 * scanning logic is in the superclass. |
| 665 * | 686 * |
| 666 * @coverage dart.engine.html | 687 * @coverage dart.engine.html |
| 667 */ | 688 */ |
| 668 class StringScanner extends AbstractScanner { | 689 class StringScanner extends AbstractScanner { |
| 669 | |
| 670 /** | 690 /** |
| 671 * The string from which characters will be read. | 691 * The string from which characters will be read. |
| 672 */ | 692 */ |
| 673 String _string; | 693 String _string; |
| 674 | 694 |
| 675 /** | 695 /** |
| 676 * The number of characters in the string. | 696 * The number of characters in the string. |
| 677 */ | 697 */ |
| 678 int _stringLength = 0; | 698 int _stringLength = 0; |
| 679 | 699 |
| 680 /** | 700 /** |
| 681 * The index, relative to the string, of the last character that was read. | 701 * The index, relative to the string, of the last character that was read. |
| 682 */ | 702 */ |
| 683 int _charOffset = 0; | 703 int _charOffset = 0; |
| 684 | 704 |
| 685 /** | 705 /** |
| 686 * Initialize a newly created scanner to scan the characters in the given stri
ng. | 706 * Initialize a newly created scanner to scan the characters in the given stri
ng. |
| 687 * | 707 * |
| 688 * @param source the source being scanned | 708 * @param source the source being scanned |
| 689 * @param string the string from which characters will be read | 709 * @param string the string from which characters will be read |
| 690 */ | 710 */ |
| 691 StringScanner(Source source, String string) : super(source) { | 711 StringScanner(Source source, String string) : super(source) { |
| 692 this._string = string; | 712 this._string = string; |
| 693 this._stringLength = string.length; | 713 this._stringLength = string.length; |
| 694 this._charOffset = -1; | 714 this._charOffset = -1; |
| 695 } | 715 } |
| 716 |
| 696 int get offset => _charOffset; | 717 int get offset => _charOffset; |
| 718 |
| 697 void set offset(int offset) { | 719 void set offset(int offset) { |
| 698 _charOffset = offset; | 720 _charOffset = offset; |
| 699 } | 721 } |
| 722 |
| 700 int advance() { | 723 int advance() { |
| 701 if (++_charOffset < _stringLength) { | 724 if (++_charOffset < _stringLength) { |
| 702 return _string.codeUnitAt(_charOffset); | 725 return _string.codeUnitAt(_charOffset); |
| 703 } | 726 } |
| 704 _charOffset = _stringLength; | 727 _charOffset = _stringLength; |
| 705 return -1; | 728 return -1; |
| 706 } | 729 } |
| 730 |
| 707 String getString(int start, int endDelta) => _string.substring(start, _charOff
set + 1 + endDelta); | 731 String getString(int start, int endDelta) => _string.substring(start, _charOff
set + 1 + endDelta); |
| 732 |
| 708 int peek() { | 733 int peek() { |
| 709 if (_charOffset + 1 < _stringLength) { | 734 if (_charOffset + 1 < _stringLength) { |
| 710 return _string.codeUnitAt(_charOffset + 1); | 735 return _string.codeUnitAt(_charOffset + 1); |
| 711 } | 736 } |
| 712 return -1; | 737 return -1; |
| 713 } | 738 } |
| 714 } | 739 } |
| 740 |
| 715 /** | 741 /** |
| 716 * Instances of the class `CharBufferScanner` implement a scanner that reads fro
m a character | 742 * Instances of the class `CharBufferScanner` implement a scanner that reads fro
m a character |
| 717 * buffer. The scanning logic is in the superclass. | 743 * buffer. The scanning logic is in the superclass. |
| 718 * | 744 * |
| 719 * @coverage dart.engine.html | 745 * @coverage dart.engine.html |
| 720 */ | 746 */ |
| 721 class CharBufferScanner extends AbstractScanner { | 747 class CharBufferScanner extends AbstractScanner { |
| 722 | |
| 723 /** | 748 /** |
| 724 * The buffer from which characters will be read. | 749 * The buffer from which characters will be read. |
| 725 */ | 750 */ |
| 726 CharSequence _buffer; | 751 CharSequence _buffer; |
| 727 | 752 |
| 728 /** | 753 /** |
| 729 * The number of characters in the buffer. | 754 * The number of characters in the buffer. |
| 730 */ | 755 */ |
| 731 int _bufferLength = 0; | 756 int _bufferLength = 0; |
| 732 | 757 |
| 733 /** | 758 /** |
| 734 * The index of the last character that was read. | 759 * The index of the last character that was read. |
| 735 */ | 760 */ |
| 736 int _charOffset = 0; | 761 int _charOffset = 0; |
| 737 | 762 |
| 738 /** | 763 /** |
| 739 * Initialize a newly created scanner to scan the characters in the given char
acter buffer. | 764 * Initialize a newly created scanner to scan the characters in the given char
acter buffer. |
| 740 * | 765 * |
| 741 * @param source the source being scanned | 766 * @param source the source being scanned |
| 742 * @param buffer the buffer from which characters will be read | 767 * @param buffer the buffer from which characters will be read |
| 743 */ | 768 */ |
| 744 CharBufferScanner(Source source, CharSequence buffer) : super(source) { | 769 CharBufferScanner(Source source, CharSequence buffer) : super(source) { |
| 745 this._buffer = buffer; | 770 this._buffer = buffer; |
| 746 this._bufferLength = buffer.length(); | 771 this._bufferLength = buffer.length(); |
| 747 this._charOffset = -1; | 772 this._charOffset = -1; |
| 748 } | 773 } |
| 774 |
| 749 int get offset => _charOffset; | 775 int get offset => _charOffset; |
| 776 |
| 750 int advance() { | 777 int advance() { |
| 751 if (++_charOffset < _bufferLength) { | 778 if (++_charOffset < _bufferLength) { |
| 752 return _buffer.charAt(_charOffset); | 779 return _buffer.charAt(_charOffset); |
| 753 } | 780 } |
| 754 _charOffset = _bufferLength; | 781 _charOffset = _bufferLength; |
| 755 return -1; | 782 return -1; |
| 756 } | 783 } |
| 784 |
| 757 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO
ffset + 1 + endDelta).toString(); | 785 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO
ffset + 1 + endDelta).toString(); |
| 786 |
| 758 int peek() { | 787 int peek() { |
| 759 if (_charOffset + 1 < _bufferLength) { | 788 if (_charOffset + 1 < _bufferLength) { |
| 760 return _buffer.charAt(_charOffset + 1); | 789 return _buffer.charAt(_charOffset + 1); |
| 761 } | 790 } |
| 762 return -1; | 791 return -1; |
| 763 } | 792 } |
| 764 } | 793 } |
| 794 |
| 765 /** | 795 /** |
| 766 * Instances of the class `ToSourceVisitor` write a source representation of a v
isited XML | 796 * Instances of the class `ToSourceVisitor` write a source representation of a v
isited XML |
| 767 * node (and all of it's children) to a writer. | 797 * node (and all of it's children) to a writer. |
| 768 * | 798 * |
| 769 * @coverage dart.engine.html | 799 * @coverage dart.engine.html |
| 770 */ | 800 */ |
| 771 class ToSourceVisitor implements XmlVisitor<Object> { | 801 class ToSourceVisitor implements XmlVisitor<Object> { |
| 772 | |
| 773 /** | 802 /** |
| 774 * The writer to which the source is to be written. | 803 * The writer to which the source is to be written. |
| 775 */ | 804 */ |
| 776 PrintWriter _writer; | 805 PrintWriter _writer; |
| 777 | 806 |
| 778 /** | 807 /** |
| 779 * Initialize a newly created visitor to write source code representing the vi
sited nodes to the | 808 * Initialize a newly created visitor to write source code representing the vi
sited nodes to the |
| 780 * given writer. | 809 * given writer. |
| 781 * | 810 * |
| 782 * @param writer the writer to which the source is to be written | 811 * @param writer the writer to which the source is to be written |
| 783 */ | 812 */ |
| 784 ToSourceVisitor(PrintWriter writer) { | 813 ToSourceVisitor(PrintWriter writer) { |
| 785 this._writer = writer; | 814 this._writer = writer; |
| 786 } | 815 } |
| 816 |
| 787 Object visitHtmlUnit(HtmlUnit node) { | 817 Object visitHtmlUnit(HtmlUnit node) { |
| 788 for (XmlTagNode child in node.tagNodes) { | 818 for (XmlTagNode child in node.tagNodes) { |
| 789 visit(child); | 819 visit(child); |
| 790 } | 820 } |
| 791 return null; | 821 return null; |
| 792 } | 822 } |
| 823 |
| 793 Object visitXmlAttributeNode(XmlAttributeNode node) { | 824 Object visitXmlAttributeNode(XmlAttributeNode node) { |
| 794 String name = node.name.lexeme; | 825 String name = node.name.lexeme; |
| 795 Token value = node.value; | 826 Token value = node.value; |
| 796 if (name.length == 0) { | 827 if (name.length == 0) { |
| 797 _writer.print("__"); | 828 _writer.print("__"); |
| 798 } else { | 829 } else { |
| 799 _writer.print(name); | 830 _writer.print(name); |
| 800 } | 831 } |
| 801 _writer.print("="); | 832 _writer.print("="); |
| 802 if (value == null) { | 833 if (value == null) { |
| 803 _writer.print("__"); | 834 _writer.print("__"); |
| 804 } else { | 835 } else { |
| 805 _writer.print(value.lexeme); | 836 _writer.print(value.lexeme); |
| 806 } | 837 } |
| 807 return null; | 838 return null; |
| 808 } | 839 } |
| 840 |
| 809 Object visitXmlTagNode(XmlTagNode node) { | 841 Object visitXmlTagNode(XmlTagNode node) { |
| 810 _writer.print("<"); | 842 _writer.print("<"); |
| 811 String tagName = node.tag.lexeme; | 843 String tagName = node.tag.lexeme; |
| 812 _writer.print(tagName); | 844 _writer.print(tagName); |
| 813 for (XmlAttributeNode attribute in node.attributes) { | 845 for (XmlAttributeNode attribute in node.attributes) { |
| 814 _writer.print(" "); | 846 _writer.print(" "); |
| 815 visit(attribute); | 847 visit(attribute); |
| 816 } | 848 } |
| 817 _writer.print(node.attributeEnd.lexeme); | 849 _writer.print(node.attributeEnd.lexeme); |
| 818 if (node.closingTag != null) { | 850 if (node.closingTag != null) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 830 * Safely visit the given node. | 862 * Safely visit the given node. |
| 831 * | 863 * |
| 832 * @param node the node to be visited | 864 * @param node the node to be visited |
| 833 */ | 865 */ |
| 834 void visit(XmlNode node) { | 866 void visit(XmlNode node) { |
| 835 if (node != null) { | 867 if (node != null) { |
| 836 node.accept(this); | 868 node.accept(this); |
| 837 } | 869 } |
| 838 } | 870 } |
| 839 } | 871 } |
| 872 |
| 840 /** | 873 /** |
| 841 * The enumeration `TokenType` defines the types of tokens that can be returned
by the | 874 * The enumeration `TokenType` defines the types of tokens that can be returned
by the |
| 842 * scanner. | 875 * scanner. |
| 843 * | 876 * |
| 844 * @coverage dart.engine.html | 877 * @coverage dart.engine.html |
| 845 */ | 878 */ |
| 846 class TokenType extends Enum<TokenType> { | 879 class TokenType extends Enum<TokenType> { |
| 847 | |
| 848 /** | 880 /** |
| 849 * The type of the token that marks the end of the input. | 881 * The type of the token that marks the end of the input. |
| 850 */ | 882 */ |
| 851 static final TokenType EOF = new TokenType_EOF('EOF', 0, ""); | 883 static final TokenType EOF = new TokenType_EOF('EOF', 0, ""); |
| 884 |
| 852 static final TokenType EQ = new TokenType('EQ', 1, "="); | 885 static final TokenType EQ = new TokenType('EQ', 1, "="); |
| 886 |
| 853 static final TokenType GT = new TokenType('GT', 2, ">"); | 887 static final TokenType GT = new TokenType('GT', 2, ">"); |
| 888 |
| 854 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</"); | 889 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</"); |
| 890 |
| 855 static final TokenType LT = new TokenType('LT', 4, "<"); | 891 static final TokenType LT = new TokenType('LT', 4, "<"); |
| 892 |
| 856 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>"); | 893 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>"); |
| 894 |
| 857 static final TokenType COMMENT = new TokenType('COMMENT', 6, null); | 895 static final TokenType COMMENT = new TokenType('COMMENT', 6, null); |
| 896 |
| 858 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null); | 897 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null); |
| 898 |
| 859 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null); | 899 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null); |
| 900 |
| 860 static final TokenType STRING = new TokenType('STRING', 9, null); | 901 static final TokenType STRING = new TokenType('STRING', 9, null); |
| 902 |
| 861 static final TokenType TAG = new TokenType('TAG', 10, null); | 903 static final TokenType TAG = new TokenType('TAG', 10, null); |
| 904 |
| 862 static final TokenType TEXT = new TokenType('TEXT', 11, null); | 905 static final TokenType TEXT = new TokenType('TEXT', 11, null); |
| 906 |
| 863 static final List<TokenType> values = [ | 907 static final List<TokenType> values = [ |
| 864 EOF, | 908 EOF, |
| 865 EQ, | 909 EQ, |
| 866 GT, | 910 GT, |
| 867 LT_SLASH, | 911 LT_SLASH, |
| 868 LT, | 912 LT, |
| 869 SLASH_GT, | 913 SLASH_GT, |
| 870 COMMENT, | 914 COMMENT, |
| 871 DECLARATION, | 915 DECLARATION, |
| 872 DIRECTIVE, | 916 DIRECTIVE, |
| 873 STRING, | 917 STRING, |
| 874 TAG, | 918 TAG, |
| 875 TEXT]; | 919 TEXT]; |
| 876 | 920 |
| 877 /** | 921 /** |
| 878 * The lexeme that defines this type of token, or `null` if there is more than
one possible | 922 * The lexeme that defines this type of token, or `null` if there is more than
one possible |
| 879 * lexeme for this type of token. | 923 * lexeme for this type of token. |
| 880 */ | 924 */ |
| 881 String lexeme; | 925 String lexeme; |
| 926 |
| 882 TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) { | 927 TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) { |
| 883 this.lexeme = lexeme; | 928 this.lexeme = lexeme; |
| 884 } | 929 } |
| 885 } | 930 } |
| 931 |
| 886 class TokenType_EOF extends TokenType { | 932 class TokenType_EOF extends TokenType { |
| 887 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar
g0); | 933 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar
g0); |
| 934 |
| 888 String toString() => "-eof-"; | 935 String toString() => "-eof-"; |
| 889 } | 936 } |
| 937 |
| 890 /** | 938 /** |
| 891 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. | 939 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. |
| 892 * | 940 * |
| 893 * @coverage dart.engine.html | 941 * @coverage dart.engine.html |
| 894 */ | 942 */ |
| 895 class XmlAttributeNode extends XmlNode { | 943 class XmlAttributeNode extends XmlNode { |
| 896 Token name; | 944 Token name; |
| 945 |
| 897 Token equals; | 946 Token equals; |
| 947 |
| 898 Token value; | 948 Token value; |
| 899 | 949 |
| 900 /** | 950 /** |
| 901 * Construct a new instance representing an XML attribute. | 951 * Construct a new instance representing an XML attribute. |
| 902 * | 952 * |
| 903 * @param name the name token (not `null`). This may be a zero length token if
the attribute | 953 * @param name the name token (not `null`). This may be a zero length token if
the attribute |
| 904 * is badly formed. | 954 * is badly formed. |
| 905 * @param equals the equals sign or `null` if none | 955 * @param equals the equals sign or `null` if none |
| 906 * @param value the value token (not `null`) | 956 * @param value the value token (not `null`) |
| 907 */ | 957 */ |
| 908 XmlAttributeNode(Token name, Token equals, Token value) { | 958 XmlAttributeNode(Token name, Token equals, Token value) { |
| 909 this.name = name; | 959 this.name = name; |
| 910 this.equals = equals; | 960 this.equals = equals; |
| 911 this.value = value; | 961 this.value = value; |
| 912 } | 962 } |
| 963 |
| 913 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); | 964 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); |
| 965 |
| 914 Token get beginToken => name; | 966 Token get beginToken => name; |
| 967 |
| 915 Token get endToken => value; | 968 Token get endToken => value; |
| 916 | 969 |
| 917 /** | 970 /** |
| 918 * Answer the lexeme for the value token without the leading and trailing quot
es. | 971 * Answer the lexeme for the value token without the leading and trailing quot
es. |
| 919 * | 972 * |
| 920 * @return the text or `null` if the value is not specified | 973 * @return the text or `null` if the value is not specified |
| 921 */ | 974 */ |
| 922 String get text { | 975 String get text { |
| 923 if (value == null) { | 976 if (value == null) { |
| 924 return null; | 977 return null; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 935 } else if (text.codeUnitAt(0) == 0x27) { | 988 } else if (text.codeUnitAt(0) == 0x27) { |
| 936 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { | 989 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { |
| 937 return text.substring(1, len - 1); | 990 return text.substring(1, len - 1); |
| 938 } else { | 991 } else { |
| 939 return text.substring(1); | 992 return text.substring(1); |
| 940 } | 993 } |
| 941 } | 994 } |
| 942 } | 995 } |
| 943 return text; | 996 return text; |
| 944 } | 997 } |
| 998 |
| 945 void visitChildren(XmlVisitor visitor) { | 999 void visitChildren(XmlVisitor visitor) { |
| 946 } | 1000 } |
| 947 } | 1001 } |
| 1002 |
| 948 /** | 1003 /** |
| 949 * The interface `XmlVisitor` defines the behavior of objects that can be used t
o visit an | 1004 * The interface `XmlVisitor` defines the behavior of objects that can be used t
o visit an |
| 950 * [XmlNode] structure. | 1005 * [XmlNode] structure. |
| 951 * | 1006 * |
| 952 * @coverage dart.engine.html | 1007 * @coverage dart.engine.html |
| 953 */ | 1008 */ |
| 954 abstract class XmlVisitor<R> { | 1009 abstract class XmlVisitor<R> { |
| 955 R visitHtmlUnit(HtmlUnit htmlUnit); | 1010 R visitHtmlUnit(HtmlUnit htmlUnit); |
| 1011 |
| 956 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode); | 1012 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode); |
| 1013 |
| 957 R visitXmlTagNode(XmlTagNode xmlTagNode); | 1014 R visitXmlTagNode(XmlTagNode xmlTagNode); |
| 958 } | 1015 } |
| 1016 |
| 959 /** | 1017 /** |
| 960 * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/
> | 1018 * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/
> |
| 961 * For example, the following code scans HTML source and returns the result: | 1019 * For example, the following code scans HTML source and returns the result: |
| 962 * | 1020 * |
| 963 * <pre> | 1021 * <pre> |
| 964 * HtmlScanner scanner = new HtmlScanner(source); | 1022 * HtmlScanner scanner = new HtmlScanner(source); |
| 965 * source.getContents(scanner); | 1023 * source.getContents(scanner); |
| 966 * return scanner.getResult(); | 1024 * return scanner.getResult(); |
| 967 * </pre> | 1025 * </pre> |
| 968 * | 1026 * |
| (...skipping 23 matching lines...) Expand all Loading... |
| 992 Token _token; | 1050 Token _token; |
| 993 | 1051 |
| 994 /** | 1052 /** |
| 995 * Construct a new instance to scan the specified source. | 1053 * Construct a new instance to scan the specified source. |
| 996 * | 1054 * |
| 997 * @param source the source to be scanned (not `null`) | 1055 * @param source the source to be scanned (not `null`) |
| 998 */ | 1056 */ |
| 999 HtmlScanner(Source source) { | 1057 HtmlScanner(Source source) { |
| 1000 this._source = source; | 1058 this._source = source; |
| 1001 } | 1059 } |
| 1060 |
| 1002 void accept(CharBuffer contents, int modificationTime) { | 1061 void accept(CharBuffer contents, int modificationTime) { |
| 1003 this._modificationTime = modificationTime; | 1062 this._modificationTime = modificationTime; |
| 1004 _scanner = new CharBufferScanner(_source, contents); | 1063 _scanner = new CharBufferScanner(_source, contents); |
| 1005 _scanner.passThroughElements = _SCRIPT_TAG; | 1064 _scanner.passThroughElements = _SCRIPT_TAG; |
| 1006 _token = _scanner.tokenize(); | 1065 _token = _scanner.tokenize(); |
| 1007 } | 1066 } |
| 1067 |
| 1008 void accept2(String contents, int modificationTime) { | 1068 void accept2(String contents, int modificationTime) { |
| 1009 this._modificationTime = modificationTime; | 1069 this._modificationTime = modificationTime; |
| 1010 _scanner = new StringScanner(_source, contents); | 1070 _scanner = new StringScanner(_source, contents); |
| 1011 _scanner.passThroughElements = _SCRIPT_TAG; | 1071 _scanner.passThroughElements = _SCRIPT_TAG; |
| 1012 _token = _scanner.tokenize(); | 1072 _token = _scanner.tokenize(); |
| 1013 } | 1073 } |
| 1014 | 1074 |
| 1015 /** | 1075 /** |
| 1016 * Answer the result of scanning the source | 1076 * Answer the result of scanning the source |
| 1017 * | 1077 * |
| 1018 * @return the result (not `null`) | 1078 * @return the result (not `null`) |
| 1019 */ | 1079 */ |
| 1020 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc
anner.lineStarts); | 1080 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc
anner.lineStarts); |
| 1021 } | 1081 } |
| 1082 |
| 1022 /** | 1083 /** |
| 1023 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised | 1084 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised |
| 1024 * of [XmlNode]s. | 1085 * of [XmlNode]s. |
| 1025 * | 1086 * |
| 1026 * @coverage dart.engine.html | 1087 * @coverage dart.engine.html |
| 1027 */ | 1088 */ |
| 1028 class XmlParser { | 1089 class XmlParser { |
| 1029 | |
| 1030 /** | 1090 /** |
| 1031 * The source being parsed. | 1091 * The source being parsed. |
| 1032 */ | 1092 */ |
| 1033 Source source; | 1093 Source source; |
| 1034 | 1094 |
| 1035 /** | 1095 /** |
| 1036 * The next token to be parsed. | 1096 * The next token to be parsed. |
| 1037 */ | 1097 */ |
| 1038 Token currentToken; | 1098 Token currentToken; |
| 1039 | 1099 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 } | 1294 } |
| 1235 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co
ntentEnd, closingTag, nodeEnd); | 1295 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co
ntentEnd, closingTag, nodeEnd); |
| 1236 } | 1296 } |
| 1237 | 1297 |
| 1238 /** | 1298 /** |
| 1239 * Report the current token as unexpected | 1299 * Report the current token as unexpected |
| 1240 */ | 1300 */ |
| 1241 void reportUnexpectedToken() { | 1301 void reportUnexpectedToken() { |
| 1242 } | 1302 } |
| 1243 } | 1303 } |
| 1304 |
| 1244 /** | 1305 /** |
| 1245 * Instances of `XmlTagNode` represent XML or HTML elements such as `` and | 1306 * Instances of `XmlTagNode` represent XML or HTML elements such as `` and |
| 1246 * `<body foo="bar"> ... </body>`. | 1307 * `<body foo="bar"> ... </body>`. |
| 1247 * | 1308 * |
| 1248 * @coverage dart.engine.html | 1309 * @coverage dart.engine.html |
| 1249 */ | 1310 */ |
| 1250 class XmlTagNode extends XmlNode { | 1311 class XmlTagNode extends XmlNode { |
| 1251 | |
| 1252 /** | 1312 /** |
| 1253 * Constant representing empty list of attributes. | 1313 * Constant representing empty list of attributes. |
| 1254 */ | 1314 */ |
| 1255 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); | 1315 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); |
| 1256 | 1316 |
| 1257 /** | 1317 /** |
| 1258 * Constant representing empty list of tag nodes. | 1318 * Constant representing empty list of tag nodes. |
| 1259 */ | 1319 */ |
| 1260 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); | 1320 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); |
| 1261 | 1321 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke
n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T
oken nodeEnd) { | 1399 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke
n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T
oken nodeEnd) { |
| 1340 this.nodeStart = nodeStart; | 1400 this.nodeStart = nodeStart; |
| 1341 this.tag = tag; | 1401 this.tag = tag; |
| 1342 this.attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); | 1402 this.attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); |
| 1343 this.attributeEnd = attributeEnd; | 1403 this.attributeEnd = attributeEnd; |
| 1344 this.tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); | 1404 this.tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); |
| 1345 this.contentEnd = contentEnd; | 1405 this.contentEnd = contentEnd; |
| 1346 this.closingTag = closingTag; | 1406 this.closingTag = closingTag; |
| 1347 this.nodeEnd = nodeEnd; | 1407 this.nodeEnd = nodeEnd; |
| 1348 } | 1408 } |
| 1409 |
| 1349 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); | 1410 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); |
| 1350 | 1411 |
| 1351 /** | 1412 /** |
| 1352 * Answer the attribute with the specified name. | 1413 * Answer the attribute with the specified name. |
| 1353 * | 1414 * |
| 1354 * @param name the attribute name | 1415 * @param name the attribute name |
| 1355 * @return the attribute or `null` if no matching attribute is found | 1416 * @return the attribute or `null` if no matching attribute is found |
| 1356 */ | 1417 */ |
| 1357 XmlAttributeNode getAttribute(String name) { | 1418 XmlAttributeNode getAttribute(String name) { |
| 1358 for (XmlAttributeNode attribute in attributes) { | 1419 for (XmlAttributeNode attribute in attributes) { |
| 1359 if (attribute.name.lexeme == name) { | 1420 if (attribute.name.lexeme == name) { |
| 1360 return attribute; | 1421 return attribute; |
| 1361 } | 1422 } |
| 1362 } | 1423 } |
| 1363 return null; | 1424 return null; |
| 1364 } | 1425 } |
| 1365 | 1426 |
| 1366 /** | 1427 /** |
| 1367 * Find the attribute with the given name (see [getAttribute] and answer the l
exeme | 1428 * Find the attribute with the given name (see [getAttribute] and answer the l
exeme |
| 1368 * for the attribute's value token without the leading and trailing quotes (se
e | 1429 * for the attribute's value token without the leading and trailing quotes (se
e |
| 1369 * [XmlAttributeNode#getText]). | 1430 * [XmlAttributeNode#getText]). |
| 1370 * | 1431 * |
| 1371 * @param name the attribute name | 1432 * @param name the attribute name |
| 1372 * @return the attribute text or `null` if no matching attribute is found | 1433 * @return the attribute text or `null` if no matching attribute is found |
| 1373 */ | 1434 */ |
| 1374 String getAttributeText(String name) { | 1435 String getAttributeText(String name) { |
| 1375 XmlAttributeNode attribute = getAttribute(name); | 1436 XmlAttributeNode attribute = getAttribute(name); |
| 1376 return attribute != null ? attribute.text : null; | 1437 return attribute != null ? attribute.text : null; |
| 1377 } | 1438 } |
| 1439 |
| 1378 Token get beginToken => nodeStart; | 1440 Token get beginToken => nodeStart; |
| 1379 | 1441 |
| 1380 /** | 1442 /** |
| 1381 * Answer a string representing the content contained in the receiver. This in
cludes the textual | 1443 * Answer a string representing the content contained in the receiver. This in
cludes the textual |
| 1382 * representation of any child tag nodes ([getTagNodes]). Whitespace between '
<', | 1444 * representation of any child tag nodes ([getTagNodes]). Whitespace between '
<', |
| 1383 * '</', and '>', '/>' is discarded, but all other whitespace is preserved. | 1445 * '</', and '>', '/>' is discarded, but all other whitespace is preserved. |
| 1384 * | 1446 * |
| 1385 * @return the content (not `null`) | 1447 * @return the content (not `null`) |
| 1386 */ | 1448 */ |
| 1387 String get content { | 1449 String get content { |
| 1388 Token token = attributeEnd.next; | 1450 Token token = attributeEnd.next; |
| 1389 if (identical(token, contentEnd)) { | 1451 if (identical(token, contentEnd)) { |
| 1390 return ""; | 1452 return ""; |
| 1391 } | 1453 } |
| 1392 String content = token.lexeme; | 1454 String content = token.lexeme; |
| 1393 token = token.next; | 1455 token = token.next; |
| 1394 if (identical(token, contentEnd)) { | 1456 if (identical(token, contentEnd)) { |
| 1395 return content; | 1457 return content; |
| 1396 } | 1458 } |
| 1397 JavaStringBuilder buffer = new JavaStringBuilder(); | 1459 JavaStringBuilder buffer = new JavaStringBuilder(); |
| 1398 while (token != contentEnd) { | 1460 while (token != contentEnd) { |
| 1399 buffer.append(token.lexeme); | 1461 buffer.append(token.lexeme); |
| 1400 token = token.next; | 1462 token = token.next; |
| 1401 } | 1463 } |
| 1402 return buffer.toString(); | 1464 return buffer.toString(); |
| 1403 } | 1465 } |
| 1466 |
| 1404 Token get endToken { | 1467 Token get endToken { |
| 1405 if (nodeEnd != null) { | 1468 if (nodeEnd != null) { |
| 1406 return nodeEnd; | 1469 return nodeEnd; |
| 1407 } | 1470 } |
| 1408 if (closingTag != null) { | 1471 if (closingTag != null) { |
| 1409 return closingTag; | 1472 return closingTag; |
| 1410 } | 1473 } |
| 1411 if (contentEnd != null) { | 1474 if (contentEnd != null) { |
| 1412 return contentEnd; | 1475 return contentEnd; |
| 1413 } | 1476 } |
| 1414 if (!tagNodes.isEmpty) { | 1477 if (!tagNodes.isEmpty) { |
| 1415 return tagNodes[tagNodes.length - 1].endToken; | 1478 return tagNodes[tagNodes.length - 1].endToken; |
| 1416 } | 1479 } |
| 1417 if (attributeEnd != null) { | 1480 if (attributeEnd != null) { |
| 1418 return attributeEnd; | 1481 return attributeEnd; |
| 1419 } | 1482 } |
| 1420 if (!attributes.isEmpty) { | 1483 if (!attributes.isEmpty) { |
| 1421 return attributes[attributes.length - 1].endToken; | 1484 return attributes[attributes.length - 1].endToken; |
| 1422 } | 1485 } |
| 1423 return tag; | 1486 return tag; |
| 1424 } | 1487 } |
| 1488 |
| 1425 void visitChildren(XmlVisitor visitor) { | 1489 void visitChildren(XmlVisitor visitor) { |
| 1426 for (XmlAttributeNode node in attributes) { | 1490 for (XmlAttributeNode node in attributes) { |
| 1427 node.accept(visitor); | 1491 node.accept(visitor); |
| 1428 } | 1492 } |
| 1429 for (XmlTagNode node in tagNodes) { | 1493 for (XmlTagNode node in tagNodes) { |
| 1430 node.accept(visitor); | 1494 node.accept(visitor); |
| 1431 } | 1495 } |
| 1432 } | 1496 } |
| 1433 | 1497 |
| 1434 /** | 1498 /** |
| 1435 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt
y | 1499 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt
y |
| 1436 */ | 1500 */ |
| 1437 List becomeParentOfEmpty(List children, List ifEmpty) { | 1501 List becomeParentOfEmpty(List children, List ifEmpty) { |
| 1438 if (children != null && children.isEmpty) { | 1502 if (children != null && children.isEmpty) { |
| 1439 return ifEmpty; | 1503 return ifEmpty; |
| 1440 } | 1504 } |
| 1441 return becomeParentOf(children); | 1505 return becomeParentOf(children); |
| 1442 } | 1506 } |
| 1443 } | 1507 } |
| 1508 |
| 1444 /** | 1509 /** |
| 1445 * Instances of the class `HtmlParser` are used to parse tokens into a AST struc
ture comprised | 1510 * Instances of the class `HtmlParser` are used to parse tokens into a AST struc
ture comprised |
| 1446 * of [XmlNode]s. | 1511 * of [XmlNode]s. |
| 1447 * | 1512 * |
| 1448 * @coverage dart.engine.html | 1513 * @coverage dart.engine.html |
| 1449 */ | 1514 */ |
| 1450 class HtmlParser extends XmlParser { | 1515 class HtmlParser extends XmlParser { |
| 1451 static Set<String> SELF_CLOSING = new Set<String>(); | 1516 static Set<String> SELF_CLOSING = new Set<String>(); |
| 1452 | 1517 |
| 1453 /** | 1518 /** |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1474 * Scan then parse the specified source. | 1539 * Scan then parse the specified source. |
| 1475 * | 1540 * |
| 1476 * @param source the source to be scanned and parsed (not `null`) | 1541 * @param source the source to be scanned and parsed (not `null`) |
| 1477 * @return the parse result (not `null`) | 1542 * @return the parse result (not `null`) |
| 1478 */ | 1543 */ |
| 1479 HtmlParseResult parse2(Source source) { | 1544 HtmlParseResult parse2(Source source) { |
| 1480 HtmlScanner scanner = new HtmlScanner(source); | 1545 HtmlScanner scanner = new HtmlScanner(source); |
| 1481 source.getContents(scanner); | 1546 source.getContents(scanner); |
| 1482 return parse(scanner.result); | 1547 return parse(scanner.result); |
| 1483 } | 1548 } |
| 1549 |
| 1484 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); | 1550 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); |
| 1485 } | 1551 } |
| 1552 |
| 1486 /** | 1553 /** |
| 1487 * Instances of the class `HtmlUnit` represent the contents of an HTML file. | 1554 * Instances of the class `HtmlUnit` represent the contents of an HTML file. |
| 1488 * | 1555 * |
| 1489 * @coverage dart.engine.html | 1556 * @coverage dart.engine.html |
| 1490 */ | 1557 */ |
| 1491 class HtmlUnit extends XmlNode { | 1558 class HtmlUnit extends XmlNode { |
| 1492 | |
| 1493 /** | 1559 /** |
| 1494 * The first token in the token stream that was parsed to form this HTML unit. | 1560 * The first token in the token stream that was parsed to form this HTML unit. |
| 1495 */ | 1561 */ |
| 1496 Token _beginToken; | 1562 Token _beginToken; |
| 1497 | 1563 |
| 1498 /** | 1564 /** |
| 1499 * The last token in the token stream that was parsed to form this compilation
unit. This token | 1565 * The last token in the token stream that was parsed to form this compilation
unit. This token |
| 1500 * should always have a type of [TokenType.EOF]. | 1566 * should always have a type of [TokenType.EOF]. |
| 1501 */ | 1567 */ |
| 1502 Token _endToken; | 1568 Token _endToken; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1517 * @param beginToken the first token in the file (not `null`) | 1583 * @param beginToken the first token in the file (not `null`) |
| 1518 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) | 1584 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) |
| 1519 * @param endToken the last token in the token stream which should be of type | 1585 * @param endToken the last token in the token stream which should be of type |
| 1520 * [TokenType.EOF] | 1586 * [TokenType.EOF] |
| 1521 */ | 1587 */ |
| 1522 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { | 1588 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { |
| 1523 this._beginToken = beginToken; | 1589 this._beginToken = beginToken; |
| 1524 this.tagNodes = becomeParentOf(tagNodes); | 1590 this.tagNodes = becomeParentOf(tagNodes); |
| 1525 this._endToken = endToken; | 1591 this._endToken = endToken; |
| 1526 } | 1592 } |
| 1593 |
| 1527 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); | 1594 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); |
| 1595 |
| 1528 Token get beginToken => _beginToken; | 1596 Token get beginToken => _beginToken; |
| 1597 |
| 1529 Token get endToken => _endToken; | 1598 Token get endToken => _endToken; |
| 1599 |
| 1530 void visitChildren(XmlVisitor visitor) { | 1600 void visitChildren(XmlVisitor visitor) { |
| 1531 for (XmlTagNode node in tagNodes) { | 1601 for (XmlTagNode node in tagNodes) { |
| 1532 node.accept(visitor); | 1602 node.accept(visitor); |
| 1533 } | 1603 } |
| 1534 } | 1604 } |
| 1535 } | 1605 } |
| OLD | NEW |