| 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 library engine.html; | 3 library engine.html; |
| 4 import 'dart:collection'; | 4 import 'dart:collection'; |
| 5 import 'java_core.dart'; | 5 import 'java_core.dart'; |
| 6 import 'java_engine.dart'; | 6 import 'java_engine.dart'; |
| 7 import 'source.dart'; | 7 import 'source.dart'; |
| 8 import 'element.dart' show HtmlElementImpl; | 8 import 'element.dart' show HtmlElementImpl; |
| 9 import 'engine.dart' show AnalysisEngine; | 9 import 'engine.dart' show AnalysisEngine; |
| 10 /** | 10 /** |
| 11 * Instances of the class `Token` represent a token that was scanned from the in
put. Each | 11 * 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. | 12 * token knows which token follows it, acting as the head of a linked list of to
kens. |
| 13 * | 13 * |
| 14 * @coverage dart.engine.html | 14 * @coverage dart.engine.html |
| 15 */ | 15 */ |
| 16 class Token { | 16 class Token { |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * The offset from the beginning of the file to the first character in the tok
en. | 19 * The offset from the beginning of the file to the first character in the tok
en. |
| 20 */ | 20 */ |
| 21 int _offset = 0; | 21 int offset = 0; |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * The previous token in the token stream. | 24 * The previous token in the token stream. |
| 25 */ | 25 */ |
| 26 Token _previous; | 26 Token previous; |
| 27 | 27 |
| 28 /** | 28 /** |
| 29 * The next token in the token stream. | 29 * The next token in the token stream. |
| 30 */ | 30 */ |
| 31 Token _next; | 31 Token next; |
| 32 | 32 |
| 33 /** | 33 /** |
| 34 * The type of the token. | 34 * The type of the token. |
| 35 */ | 35 */ |
| 36 TokenType _type; | 36 TokenType type; |
| 37 | 37 |
| 38 /** | 38 /** |
| 39 * The lexeme represented by this token. | 39 * The lexeme represented by this token. |
| 40 */ | 40 */ |
| 41 String _value; | 41 String lexeme; |
| 42 | 42 |
| 43 /** | 43 /** |
| 44 * Initialize a newly created token. | 44 * Initialize a newly created token. |
| 45 * | 45 * |
| 46 * @param type the token type (not `null`) | 46 * @param type the token type (not `null`) |
| 47 * @param offset the offset from the beginning of the file to the first charac
ter in the token | 47 * @param offset the offset from the beginning of the file to the first charac
ter in the token |
| 48 */ | 48 */ |
| 49 Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme); | 49 Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme); |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * Initialize a newly created token. | 52 * Initialize a newly created token. |
| 53 * | 53 * |
| 54 * @param type the token type (not `null`) | 54 * @param type the token type (not `null`) |
| 55 * @param offset the offset from the beginning of the file to the first charac
ter in the token | 55 * @param offset the offset from the beginning of the file to the first charac
ter in the token |
| 56 * @param value the lexeme represented by this token (not `null`) | 56 * @param value the lexeme represented by this token (not `null`) |
| 57 */ | 57 */ |
| 58 Token.con2(TokenType type, int offset, String value) { | 58 Token.con2(TokenType type, int offset, String value) { |
| 59 this._type = type; | 59 this.type = type; |
| 60 this._value = StringUtilities.intern(value); | 60 this.lexeme = StringUtilities.intern(value); |
| 61 this._offset = offset; | 61 this.offset = offset; |
| 62 } | 62 } |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * Return the offset from the beginning of the file to the character after las
t character of the | 65 * Return the offset from the beginning of the file to the character after las
t character of the |
| 66 * token. | 66 * token. |
| 67 * | 67 * |
| 68 * @return the offset from the beginning of the file to the first character af
ter last character | 68 * @return the offset from the beginning of the file to the first character af
ter last character |
| 69 * of the token | 69 * of the token |
| 70 */ | 70 */ |
| 71 int get end => _offset + length; | 71 int get end => offset + length; |
| 72 | 72 |
| 73 /** | 73 /** |
| 74 * Return the number of characters in the node's source range. | 74 * Return the number of characters in the node's source range. |
| 75 * | 75 * |
| 76 * @return the number of characters in the node's source range | 76 * @return the number of characters in the node's source range |
| 77 */ | 77 */ |
| 78 int get length => lexeme.length; | 78 int get length => lexeme.length; |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * Return the lexeme that represents this token. | |
| 82 * | |
| 83 * @return the lexeme (not `null`) | |
| 84 */ | |
| 85 String get lexeme => _value; | |
| 86 | |
| 87 /** | |
| 88 * Return the next token in the token stream. | |
| 89 * | |
| 90 * @return the next token in the token stream | |
| 91 */ | |
| 92 Token get next => _next; | |
| 93 | |
| 94 /** | |
| 95 * Return the offset from the beginning of the file to the first character in
the token. | |
| 96 * | |
| 97 * @return the offset from the beginning of the file to the first character in
the token | |
| 98 */ | |
| 99 int get offset => _offset; | |
| 100 | |
| 101 /** | |
| 102 * Return the previous token in the token stream. | |
| 103 * | |
| 104 * @return the previous token in the token stream | |
| 105 */ | |
| 106 Token get previous => _previous; | |
| 107 | |
| 108 /** | |
| 109 * Answer the token type for the receiver. | |
| 110 * | |
| 111 * @return the token type (not `null`) | |
| 112 */ | |
| 113 TokenType get type => _type; | |
| 114 | |
| 115 /** | |
| 116 * Return `true` if this token is a synthetic token. A synthetic token is a to
ken that was | 81 * Return `true` if this token is a synthetic token. A synthetic token is a to
ken that was |
| 117 * introduced by the parser in order to recover from an error in the code. Syn
thetic tokens always | 82 * introduced by the parser in order to recover from an error in the code. Syn
thetic tokens always |
| 118 * have a length of zero (`0`). | 83 * have a length of zero (`0`). |
| 119 * | 84 * |
| 120 * @return `true` if this token is a synthetic token | 85 * @return `true` if this token is a synthetic token |
| 121 */ | 86 */ |
| 122 bool get isSynthetic => length == 0; | 87 bool get isSynthetic => length == 0; |
| 123 | 88 |
| 124 /** | 89 /** |
| 125 * Set the next token in the token stream to the given token. This has the sid
e-effect of setting | 90 * Set the next token in the token stream to the given token. This has the sid
e-effect of setting |
| 126 * this token to be the previous token for the given token. | 91 * this token to be the previous token for the given token. |
| 127 * | 92 * |
| 128 * @param token the next token in the token stream | 93 * @param token the next token in the token stream |
| 129 * @return the token that was passed in | 94 * @return the token that was passed in |
| 130 */ | 95 */ |
| 131 Token setNext(Token token) { | 96 Token setNext(Token token) { |
| 132 _next = token; | 97 next = token; |
| 133 token.previous = this; | 98 token.previous = this; |
| 134 return token; | 99 return token; |
| 135 } | 100 } |
| 136 String toString() => lexeme; | 101 String toString() => lexeme; |
| 137 | |
| 138 /** | |
| 139 * Set the previous token in the token stream to the given token. | |
| 140 * | |
| 141 * @param previous the previous token in the token stream | |
| 142 */ | |
| 143 void set previous(Token previous2) { | |
| 144 this._previous = previous2; | |
| 145 } | |
| 146 } | 102 } |
| 147 /** | 103 /** |
| 148 * Instances of `HtmlParseResult` hold the result of parsing an HTML file. | 104 * Instances of `HtmlParseResult` hold the result of parsing an HTML file. |
| 149 * | 105 * |
| 150 * @coverage dart.engine.html | 106 * @coverage dart.engine.html |
| 151 */ | 107 */ |
| 152 class HtmlParseResult extends HtmlScanResult { | 108 class HtmlParseResult extends HtmlScanResult { |
| 153 | 109 |
| 154 /** | 110 /** |
| 155 * The unit containing the parsed information (not `null`). | 111 * The unit containing the parsed information (not `null`). |
| 156 */ | 112 */ |
| 157 HtmlUnit _unit; | 113 HtmlUnit htmlUnit; |
| 158 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU
nit unit) : super(modificationTime, token, lineStarts) { | 114 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU
nit unit) : super(modificationTime, token, lineStarts) { |
| 159 this._unit = unit; | 115 this.htmlUnit = unit; |
| 160 } | 116 } |
| 161 | |
| 162 /** | |
| 163 * Answer the unit generated by parsing the source | |
| 164 * | |
| 165 * @return the unit (not `null`) | |
| 166 */ | |
| 167 HtmlUnit get htmlUnit => _unit; | |
| 168 } | 117 } |
| 169 /** | 118 /** |
| 170 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively | 119 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively |
| 171 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit | 120 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit |
| 172 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and | 121 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and |
| 173 * [XmlTagNode]s to be visited. | 122 * [XmlTagNode]s to be visited. |
| 174 * | 123 * |
| 175 * Subclasses that override a visit method must either invoke the overridden vis
it method or must | 124 * Subclasses that override a visit method must either invoke the overridden vis
it method or must |
| 176 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children | 125 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children |
| 177 * of the visited node to not be visited. | 126 * of the visited node to not be visited. |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 * required to implement the interface used to access the characters being scann
ed. | 336 * required to implement the interface used to access the characters being scann
ed. |
| 388 * | 337 * |
| 389 * @coverage dart.engine.html | 338 * @coverage dart.engine.html |
| 390 */ | 339 */ |
| 391 abstract class AbstractScanner { | 340 abstract class AbstractScanner { |
| 392 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; | 341 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; |
| 393 | 342 |
| 394 /** | 343 /** |
| 395 * The source being scanned. | 344 * The source being scanned. |
| 396 */ | 345 */ |
| 397 Source _source; | 346 Source source; |
| 398 | 347 |
| 399 /** | 348 /** |
| 400 * The token pointing to the head of the linked list of tokens. | 349 * The token pointing to the head of the linked list of tokens. |
| 401 */ | 350 */ |
| 402 Token _tokens; | 351 Token _tokens; |
| 403 | 352 |
| 404 /** | 353 /** |
| 405 * The last token that was scanned. | 354 * The last token that was scanned. |
| 406 */ | 355 */ |
| 407 Token _tail; | 356 Token _tail; |
| 408 | 357 |
| 409 /** | 358 /** |
| 410 * A list containing the offsets of the first character of each line in the so
urce code. | 359 * A list containing the offsets of the first character of each line in the so
urce code. |
| 411 */ | 360 */ |
| 412 List<int> _lineStarts = new List<int>(); | 361 List<int> _lineStarts = new List<int>(); |
| 413 | 362 |
| 414 /** | 363 /** |
| 415 * An array of element tags for which the content between tags should be consi
der a single token. | 364 * An array of element tags for which the content between tags should be consi
der a single token. |
| 416 */ | 365 */ |
| 417 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; | 366 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; |
| 418 | 367 |
| 419 /** | 368 /** |
| 420 * Initialize a newly created scanner. | 369 * Initialize a newly created scanner. |
| 421 * | 370 * |
| 422 * @param source the source being scanned | 371 * @param source the source being scanned |
| 423 */ | 372 */ |
| 424 AbstractScanner(Source source) { | 373 AbstractScanner(Source source) { |
| 425 this._source = source; | 374 this.source = source; |
| 426 _tokens = new Token.con1(TokenType.EOF, -1); | 375 _tokens = new Token.con1(TokenType.EOF, -1); |
| 427 _tokens.setNext(_tokens); | 376 _tokens.setNext(_tokens); |
| 428 _tail = _tokens; | 377 _tail = _tokens; |
| 429 recordStartOfLine(); | 378 recordStartOfLine(); |
| 430 } | 379 } |
| 431 | 380 |
| 432 /** | 381 /** |
| 433 * Return an array containing the offsets of the first character of each line
in the source code. | 382 * Return an array containing the offsets of the first character of each line
in the source code. |
| 434 * | 383 * |
| 435 * @return an array containing the offsets of the first character of each line
in the source code | 384 * @return an array containing the offsets of the first character of each line
in the source code |
| 436 */ | 385 */ |
| 437 List<int> get lineStarts => _lineStarts; | 386 List<int> get lineStarts => _lineStarts; |
| 438 | 387 |
| 439 /** | 388 /** |
| 440 * Return the current offset relative to the beginning of the file. Return the
initial offset if | 389 * Return the current offset relative to the beginning of the file. Return the
initial offset if |
| 441 * the scanner has not yet scanned the source code, and one (1) past the end o
f the source code if | 390 * the scanner has not yet scanned the source code, and one (1) past the end o
f the source code if |
| 442 * the source code has been scanned. | 391 * the source code has been scanned. |
| 443 * | 392 * |
| 444 * @return the current offset of the scanner in the source | 393 * @return the current offset of the scanner in the source |
| 445 */ | 394 */ |
| 446 int get offset; | 395 int get offset; |
| 447 | 396 |
| 448 /** | 397 /** |
| 449 * Answer the source being scanned. | |
| 450 * | |
| 451 * @return the source or `null` if undefined | |
| 452 */ | |
| 453 Source get source => _source; | |
| 454 | |
| 455 /** | |
| 456 * Set array of element tags for which the content between tags should be cons
ider a single token. | 398 * Set array of element tags for which the content between tags should be cons
ider a single token. |
| 457 */ | 399 */ |
| 458 void set passThroughElements(List<String> passThroughElements2) { | 400 void set passThroughElements(List<String> passThroughElements2) { |
| 459 this._passThroughElements = passThroughElements2 != null ? passThroughElemen
ts2 : _NO_PASS_THROUGH_ELEMENTS; | 401 this._passThroughElements = passThroughElements2 != null ? passThroughElemen
ts2 : _NO_PASS_THROUGH_ELEMENTS; |
| 460 } | 402 } |
| 461 | 403 |
| 462 /** | 404 /** |
| 463 * Scan the source code to produce a list of tokens representing the source. | 405 * Scan the source code to produce a list of tokens representing the source. |
| 464 * | 406 * |
| 465 * @return the first token in the list of tokens that were produced | 407 * @return the first token in the list of tokens that were produced |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 /** | 635 /** |
| 694 * Instances of `HtmlScanResult` hold the result of scanning an HTML file. | 636 * Instances of `HtmlScanResult` hold the result of scanning an HTML file. |
| 695 * | 637 * |
| 696 * @coverage dart.engine.html | 638 * @coverage dart.engine.html |
| 697 */ | 639 */ |
| 698 class HtmlScanResult { | 640 class HtmlScanResult { |
| 699 | 641 |
| 700 /** | 642 /** |
| 701 * The time at which the contents of the source were last set. | 643 * The time at which the contents of the source were last set. |
| 702 */ | 644 */ |
| 703 int _modificationTime = 0; | 645 int modificationTime = 0; |
| 704 | 646 |
| 705 /** | 647 /** |
| 706 * The first token in the token stream (not `null`). | 648 * The first token in the token stream (not `null`). |
| 707 */ | 649 */ |
| 708 Token _token; | 650 Token token; |
| 709 | 651 |
| 710 /** | 652 /** |
| 711 * The line start information that was produced. | 653 * The line start information that was produced. |
| 712 */ | 654 */ |
| 713 List<int> _lineStarts; | 655 List<int> lineStarts; |
| 714 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { | 656 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { |
| 715 this._modificationTime = modificationTime; | 657 this.modificationTime = modificationTime; |
| 716 this._token = token; | 658 this.token = token; |
| 717 this._lineStarts = lineStarts; | 659 this.lineStarts = lineStarts; |
| 718 } | 660 } |
| 719 | |
| 720 /** | |
| 721 * Answer the line start information that was produced. | |
| 722 * | |
| 723 * @return an array of line starts (not `null`) | |
| 724 */ | |
| 725 List<int> get lineStarts => _lineStarts; | |
| 726 | |
| 727 /** | |
| 728 * Return the time at which the contents of the source were last set. | |
| 729 * | |
| 730 * @return the time at which the contents of the source were last set | |
| 731 */ | |
| 732 int get modificationTime => _modificationTime; | |
| 733 | |
| 734 /** | |
| 735 * Answer the first token in the token stream. | |
| 736 * | |
| 737 * @return the token (not `null`) | |
| 738 */ | |
| 739 Token get token => _token; | |
| 740 } | 661 } |
| 741 /** | 662 /** |
| 742 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The | 663 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The |
| 743 * scanning logic is in the superclass. | 664 * scanning logic is in the superclass. |
| 744 * | 665 * |
| 745 * @coverage dart.engine.html | 666 * @coverage dart.engine.html |
| 746 */ | 667 */ |
| 747 class StringScanner extends AbstractScanner { | 668 class StringScanner extends AbstractScanner { |
| 748 | 669 |
| 749 /** | 670 /** |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 DECLARATION, | 871 DECLARATION, |
| 951 DIRECTIVE, | 872 DIRECTIVE, |
| 952 STRING, | 873 STRING, |
| 953 TAG, | 874 TAG, |
| 954 TEXT]; | 875 TEXT]; |
| 955 | 876 |
| 956 /** | 877 /** |
| 957 * The lexeme that defines this type of token, or `null` if there is more than
one possible | 878 * The lexeme that defines this type of token, or `null` if there is more than
one possible |
| 958 * lexeme for this type of token. | 879 * lexeme for this type of token. |
| 959 */ | 880 */ |
| 960 String _lexeme; | 881 String lexeme; |
| 961 TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) { | 882 TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) { |
| 962 this._lexeme = lexeme; | 883 this.lexeme = lexeme; |
| 963 } | 884 } |
| 964 | |
| 965 /** | |
| 966 * Return the lexeme that defines this type of token, or `null` if there is mo
re than one | |
| 967 * possible lexeme for this type of token. | |
| 968 * | |
| 969 * @return the lexeme that defines this type of token | |
| 970 */ | |
| 971 String get lexeme => _lexeme; | |
| 972 } | 885 } |
| 973 class TokenType_EOF extends TokenType { | 886 class TokenType_EOF extends TokenType { |
| 974 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar
g0); | 887 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar
g0); |
| 975 String toString() => "-eof-"; | 888 String toString() => "-eof-"; |
| 976 } | 889 } |
| 977 /** | 890 /** |
| 978 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. | 891 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. |
| 979 * | 892 * |
| 980 * @coverage dart.engine.html | 893 * @coverage dart.engine.html |
| 981 */ | 894 */ |
| 982 class XmlAttributeNode extends XmlNode { | 895 class XmlAttributeNode extends XmlNode { |
| 983 Token _name; | 896 Token name; |
| 984 Token _equals; | 897 Token equals; |
| 985 Token _value; | 898 Token value; |
| 986 | 899 |
| 987 /** | 900 /** |
| 988 * Construct a new instance representing an XML attribute. | 901 * Construct a new instance representing an XML attribute. |
| 989 * | 902 * |
| 990 * @param name the name token (not `null`). This may be a zero length token if
the attribute | 903 * @param name the name token (not `null`). This may be a zero length token if
the attribute |
| 991 * is badly formed. | 904 * is badly formed. |
| 992 * @param equals the equals sign or `null` if none | 905 * @param equals the equals sign or `null` if none |
| 993 * @param value the value token (not `null`) | 906 * @param value the value token (not `null`) |
| 994 */ | 907 */ |
| 995 XmlAttributeNode(Token name, Token equals, Token value) { | 908 XmlAttributeNode(Token name, Token equals, Token value) { |
| 996 this._name = name; | 909 this.name = name; |
| 997 this._equals = equals; | 910 this.equals = equals; |
| 998 this._value = value; | 911 this.value = value; |
| 999 } | 912 } |
| 1000 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); | 913 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); |
| 1001 Token get beginToken => _name; | 914 Token get beginToken => name; |
| 1002 Token get endToken => _value; | 915 Token get endToken => value; |
| 1003 | |
| 1004 /** | |
| 1005 * Answer the equals sign token that appears between the name and value tokens
. This may be | |
| 1006 * `null` if the attribute is badly formed. | |
| 1007 * | |
| 1008 * @return the token or `null` if there is no equals sign between the name and
value | |
| 1009 */ | |
| 1010 Token get equals => _equals; | |
| 1011 | |
| 1012 /** | |
| 1013 * Answer the attribute name. This may be a zero length token if the attribute
is badly formed. | |
| 1014 * | |
| 1015 * @return the name (not `null`) | |
| 1016 */ | |
| 1017 Token get name => _name; | |
| 1018 | 916 |
| 1019 /** | 917 /** |
| 1020 * Answer the lexeme for the value token without the leading and trailing quot
es. | 918 * Answer the lexeme for the value token without the leading and trailing quot
es. |
| 1021 * | 919 * |
| 1022 * @return the text or `null` if the value is not specified | 920 * @return the text or `null` if the value is not specified |
| 1023 */ | 921 */ |
| 1024 String get text { | 922 String get text { |
| 1025 if (_value == null) { | 923 if (value == null) { |
| 1026 return null; | 924 return null; |
| 1027 } | 925 } |
| 1028 String text = _value.lexeme; | 926 String text = value.lexeme; |
| 1029 int len = text.length; | 927 int len = text.length; |
| 1030 if (len > 0) { | 928 if (len > 0) { |
| 1031 if (text.codeUnitAt(0) == 0x22) { | 929 if (text.codeUnitAt(0) == 0x22) { |
| 1032 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) { | 930 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) { |
| 1033 return text.substring(1, len - 1); | 931 return text.substring(1, len - 1); |
| 1034 } else { | 932 } else { |
| 1035 return text.substring(1); | 933 return text.substring(1); |
| 1036 } | 934 } |
| 1037 } else if (text.codeUnitAt(0) == 0x27) { | 935 } else if (text.codeUnitAt(0) == 0x27) { |
| 1038 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { | 936 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { |
| 1039 return text.substring(1, len - 1); | 937 return text.substring(1, len - 1); |
| 1040 } else { | 938 } else { |
| 1041 return text.substring(1); | 939 return text.substring(1); |
| 1042 } | 940 } |
| 1043 } | 941 } |
| 1044 } | 942 } |
| 1045 return text; | 943 return text; |
| 1046 } | 944 } |
| 1047 | |
| 1048 /** | |
| 1049 * Answer the attribute value. A properly formed value will start and end with
matching quote | |
| 1050 * characters, but the value returned may not be properly formed. | |
| 1051 * | |
| 1052 * @return the value or `null` if this represents a badly formed attribute | |
| 1053 */ | |
| 1054 Token get value => _value; | |
| 1055 void visitChildren(XmlVisitor visitor) { | 945 void visitChildren(XmlVisitor visitor) { |
| 1056 } | 946 } |
| 1057 } | 947 } |
| 1058 /** | 948 /** |
| 1059 * The interface `XmlVisitor` defines the behavior of objects that can be used t
o visit an | 949 * The interface `XmlVisitor` defines the behavior of objects that can be used t
o visit an |
| 1060 * [XmlNode] structure. | 950 * [XmlNode] structure. |
| 1061 * | 951 * |
| 1062 * @coverage dart.engine.html | 952 * @coverage dart.engine.html |
| 1063 */ | 953 */ |
| 1064 abstract class XmlVisitor<R> { | 954 abstract class XmlVisitor<R> { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised | 1023 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised |
| 1134 * of [XmlNode]s. | 1024 * of [XmlNode]s. |
| 1135 * | 1025 * |
| 1136 * @coverage dart.engine.html | 1026 * @coverage dart.engine.html |
| 1137 */ | 1027 */ |
| 1138 class XmlParser { | 1028 class XmlParser { |
| 1139 | 1029 |
| 1140 /** | 1030 /** |
| 1141 * The source being parsed. | 1031 * The source being parsed. |
| 1142 */ | 1032 */ |
| 1143 Source _source; | 1033 Source source; |
| 1144 | 1034 |
| 1145 /** | 1035 /** |
| 1146 * The next token to be parsed. | 1036 * The next token to be parsed. |
| 1147 */ | 1037 */ |
| 1148 Token _currentToken; | 1038 Token currentToken; |
| 1149 | 1039 |
| 1150 /** | 1040 /** |
| 1151 * Construct a parser for the specified source. | 1041 * Construct a parser for the specified source. |
| 1152 * | 1042 * |
| 1153 * @param source the source being parsed | 1043 * @param source the source being parsed |
| 1154 */ | 1044 */ |
| 1155 XmlParser(Source source) { | 1045 XmlParser(Source source) { |
| 1156 this._source = source; | 1046 this.source = source; |
| 1157 } | 1047 } |
| 1158 | 1048 |
| 1159 /** | 1049 /** |
| 1160 * Answer the source being parsed. | |
| 1161 * | |
| 1162 * @return the source | |
| 1163 */ | |
| 1164 Source get source => _source; | |
| 1165 | |
| 1166 /** | |
| 1167 * Answer `true` if the specified tag is self closing and thus should never ha
ve content or | 1050 * Answer `true` if the specified tag is self closing and thus should never ha
ve content or |
| 1168 * child tag nodes. | 1051 * child tag nodes. |
| 1169 * | 1052 * |
| 1170 * @param tag the tag (not `null`) | 1053 * @param tag the tag (not `null`) |
| 1171 * @return `true` if self closing | 1054 * @return `true` if self closing |
| 1172 */ | 1055 */ |
| 1173 bool isSelfClosing(Token tag) => false; | 1056 bool isSelfClosing(Token tag) => false; |
| 1174 | 1057 |
| 1175 /** | 1058 /** |
| 1176 * Parse the entire token stream and in the process, advance the current token
to the end of the | 1059 * Parse the entire token stream and in the process, advance the current token
to the end of the |
| 1177 * token stream. | 1060 * token stream. |
| 1178 * | 1061 * |
| 1179 * @return the list of tag nodes found (not `null`, contains no `null`) | 1062 * @return the list of tag nodes found (not `null`, contains no `null`) |
| 1180 */ | 1063 */ |
| 1181 List<XmlTagNode> parseTopTagNodes(Token firstToken) { | 1064 List<XmlTagNode> parseTopTagNodes(Token firstToken) { |
| 1182 _currentToken = firstToken; | 1065 currentToken = firstToken; |
| 1183 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); | 1066 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); |
| 1184 while (true) { | 1067 while (true) { |
| 1185 while (true) { | 1068 while (true) { |
| 1186 if (_currentToken.type == TokenType.LT) { | 1069 if (currentToken.type == TokenType.LT) { |
| 1187 tagNodes.add(parseTagNode()); | 1070 tagNodes.add(parseTagNode()); |
| 1188 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken.
type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) { | 1071 } else if (currentToken.type == TokenType.DECLARATION || currentToken.ty
pe == TokenType.DIRECTIVE || currentToken.type == TokenType.COMMENT) { |
| 1189 _currentToken = _currentToken.next; | 1072 currentToken = currentToken.next; |
| 1190 } else if (_currentToken.type == TokenType.EOF) { | 1073 } else if (currentToken.type == TokenType.EOF) { |
| 1191 return tagNodes; | 1074 return tagNodes; |
| 1192 } else { | 1075 } else { |
| 1193 reportUnexpectedToken(); | 1076 reportUnexpectedToken(); |
| 1194 _currentToken = _currentToken.next; | 1077 currentToken = currentToken.next; |
| 1195 } | 1078 } |
| 1196 break; | 1079 break; |
| 1197 } | 1080 } |
| 1198 } | 1081 } |
| 1199 } | 1082 } |
| 1200 | 1083 |
| 1201 /** | 1084 /** |
| 1202 * Answer the current token. | |
| 1203 * | |
| 1204 * @return the current token | |
| 1205 */ | |
| 1206 Token get currentToken => _currentToken; | |
| 1207 | |
| 1208 /** | |
| 1209 * Insert a synthetic token of the specified type before the current token | 1085 * Insert a synthetic token of the specified type before the current token |
| 1210 * | 1086 * |
| 1211 * @param type the type of token to be inserted (not `null`) | 1087 * @param type the type of token to be inserted (not `null`) |
| 1212 * @return the synthetic token that was inserted (not `null`) | 1088 * @return the synthetic token that was inserted (not `null`) |
| 1213 */ | 1089 */ |
| 1214 Token insertSyntheticToken(TokenType type) { | 1090 Token insertSyntheticToken(TokenType type) { |
| 1215 Token token = new Token.con2(type, _currentToken.offset, ""); | 1091 Token token = new Token.con2(type, currentToken.offset, ""); |
| 1216 _currentToken.previous.setNext(token); | 1092 currentToken.previous.setNext(token); |
| 1217 token.setNext(_currentToken); | 1093 token.setNext(currentToken); |
| 1218 return token; | 1094 return token; |
| 1219 } | 1095 } |
| 1220 | 1096 |
| 1221 /** | 1097 /** |
| 1222 * Parse the token stream for an attribute. This method advances the current t
oken over the | 1098 * Parse the token stream for an attribute. This method advances the current t
oken over the |
| 1223 * attribute, but should not be called if the [currentToken] is not [TokenType
#TAG]. | 1099 * attribute, but should not be called if the [currentToken] is not [TokenType
#TAG]. |
| 1224 * | 1100 * |
| 1225 * @return the attribute (not `null`) | 1101 * @return the attribute (not `null`) |
| 1226 */ | 1102 */ |
| 1227 XmlAttributeNode parseAttribute() { | 1103 XmlAttributeNode parseAttribute() { |
| 1228 Token name = _currentToken; | 1104 Token name = currentToken; |
| 1229 _currentToken = _currentToken.next; | 1105 currentToken = currentToken.next; |
| 1230 Token equals; | 1106 Token equals; |
| 1231 if (identical(_currentToken.type, TokenType.EQ)) { | 1107 if (identical(currentToken.type, TokenType.EQ)) { |
| 1232 equals = _currentToken; | 1108 equals = currentToken; |
| 1233 _currentToken = _currentToken.next; | 1109 currentToken = currentToken.next; |
| 1234 } else { | 1110 } else { |
| 1235 reportUnexpectedToken(); | 1111 reportUnexpectedToken(); |
| 1236 equals = insertSyntheticToken(TokenType.EQ); | 1112 equals = insertSyntheticToken(TokenType.EQ); |
| 1237 } | 1113 } |
| 1238 Token value; | 1114 Token value; |
| 1239 if (identical(_currentToken.type, TokenType.STRING)) { | 1115 if (identical(currentToken.type, TokenType.STRING)) { |
| 1240 value = _currentToken; | 1116 value = currentToken; |
| 1241 _currentToken = _currentToken.next; | 1117 currentToken = currentToken.next; |
| 1242 } else { | 1118 } else { |
| 1243 reportUnexpectedToken(); | 1119 reportUnexpectedToken(); |
| 1244 value = insertSyntheticToken(TokenType.STRING); | 1120 value = insertSyntheticToken(TokenType.STRING); |
| 1245 } | 1121 } |
| 1246 return new XmlAttributeNode(name, equals, value); | 1122 return new XmlAttributeNode(name, equals, value); |
| 1247 } | 1123 } |
| 1248 | 1124 |
| 1249 /** | 1125 /** |
| 1250 * Parse the stream for a sequence of attributes. This method advances the cur
rent token to the | 1126 * Parse the stream for a sequence of attributes. This method advances the cur
rent token to the |
| 1251 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF]. | 1127 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF]. |
| 1252 * | 1128 * |
| 1253 * @return a collection of zero or more attributes (not `null`, contains no `n
ull`s) | 1129 * @return a collection of zero or more attributes (not `null`, contains no `n
ull`s) |
| 1254 */ | 1130 */ |
| 1255 List<XmlAttributeNode> parseAttributes() { | 1131 List<XmlAttributeNode> parseAttributes() { |
| 1256 TokenType type = _currentToken.type; | 1132 TokenType type = currentToken.type; |
| 1257 if (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) ||
identical(type, TokenType.EOF)) { | 1133 if (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) ||
identical(type, TokenType.EOF)) { |
| 1258 return XmlTagNode.NO_ATTRIBUTES; | 1134 return XmlTagNode.NO_ATTRIBUTES; |
| 1259 } | 1135 } |
| 1260 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); | 1136 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); |
| 1261 while (true) { | 1137 while (true) { |
| 1262 while (true) { | 1138 while (true) { |
| 1263 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp
e.SLASH_GT || _currentToken.type == TokenType.EOF) { | 1139 if (currentToken.type == TokenType.GT || currentToken.type == TokenType.
SLASH_GT || currentToken.type == TokenType.EOF) { |
| 1264 return attributes; | 1140 return attributes; |
| 1265 } else if (_currentToken.type == TokenType.TAG) { | 1141 } else if (currentToken.type == TokenType.TAG) { |
| 1266 attributes.add(parseAttribute()); | 1142 attributes.add(parseAttribute()); |
| 1267 } else { | 1143 } else { |
| 1268 reportUnexpectedToken(); | 1144 reportUnexpectedToken(); |
| 1269 _currentToken = _currentToken.next; | 1145 currentToken = currentToken.next; |
| 1270 } | 1146 } |
| 1271 break; | 1147 break; |
| 1272 } | 1148 } |
| 1273 } | 1149 } |
| 1274 } | 1150 } |
| 1275 | 1151 |
| 1276 /** | 1152 /** |
| 1277 * Parse the stream for a sequence of tag nodes existing within a parent tag n
ode. This method | 1153 * Parse the stream for a sequence of tag nodes existing within a parent tag n
ode. This method |
| 1278 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E
OF]. | 1154 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E
OF]. |
| 1279 * | 1155 * |
| 1280 * @return a list of nodes (not `null`, contains no `null`s) | 1156 * @return a list of nodes (not `null`, contains no `null`s) |
| 1281 */ | 1157 */ |
| 1282 List<XmlTagNode> parseChildTagNodes() { | 1158 List<XmlTagNode> parseChildTagNodes() { |
| 1283 TokenType type = _currentToken.type; | 1159 TokenType type = currentToken.type; |
| 1284 if (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) { | 1160 if (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) { |
| 1285 return XmlTagNode.NO_TAG_NODES; | 1161 return XmlTagNode.NO_TAG_NODES; |
| 1286 } | 1162 } |
| 1287 List<XmlTagNode> nodes = new List<XmlTagNode>(); | 1163 List<XmlTagNode> nodes = new List<XmlTagNode>(); |
| 1288 while (true) { | 1164 while (true) { |
| 1289 while (true) { | 1165 while (true) { |
| 1290 if (_currentToken.type == TokenType.LT) { | 1166 if (currentToken.type == TokenType.LT) { |
| 1291 nodes.add(parseTagNode()); | 1167 nodes.add(parseTagNode()); |
| 1292 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ
e == TokenType.EOF) { | 1168 } else if (currentToken.type == TokenType.LT_SLASH || currentToken.type
== TokenType.EOF) { |
| 1293 return nodes; | 1169 return nodes; |
| 1294 } else if (_currentToken.type == TokenType.COMMENT) { | 1170 } else if (currentToken.type == TokenType.COMMENT) { |
| 1295 _currentToken = _currentToken.next; | 1171 currentToken = currentToken.next; |
| 1296 } else { | 1172 } else { |
| 1297 reportUnexpectedToken(); | 1173 reportUnexpectedToken(); |
| 1298 _currentToken = _currentToken.next; | 1174 currentToken = currentToken.next; |
| 1299 } | 1175 } |
| 1300 break; | 1176 break; |
| 1301 } | 1177 } |
| 1302 } | 1178 } |
| 1303 } | 1179 } |
| 1304 | 1180 |
| 1305 /** | 1181 /** |
| 1306 * Parse the token stream for the next tag node. This method advances current
token over the | 1182 * Parse the token stream for the next tag node. This method advances current
token over the |
| 1307 * parsed tag node, but should only be called if the current token is [TokenTy
pe#LT] | 1183 * parsed tag node, but should only be called if the current token is [TokenTy
pe#LT] |
| 1308 * | 1184 * |
| 1309 * @return the tag node or `null` if none found | 1185 * @return the tag node or `null` if none found |
| 1310 */ | 1186 */ |
| 1311 XmlTagNode parseTagNode() { | 1187 XmlTagNode parseTagNode() { |
| 1312 Token nodeStart = _currentToken; | 1188 Token nodeStart = currentToken; |
| 1313 _currentToken = _currentToken.next; | 1189 currentToken = currentToken.next; |
| 1314 Token tag; | 1190 Token tag; |
| 1315 if (identical(_currentToken.type, TokenType.TAG)) { | 1191 if (identical(currentToken.type, TokenType.TAG)) { |
| 1316 tag = _currentToken; | 1192 tag = currentToken; |
| 1317 _currentToken = _currentToken.next; | 1193 currentToken = currentToken.next; |
| 1318 } else { | 1194 } else { |
| 1319 reportUnexpectedToken(); | 1195 reportUnexpectedToken(); |
| 1320 tag = insertSyntheticToken(TokenType.TAG); | 1196 tag = insertSyntheticToken(TokenType.TAG); |
| 1321 } | 1197 } |
| 1322 List<XmlAttributeNode> attributes = parseAttributes(); | 1198 List<XmlAttributeNode> attributes = parseAttributes(); |
| 1323 Token attributeEnd; | 1199 Token attributeEnd; |
| 1324 if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.t
ype, TokenType.SLASH_GT)) { | 1200 if (identical(currentToken.type, TokenType.GT) || identical(currentToken.typ
e, TokenType.SLASH_GT)) { |
| 1325 attributeEnd = _currentToken; | 1201 attributeEnd = currentToken; |
| 1326 _currentToken = _currentToken.next; | 1202 currentToken = currentToken.next; |
| 1327 } else { | 1203 } else { |
| 1328 reportUnexpectedToken(); | 1204 reportUnexpectedToken(); |
| 1329 attributeEnd = insertSyntheticToken(TokenType.SLASH_GT); | 1205 attributeEnd = insertSyntheticToken(TokenType.SLASH_GT); |
| 1330 } | 1206 } |
| 1331 if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag))
{ | 1207 if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag))
{ |
| 1332 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode
.NO_TAG_NODES, _currentToken, null, attributeEnd); | 1208 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode
.NO_TAG_NODES, currentToken, null, attributeEnd); |
| 1333 } | 1209 } |
| 1334 List<XmlTagNode> tagNodes = parseChildTagNodes(); | 1210 List<XmlTagNode> tagNodes = parseChildTagNodes(); |
| 1335 Token contentEnd; | 1211 Token contentEnd; |
| 1336 if (identical(_currentToken.type, TokenType.LT_SLASH)) { | 1212 if (identical(currentToken.type, TokenType.LT_SLASH)) { |
| 1337 contentEnd = _currentToken; | 1213 contentEnd = currentToken; |
| 1338 _currentToken = _currentToken.next; | 1214 currentToken = currentToken.next; |
| 1339 } else { | 1215 } else { |
| 1340 reportUnexpectedToken(); | 1216 reportUnexpectedToken(); |
| 1341 contentEnd = insertSyntheticToken(TokenType.LT_SLASH); | 1217 contentEnd = insertSyntheticToken(TokenType.LT_SLASH); |
| 1342 } | 1218 } |
| 1343 Token closingTag; | 1219 Token closingTag; |
| 1344 if (identical(_currentToken.type, TokenType.TAG)) { | 1220 if (identical(currentToken.type, TokenType.TAG)) { |
| 1345 closingTag = _currentToken; | 1221 closingTag = currentToken; |
| 1346 _currentToken = _currentToken.next; | 1222 currentToken = currentToken.next; |
| 1347 } else { | 1223 } else { |
| 1348 reportUnexpectedToken(); | 1224 reportUnexpectedToken(); |
| 1349 closingTag = insertSyntheticToken(TokenType.TAG); | 1225 closingTag = insertSyntheticToken(TokenType.TAG); |
| 1350 } | 1226 } |
| 1351 Token nodeEnd; | 1227 Token nodeEnd; |
| 1352 if (identical(_currentToken.type, TokenType.GT)) { | 1228 if (identical(currentToken.type, TokenType.GT)) { |
| 1353 nodeEnd = _currentToken; | 1229 nodeEnd = currentToken; |
| 1354 _currentToken = _currentToken.next; | 1230 currentToken = currentToken.next; |
| 1355 } else { | 1231 } else { |
| 1356 reportUnexpectedToken(); | 1232 reportUnexpectedToken(); |
| 1357 nodeEnd = insertSyntheticToken(TokenType.GT); | 1233 nodeEnd = insertSyntheticToken(TokenType.GT); |
| 1358 } | 1234 } |
| 1359 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co
ntentEnd, closingTag, nodeEnd); | 1235 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co
ntentEnd, closingTag, nodeEnd); |
| 1360 } | 1236 } |
| 1361 | 1237 |
| 1362 /** | 1238 /** |
| 1363 * Report the current token as unexpected | 1239 * Report the current token as unexpected |
| 1364 */ | 1240 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1379 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); | 1255 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); |
| 1380 | 1256 |
| 1381 /** | 1257 /** |
| 1382 * Constant representing empty list of tag nodes. | 1258 * Constant representing empty list of tag nodes. |
| 1383 */ | 1259 */ |
| 1384 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); | 1260 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); |
| 1385 | 1261 |
| 1386 /** | 1262 /** |
| 1387 * The starting [TokenType#LT] token (not `null`). | 1263 * The starting [TokenType#LT] token (not `null`). |
| 1388 */ | 1264 */ |
| 1389 Token _nodeStart; | 1265 Token nodeStart; |
| 1390 | 1266 |
| 1391 /** | 1267 /** |
| 1392 * The [TokenType#TAG] token after the starting '<' (not `null`). | 1268 * The [TokenType#TAG] token after the starting '<' (not `null`). |
| 1393 */ | 1269 */ |
| 1394 Token _tag; | 1270 Token tag; |
| 1395 | 1271 |
| 1396 /** | 1272 /** |
| 1397 * The attributes contained by the receiver (not `null`, contains no `null`s). | 1273 * The attributes contained by the receiver (not `null`, contains no `null`s). |
| 1398 */ | 1274 */ |
| 1399 List<XmlAttributeNode> _attributes; | 1275 List<XmlAttributeNode> attributes; |
| 1400 | 1276 |
| 1401 /** | 1277 /** |
| 1402 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not | 1278 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not |
| 1403 * `null`). The token may be the same token as [nodeEnd] if there are no child | 1279 * `null`). The token may be the same token as [nodeEnd] if there are no child |
| 1404 * [tagNodes]. | 1280 * [tagNodes]. |
| 1405 */ | 1281 */ |
| 1406 Token _attributeEnd; | 1282 Token attributeEnd; |
| 1407 | 1283 |
| 1408 /** | 1284 /** |
| 1409 * The tag nodes contained in the receiver (not `null`, contains no `null`s). | 1285 * The tag nodes contained in the receiver (not `null`, contains no `null`s). |
| 1410 */ | 1286 */ |
| 1411 List<XmlTagNode> _tagNodes; | 1287 List<XmlTagNode> tagNodes; |
| 1412 | 1288 |
| 1413 /** | 1289 /** |
| 1414 * The token (not `null`) after the content, which may be | 1290 * The token (not `null`) after the content, which may be |
| 1415 * | 1291 * |
| 1416 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or | 1292 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or |
| 1417 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
self | 1293 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
self |
| 1418 * closing or the attributeEnd is [TokenType#SLASH_GT], or | 1294 * closing or the attributeEnd is [TokenType#SLASH_GT], or |
| 1419 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la
st node in | 1295 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la
st node in |
| 1420 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there
is no | 1296 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there
is no |
| 1421 * content and the attributes ended with [TokenType#SLASH_GT]. | 1297 * content and the attributes ended with [TokenType#SLASH_GT]. |
| 1422 * | 1298 * |
| 1423 */ | 1299 */ |
| 1424 Token _contentEnd; | 1300 Token contentEnd; |
| 1425 | 1301 |
| 1426 /** | 1302 /** |
| 1427 * The closing [TokenType#TAG] after the child elements or `null` if there is
no | 1303 * The closing [TokenType#TAG] after the child elements or `null` if there is
no |
| 1428 * content and the attributes ended with [TokenType#SLASH_GT] | 1304 * content and the attributes ended with [TokenType#SLASH_GT] |
| 1429 */ | 1305 */ |
| 1430 Token _closingTag; | 1306 Token closingTag; |
| 1431 | 1307 |
| 1432 /** | 1308 /** |
| 1433 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). | 1309 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). |
| 1434 */ | 1310 */ |
| 1435 Token _nodeEnd; | 1311 Token nodeEnd; |
| 1436 | 1312 |
| 1437 /** | 1313 /** |
| 1438 * Construct a new instance representing an XML or HTML element | 1314 * Construct a new instance representing an XML or HTML element |
| 1439 * | 1315 * |
| 1440 * @param nodeStart the starting [TokenType#LT] token (not `null`) | 1316 * @param nodeStart the starting [TokenType#LT] token (not `null`) |
| 1441 * @param tag the [TokenType#TAG] token after the starting '<' (not `null`)
. | 1317 * @param tag the [TokenType#TAG] token after the starting '<' (not `null`)
. |
| 1442 * @param attributes the attributes associated with this element or [NO_ATTRIB
UTES] (not | 1318 * @param attributes the attributes associated with this element or [NO_ATTRIB
UTES] (not |
| 1443 * `null`, contains no `null`s) | 1319 * `null`, contains no `null`s) |
| 1444 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after
the | 1320 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after
the |
| 1445 * attributes (not `null`). The token may be the same token as [nodeE
nd] if | 1321 * attributes (not `null`). The token may be the same token as [nodeE
nd] if |
| 1446 * there are no child [tagNodes]. | 1322 * there are no child [tagNodes]. |
| 1447 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul
l`, | 1323 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul
l`, |
| 1448 * contains no `null`s) | 1324 * contains no `null`s) |
| 1449 * @param contentEnd the token (not `null`) after the content, which may be | 1325 * @param contentEnd the token (not `null`) after the content, which may be |
| 1450 * | 1326 * |
| 1451 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or | 1327 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or |
| 1452 * * (2) the [TokenType#LT] nodeStart of the next sibling node if thi
s node is | 1328 * * (2) the [TokenType#LT] nodeStart of the next sibling node if thi
s node is |
| 1453 * self closing or the attributeEnd is [TokenType#SLASH_GT], or | 1329 * self closing or the attributeEnd is [TokenType#SLASH_GT], or |
| 1454 * * (3) [TokenType#EOF] if the node does not have a closing tag and
is the last | 1330 * * (3) [TokenType#EOF] if the node does not have a closing tag and
is the last |
| 1455 * node in the stream [TokenType#LT_SLASH] token after the content, o
r `null` | 1331 * node in the stream [TokenType#LT_SLASH] token after the content, o
r `null` |
| 1456 * if there is no content and the attributes ended with [TokenType#SL
ASH_GT]. | 1332 * if there is no content and the attributes ended with [TokenType#SL
ASH_GT]. |
| 1457 * | 1333 * |
| 1458 * @param closingTag the closing [TokenType#TAG] after the child elements or `
null` if | 1334 * @param closingTag the closing [TokenType#TAG] after the child elements or `
null` if |
| 1459 * there is no content and the attributes ended with [TokenType#SLASH
_GT] | 1335 * there is no content and the attributes ended with [TokenType#SLASH
_GT] |
| 1460 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not | 1336 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not |
| 1461 * `null`) | 1337 * `null`) |
| 1462 */ | 1338 */ |
| 1463 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke
n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T
oken nodeEnd) { | 1339 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke
n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T
oken nodeEnd) { |
| 1464 this._nodeStart = nodeStart; | 1340 this.nodeStart = nodeStart; |
| 1465 this._tag = tag; | 1341 this.tag = tag; |
| 1466 this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); | 1342 this.attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); |
| 1467 this._attributeEnd = attributeEnd; | 1343 this.attributeEnd = attributeEnd; |
| 1468 this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); | 1344 this.tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); |
| 1469 this._contentEnd = contentEnd; | 1345 this.contentEnd = contentEnd; |
| 1470 this._closingTag = closingTag; | 1346 this.closingTag = closingTag; |
| 1471 this._nodeEnd = nodeEnd; | 1347 this.nodeEnd = nodeEnd; |
| 1472 } | 1348 } |
| 1473 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); | 1349 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); |
| 1474 | 1350 |
| 1475 /** | 1351 /** |
| 1476 * Answer the attribute with the specified name. | 1352 * Answer the attribute with the specified name. |
| 1477 * | 1353 * |
| 1478 * @param name the attribute name | 1354 * @param name the attribute name |
| 1479 * @return the attribute or `null` if no matching attribute is found | 1355 * @return the attribute or `null` if no matching attribute is found |
| 1480 */ | 1356 */ |
| 1481 XmlAttributeNode getAttribute(String name2) { | 1357 XmlAttributeNode getAttribute(String name2) { |
| 1482 for (XmlAttributeNode attribute in _attributes) { | 1358 for (XmlAttributeNode attribute in attributes) { |
| 1483 if (attribute.name.lexeme == name2) { | 1359 if (attribute.name.lexeme == name2) { |
| 1484 return attribute; | 1360 return attribute; |
| 1485 } | 1361 } |
| 1486 } | 1362 } |
| 1487 return null; | 1363 return null; |
| 1488 } | 1364 } |
| 1489 | 1365 |
| 1490 /** | 1366 /** |
| 1491 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not | |
| 1492 * `null`). The token may be the same token as [nodeEnd] if there are no child | |
| 1493 * [tagNodes]. | |
| 1494 * | |
| 1495 * @return the token (not `null`) | |
| 1496 */ | |
| 1497 Token get attributeEnd => _attributeEnd; | |
| 1498 | |
| 1499 /** | |
| 1500 * Answer the receiver's attributes. Callers should not manipulate the returne
d list to edit the | |
| 1501 * AST structure. | |
| 1502 * | |
| 1503 * @return the attributes (not `null`, contains no `null`s) | |
| 1504 */ | |
| 1505 List<XmlAttributeNode> get attributes => _attributes; | |
| 1506 | |
| 1507 /** | |
| 1508 * Find the attribute with the given name (see [getAttribute] and answer the l
exeme | 1367 * Find the attribute with the given name (see [getAttribute] and answer the l
exeme |
| 1509 * for the attribute's value token without the leading and trailing quotes (se
e | 1368 * for the attribute's value token without the leading and trailing quotes (se
e |
| 1510 * [XmlAttributeNode#getText]). | 1369 * [XmlAttributeNode#getText]). |
| 1511 * | 1370 * |
| 1512 * @param name the attribute name | 1371 * @param name the attribute name |
| 1513 * @return the attribute text or `null` if no matching attribute is found | 1372 * @return the attribute text or `null` if no matching attribute is found |
| 1514 */ | 1373 */ |
| 1515 String getAttributeText(String name) { | 1374 String getAttributeText(String name) { |
| 1516 XmlAttributeNode attribute = getAttribute(name); | 1375 XmlAttributeNode attribute = getAttribute(name); |
| 1517 return attribute != null ? attribute.text : null; | 1376 return attribute != null ? attribute.text : null; |
| 1518 } | 1377 } |
| 1519 Token get beginToken => _nodeStart; | 1378 Token get beginToken => nodeStart; |
| 1520 | |
| 1521 /** | |
| 1522 * The the closing [TokenType#TAG] after the child elements or `null` if there
is no | |
| 1523 * content and the attributes ended with [TokenType#SLASH_GT] | |
| 1524 * | |
| 1525 * @return the closing tag or `null` | |
| 1526 */ | |
| 1527 Token get closingTag => _closingTag; | |
| 1528 | 1379 |
| 1529 /** | 1380 /** |
| 1530 * Answer a string representing the content contained in the receiver. This in
cludes the textual | 1381 * Answer a string representing the content contained in the receiver. This in
cludes the textual |
| 1531 * representation of any child tag nodes ([getTagNodes]). Whitespace between '
<', | 1382 * representation of any child tag nodes ([getTagNodes]). Whitespace between '
<', |
| 1532 * '</', and '>', '/>' is discarded, but all other whitespace is preserved. | 1383 * '</', and '>', '/>' is discarded, but all other whitespace is preserved. |
| 1533 * | 1384 * |
| 1534 * @return the content (not `null`) | 1385 * @return the content (not `null`) |
| 1535 */ | 1386 */ |
| 1536 String get content { | 1387 String get content { |
| 1537 Token token = _attributeEnd.next; | 1388 Token token = attributeEnd.next; |
| 1538 if (identical(token, _contentEnd)) { | 1389 if (identical(token, contentEnd)) { |
| 1539 return ""; | 1390 return ""; |
| 1540 } | 1391 } |
| 1541 String content = token.lexeme; | 1392 String content = token.lexeme; |
| 1542 token = token.next; | 1393 token = token.next; |
| 1543 if (identical(token, _contentEnd)) { | 1394 if (identical(token, contentEnd)) { |
| 1544 return content; | 1395 return content; |
| 1545 } | 1396 } |
| 1546 JavaStringBuilder buffer = new JavaStringBuilder(); | 1397 JavaStringBuilder buffer = new JavaStringBuilder(); |
| 1547 while (token != _contentEnd) { | 1398 while (token != contentEnd) { |
| 1548 buffer.append(token.lexeme); | 1399 buffer.append(token.lexeme); |
| 1549 token = token.next; | 1400 token = token.next; |
| 1550 } | 1401 } |
| 1551 return buffer.toString(); | 1402 return buffer.toString(); |
| 1552 } | 1403 } |
| 1553 | |
| 1554 /** | |
| 1555 * Answer the token (not `null`) after the content, which may be | |
| 1556 * | |
| 1557 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or | |
| 1558 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
self | |
| 1559 * closing or the attributeEnd is [TokenType#SLASH_GT], or | |
| 1560 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la
st node in | |
| 1561 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there
is no | |
| 1562 * content and the attributes ended with [TokenType#SLASH_GT]. | |
| 1563 * | |
| 1564 * | |
| 1565 * @return the token (not `null`) | |
| 1566 */ | |
| 1567 Token get contentEnd => _contentEnd; | |
| 1568 Token get endToken { | 1404 Token get endToken { |
| 1569 if (_nodeEnd != null) { | 1405 if (nodeEnd != null) { |
| 1570 return _nodeEnd; | 1406 return nodeEnd; |
| 1571 } | 1407 } |
| 1572 if (_closingTag != null) { | 1408 if (closingTag != null) { |
| 1573 return _closingTag; | 1409 return closingTag; |
| 1574 } | 1410 } |
| 1575 if (_contentEnd != null) { | 1411 if (contentEnd != null) { |
| 1576 return _contentEnd; | 1412 return contentEnd; |
| 1577 } | 1413 } |
| 1578 if (!_tagNodes.isEmpty) { | 1414 if (!tagNodes.isEmpty) { |
| 1579 return _tagNodes[_tagNodes.length - 1].endToken; | 1415 return tagNodes[tagNodes.length - 1].endToken; |
| 1580 } | 1416 } |
| 1581 if (_attributeEnd != null) { | 1417 if (attributeEnd != null) { |
| 1582 return _attributeEnd; | 1418 return attributeEnd; |
| 1583 } | 1419 } |
| 1584 if (!_attributes.isEmpty) { | 1420 if (!attributes.isEmpty) { |
| 1585 return _attributes[_attributes.length - 1].endToken; | 1421 return attributes[attributes.length - 1].endToken; |
| 1586 } | 1422 } |
| 1587 return _tag; | 1423 return tag; |
| 1588 } | 1424 } |
| 1589 | |
| 1590 /** | |
| 1591 * Answer the ending [TokenType#GT] or [TokenType#SLASH_GT] token. | |
| 1592 * | |
| 1593 * @return the token (not `null`) | |
| 1594 */ | |
| 1595 Token get nodeEnd => _nodeEnd; | |
| 1596 | |
| 1597 /** | |
| 1598 * Answer the starting [TokenType#LT] token. | |
| 1599 * | |
| 1600 * @return the token (not `null`) | |
| 1601 */ | |
| 1602 Token get nodeStart => _nodeStart; | |
| 1603 | |
| 1604 /** | |
| 1605 * Answer the [TokenType#TAG] token after the starting '<'. | |
| 1606 * | |
| 1607 * @return the token (not `null`) | |
| 1608 */ | |
| 1609 Token get tag => _tag; | |
| 1610 | |
| 1611 /** | |
| 1612 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list | |
| 1613 * to edit the AST structure. | |
| 1614 * | |
| 1615 * @return the children (not `null`, contains no `null`s) | |
| 1616 */ | |
| 1617 List<XmlTagNode> get tagNodes => _tagNodes; | |
| 1618 void visitChildren(XmlVisitor visitor) { | 1425 void visitChildren(XmlVisitor visitor) { |
| 1619 for (XmlAttributeNode node in _attributes) { | 1426 for (XmlAttributeNode node in attributes) { |
| 1620 node.accept(visitor); | 1427 node.accept(visitor); |
| 1621 } | 1428 } |
| 1622 for (XmlTagNode node in _tagNodes) { | 1429 for (XmlTagNode node in tagNodes) { |
| 1623 node.accept(visitor); | 1430 node.accept(visitor); |
| 1624 } | 1431 } |
| 1625 } | 1432 } |
| 1626 | 1433 |
| 1627 /** | 1434 /** |
| 1628 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt
y | 1435 * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empt
y |
| 1629 */ | 1436 */ |
| 1630 List becomeParentOfEmpty(List children, List ifEmpty) { | 1437 List becomeParentOfEmpty(List children, List ifEmpty) { |
| 1631 if (children != null && children.isEmpty) { | 1438 if (children != null && children.isEmpty) { |
| 1632 return ifEmpty; | 1439 return ifEmpty; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1690 | 1497 |
| 1691 /** | 1498 /** |
| 1692 * The last token in the token stream that was parsed to form this compilation
unit. This token | 1499 * The last token in the token stream that was parsed to form this compilation
unit. This token |
| 1693 * should always have a type of [TokenType.EOF]. | 1500 * should always have a type of [TokenType.EOF]. |
| 1694 */ | 1501 */ |
| 1695 Token _endToken; | 1502 Token _endToken; |
| 1696 | 1503 |
| 1697 /** | 1504 /** |
| 1698 * The tag nodes contained in the receiver (not `null`, contains no `null`s). | 1505 * The tag nodes contained in the receiver (not `null`, contains no `null`s). |
| 1699 */ | 1506 */ |
| 1700 List<XmlTagNode> _tagNodes; | 1507 List<XmlTagNode> tagNodes; |
| 1701 | 1508 |
| 1702 /** | 1509 /** |
| 1703 * The element associated with this HTML unit or `null` if the receiver is not
resolved. | 1510 * The element associated with this HTML unit or `null` if the receiver is not
resolved. |
| 1704 */ | 1511 */ |
| 1705 HtmlElementImpl _element; | 1512 HtmlElementImpl element; |
| 1706 | 1513 |
| 1707 /** | 1514 /** |
| 1708 * Construct a new instance representing the content of an HTML file. | 1515 * Construct a new instance representing the content of an HTML file. |
| 1709 * | 1516 * |
| 1710 * @param beginToken the first token in the file (not `null`) | 1517 * @param beginToken the first token in the file (not `null`) |
| 1711 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) | 1518 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) |
| 1712 * @param endToken the last token in the token stream which should be of type | 1519 * @param endToken the last token in the token stream which should be of type |
| 1713 * [TokenType.EOF] | 1520 * [TokenType.EOF] |
| 1714 */ | 1521 */ |
| 1715 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { | 1522 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { |
| 1716 this._beginToken = beginToken; | 1523 this._beginToken = beginToken; |
| 1717 this._tagNodes = becomeParentOf(tagNodes); | 1524 this.tagNodes = becomeParentOf(tagNodes); |
| 1718 this._endToken = endToken; | 1525 this._endToken = endToken; |
| 1719 } | 1526 } |
| 1720 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); | 1527 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); |
| 1721 Token get beginToken => _beginToken; | 1528 Token get beginToken => _beginToken; |
| 1722 | |
| 1723 /** | |
| 1724 * Return the element associated with this HTML unit. | |
| 1725 * | |
| 1726 * @return the element or `null` if the receiver is not resolved | |
| 1727 */ | |
| 1728 HtmlElementImpl get element => _element; | |
| 1729 Token get endToken => _endToken; | 1529 Token get endToken => _endToken; |
| 1730 | |
| 1731 /** | |
| 1732 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list | |
| 1733 * to edit the AST structure. | |
| 1734 * | |
| 1735 * @return the children (not `null`, contains no `null`s) | |
| 1736 */ | |
| 1737 List<XmlTagNode> get tagNodes => _tagNodes; | |
| 1738 | |
| 1739 /** | |
| 1740 * Set the element associated with this HTML unit. | |
| 1741 * | |
| 1742 * @param element the element | |
| 1743 */ | |
| 1744 void set element(HtmlElementImpl element2) { | |
| 1745 this._element = element2; | |
| 1746 } | |
| 1747 void visitChildren(XmlVisitor visitor) { | 1530 void visitChildren(XmlVisitor visitor) { |
| 1748 for (XmlTagNode node in _tagNodes) { | 1531 for (XmlTagNode node in tagNodes) { |
| 1749 node.accept(visitor); | 1532 node.accept(visitor); |
| 1750 } | 1533 } |
| 1751 } | 1534 } |
| 1752 } | 1535 } |
| OLD | NEW |