| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.html; | 8 library engine.html; |
| 9 | 9 |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| 11 import 'java_core.dart'; | 11 import 'java_core.dart'; |
| 12 import 'java_engine.dart'; | 12 import 'java_engine.dart'; |
| 13 import 'source.dart'; | 13 import 'source.dart'; |
| 14 import 'error.dart' show AnalysisErrorListener; | 14 import 'error.dart' show AnalysisErrorListener; |
| 15 import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token; | 15 import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token; |
| 16 import 'parser.dart' show Parser; | 16 import 'parser.dart' show Parser; |
| 17 import 'ast.dart'; | 17 import 'ast.dart'; |
| 18 import 'element.dart'; | 18 import 'element.dart'; |
| 19 import 'engine.dart' show AnalysisEngine, AngularHtmlUnitResolver, ExpressionVis
itor; | 19 import 'engine.dart' show AnalysisEngine, AngularHtmlUnitResolver, ExpressionVis
itor; |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * Instances of the class `Token` represent a token that was scanned from the in
put. Each | 22 * Instances of the class `Token` represent a token that was scanned from the in
put. Each |
| 23 * token knows which token follows it, acting as the head of a linked list of to
kens. | 23 * token knows which token follows it, acting as the head of a linked list of to
kens. |
| 24 */ | 24 */ |
| 25 class Token { | 25 class Token { |
| 26 /** | 26 /** |
| 27 * The offset from the beginning of the file to the first character in the tok
en. | 27 * The offset from the beginning of the file to the first character in the tok
en. |
| 28 */ | 28 */ |
| 29 int _offset = 0; | 29 final int offset; |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * The previous token in the token stream. | 32 * The previous token in the token stream. |
| 33 */ | 33 */ |
| 34 Token previous; | 34 Token previous; |
| 35 | 35 |
| 36 /** | 36 /** |
| 37 * The next token in the token stream. | 37 * The next token in the token stream. |
| 38 */ | 38 */ |
| 39 Token _next; | 39 Token _next; |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * The type of the token. | 42 * The type of the token. |
| 43 */ | 43 */ |
| 44 TokenType _type; | 44 final TokenType type; |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * The lexeme represented by this token. | 47 * The lexeme represented by this token. |
| 48 */ | 48 */ |
| 49 String _value; | 49 String _value; |
| 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 */ | 56 */ |
| 57 Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme); | 57 Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme); |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * Initialize a newly created token. | 60 * Initialize a newly created token. |
| 61 * | 61 * |
| 62 * @param type the token type (not `null`) | 62 * @param type the token type (not `null`) |
| 63 * @param offset the offset from the beginning of the file to the first charac
ter in the token | 63 * @param offset the offset from the beginning of the file to the first charac
ter in the token |
| 64 * @param value the lexeme represented by this token (not `null`) | 64 * @param value the lexeme represented by this token (not `null`) |
| 65 */ | 65 */ |
| 66 Token.con2(TokenType type, int offset, String value) { | 66 Token.con2(this.type, this.offset, String value) { |
| 67 this._type = type; | |
| 68 this._value = StringUtilities.intern(value); | 67 this._value = StringUtilities.intern(value); |
| 69 this._offset = offset; | |
| 70 } | 68 } |
| 71 | 69 |
| 72 /** | 70 /** |
| 73 * Return the offset from the beginning of the file to the character after las
t character of the | 71 * Return the offset from the beginning of the file to the character after las
t character of the |
| 74 * token. | 72 * token. |
| 75 * | 73 * |
| 76 * @return the offset from the beginning of the file to the first character af
ter last character | 74 * @return the offset from the beginning of the file to the first character af
ter last character |
| 77 * of the token | 75 * of the token |
| 78 */ | 76 */ |
| 79 int get end => _offset + length; | 77 int get end => offset + length; |
| 80 | 78 |
| 81 /** | 79 /** |
| 82 * Return the number of characters in the node's source range. | 80 * Return the number of characters in the node's source range. |
| 83 * | 81 * |
| 84 * @return the number of characters in the node's source range | 82 * @return the number of characters in the node's source range |
| 85 */ | 83 */ |
| 86 int get length => lexeme.length; | 84 int get length => lexeme.length; |
| 87 | 85 |
| 88 /** | 86 /** |
| 89 * Return the lexeme that represents this token. | 87 * Return the lexeme that represents this token. |
| 90 * | 88 * |
| 91 * @return the lexeme (not `null`) | 89 * @return the lexeme (not `null`) |
| 92 */ | 90 */ |
| 93 String get lexeme => _value; | 91 String get lexeme => _value; |
| 94 | 92 |
| 95 /** | 93 /** |
| 96 * Return the next token in the token stream. | 94 * Return the next token in the token stream. |
| 97 * | 95 * |
| 98 * @return the next token in the token stream | 96 * @return the next token in the token stream |
| 99 */ | 97 */ |
| 100 Token get next => _next; | 98 Token get next => _next; |
| 101 | 99 |
| 102 /** | 100 /** |
| 103 * Return the offset from the beginning of the file to the first character in
the token. | |
| 104 * | |
| 105 * @return the offset from the beginning of the file to the first character in
the token | |
| 106 */ | |
| 107 int get offset => _offset; | |
| 108 | |
| 109 /** | |
| 110 * Answer the token type for the receiver. | |
| 111 * | |
| 112 * @return the token type (not `null`) | |
| 113 */ | |
| 114 TokenType get type => _type; | |
| 115 | |
| 116 /** | |
| 117 * Return `true` if this token is a synthetic token. A synthetic token is a to
ken that was | 101 * Return `true` if this token is a synthetic token. A synthetic token is a to
ken that was |
| 118 * introduced by the parser in order to recover from an error in the code. Syn
thetic tokens always | 102 * introduced by the parser in order to recover from an error in the code. Syn
thetic tokens always |
| 119 * have a length of zero (`0`). | 103 * have a length of zero (`0`). |
| 120 * | 104 * |
| 121 * @return `true` if this token is a synthetic token | 105 * @return `true` if this token is a synthetic token |
| 122 */ | 106 */ |
| 123 bool get isSynthetic => length == 0; | 107 bool get isSynthetic => length == 0; |
| 124 | 108 |
| 125 /** | 109 /** |
| 126 * Set the next token in the token stream to the given token. This has the sid
e-effect of setting | 110 * Set the next token in the token stream to the given token. This has the sid
e-effect of setting |
| (...skipping 10 matching lines...) Expand all Loading... |
| 137 | 121 |
| 138 @override | 122 @override |
| 139 String toString() => lexeme; | 123 String toString() => lexeme; |
| 140 } | 124 } |
| 141 | 125 |
| 142 /** | 126 /** |
| 143 * Implementation of [XmlExpression] for an [Expression] embedded without any wr
apping | 127 * Implementation of [XmlExpression] for an [Expression] embedded without any wr
apping |
| 144 * characters. | 128 * characters. |
| 145 */ | 129 */ |
| 146 class RawXmlExpression extends XmlExpression { | 130 class RawXmlExpression extends XmlExpression { |
| 147 Expression expression; | 131 final Expression expression; |
| 148 | 132 |
| 149 RawXmlExpression(Expression expression) { | 133 RawXmlExpression(this.expression); |
| 150 this.expression = expression; | |
| 151 } | |
| 152 | 134 |
| 153 @override | 135 @override |
| 154 int get end => expression.end; | 136 int get end => expression.end; |
| 155 | 137 |
| 156 @override | 138 @override |
| 157 int get length => expression.length; | 139 int get length => expression.length; |
| 158 | 140 |
| 159 @override | 141 @override |
| 160 int get offset => expression.offset; | 142 int get offset => expression.offset; |
| 161 | 143 |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 } | 596 } |
| 615 | 597 |
| 616 /** | 598 /** |
| 617 * This method exists for debugging purposes only. | 599 * This method exists for debugging purposes only. |
| 618 */ | 600 */ |
| 619 String _buildRecursiveStructureMessage(XmlNode newParent) { | 601 String _buildRecursiveStructureMessage(XmlNode newParent) { |
| 620 JavaStringBuilder builder = new JavaStringBuilder(); | 602 JavaStringBuilder builder = new JavaStringBuilder(); |
| 621 builder.append("Attempt to create recursive structure: "); | 603 builder.append("Attempt to create recursive structure: "); |
| 622 XmlNode current = newParent; | 604 XmlNode current = newParent; |
| 623 while (current != null) { | 605 while (current != null) { |
| 624 if (current != newParent) { | 606 if (!identical(current, newParent)) { |
| 625 builder.append(" -> "); | 607 builder.append(" -> "); |
| 626 } | 608 } |
| 627 if (identical(current, this)) { | 609 if (identical(current, this)) { |
| 628 builder.appendChar(0x2A); | 610 builder.appendChar(0x2A); |
| 629 _appendIdentifier(builder, current); | 611 _appendIdentifier(builder, current); |
| 630 builder.appendChar(0x2A); | 612 builder.appendChar(0x2A); |
| 631 } else { | 613 } else { |
| 632 _appendIdentifier(builder, current); | 614 _appendIdentifier(builder, current); |
| 633 } | 615 } |
| 634 current = current.parent; | 616 current = current.parent; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 /** | 659 /** |
| 678 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc
lasses are | 660 * The abstract class `AbstractScanner` implements a scanner for HTML code. Subc
lasses are |
| 679 * required to implement the interface used to access the characters being scann
ed. | 661 * required to implement the interface used to access the characters being scann
ed. |
| 680 */ | 662 */ |
| 681 abstract class AbstractScanner { | 663 abstract class AbstractScanner { |
| 682 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; | 664 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; |
| 683 | 665 |
| 684 /** | 666 /** |
| 685 * The source being scanned. | 667 * The source being scanned. |
| 686 */ | 668 */ |
| 687 Source source; | 669 final Source source; |
| 688 | 670 |
| 689 /** | 671 /** |
| 690 * The token pointing to the head of the linked list of tokens. | 672 * The token pointing to the head of the linked list of tokens. |
| 691 */ | 673 */ |
| 692 Token _tokens; | 674 Token _tokens; |
| 693 | 675 |
| 694 /** | 676 /** |
| 695 * The last token that was scanned. | 677 * The last token that was scanned. |
| 696 */ | 678 */ |
| 697 Token _tail; | 679 Token _tail; |
| 698 | 680 |
| 699 /** | 681 /** |
| 700 * A list containing the offsets of the first character of each line in the so
urce code. | 682 * A list containing the offsets of the first character of each line in the so
urce code. |
| 701 */ | 683 */ |
| 702 List<int> _lineStarts = new List<int>(); | 684 List<int> _lineStarts = new List<int>(); |
| 703 | 685 |
| 704 /** | 686 /** |
| 705 * An array of element tags for which the content between tags should be consi
der a single token. | 687 * An array of element tags for which the content between tags should be consi
der a single token. |
| 706 */ | 688 */ |
| 707 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; | 689 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; |
| 708 | 690 |
| 709 /** | 691 /** |
| 710 * Initialize a newly created scanner. | 692 * Initialize a newly created scanner. |
| 711 * | 693 * |
| 712 * @param source the source being scanned | 694 * @param source the source being scanned |
| 713 */ | 695 */ |
| 714 AbstractScanner(Source source) { | 696 AbstractScanner(this.source) { |
| 715 this.source = source; | |
| 716 _tokens = new Token.con1(TokenType.EOF, -1); | 697 _tokens = new Token.con1(TokenType.EOF, -1); |
| 717 _tokens.setNext(_tokens); | 698 _tokens.setNext(_tokens); |
| 718 _tail = _tokens; | 699 _tail = _tokens; |
| 719 recordStartOfLine(); | 700 recordStartOfLine(); |
| 720 } | 701 } |
| 721 | 702 |
| 722 /** | 703 /** |
| 723 * Return an array containing the offsets of the first character of each line
in the source code. | 704 * Return an array containing the offsets of the first character of each line
in the source code. |
| 724 * | 705 * |
| 725 * @return an array containing the offsets of the first character of each line
in the source code | 706 * @return an array containing the offsets of the first character of each line
in the source code |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 } | 976 } |
| 996 | 977 |
| 997 /** | 978 /** |
| 998 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The | 979 * Instances of the class `StringScanner` implement a scanner that reads from a
string. The |
| 999 * scanning logic is in the superclass. | 980 * scanning logic is in the superclass. |
| 1000 */ | 981 */ |
| 1001 class StringScanner extends AbstractScanner { | 982 class StringScanner extends AbstractScanner { |
| 1002 /** | 983 /** |
| 1003 * The string from which characters will be read. | 984 * The string from which characters will be read. |
| 1004 */ | 985 */ |
| 1005 String _string; | 986 final String _string; |
| 1006 | 987 |
| 1007 /** | 988 /** |
| 1008 * The number of characters in the string. | 989 * The number of characters in the string. |
| 1009 */ | 990 */ |
| 1010 int _stringLength = 0; | 991 int _stringLength = 0; |
| 1011 | 992 |
| 1012 /** | 993 /** |
| 1013 * The index, relative to the string, of the last character that was read. | 994 * The index, relative to the string, of the last character that was read. |
| 1014 */ | 995 */ |
| 1015 int _charOffset = 0; | 996 int _charOffset = 0; |
| 1016 | 997 |
| 1017 /** | 998 /** |
| 1018 * Initialize a newly created scanner to scan the characters in the given stri
ng. | 999 * Initialize a newly created scanner to scan the characters in the given stri
ng. |
| 1019 * | 1000 * |
| 1020 * @param source the source being scanned | 1001 * @param source the source being scanned |
| 1021 * @param string the string from which characters will be read | 1002 * @param string the string from which characters will be read |
| 1022 */ | 1003 */ |
| 1023 StringScanner(Source source, String string) : super(source) { | 1004 StringScanner(Source source, this._string) : super(source) { |
| 1024 this._string = string; | 1005 this._stringLength = _string.length; |
| 1025 this._stringLength = string.length; | |
| 1026 this._charOffset = -1; | 1006 this._charOffset = -1; |
| 1027 } | 1007 } |
| 1028 | 1008 |
| 1029 @override | 1009 @override |
| 1030 int get offset => _charOffset; | 1010 int get offset => _charOffset; |
| 1031 | 1011 |
| 1032 void set offset(int offset) { | 1012 void set offset(int offset) { |
| 1033 _charOffset = offset; | 1013 _charOffset = offset; |
| 1034 } | 1014 } |
| 1035 | 1015 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1055 } | 1035 } |
| 1056 | 1036 |
| 1057 /** | 1037 /** |
| 1058 * Instances of the class `ToSourceVisitor` write a source representation of a v
isited XML | 1038 * Instances of the class `ToSourceVisitor` write a source representation of a v
isited XML |
| 1059 * node (and all of it's children) to a writer. | 1039 * node (and all of it's children) to a writer. |
| 1060 */ | 1040 */ |
| 1061 class ToSourceVisitor implements XmlVisitor<Object> { | 1041 class ToSourceVisitor implements XmlVisitor<Object> { |
| 1062 /** | 1042 /** |
| 1063 * The writer to which the source is to be written. | 1043 * The writer to which the source is to be written. |
| 1064 */ | 1044 */ |
| 1065 PrintWriter _writer; | 1045 final PrintWriter _writer; |
| 1066 | 1046 |
| 1067 /** | 1047 /** |
| 1068 * Initialize a newly created visitor to write source code representing the vi
sited nodes to the | 1048 * Initialize a newly created visitor to write source code representing the vi
sited nodes to the |
| 1069 * given writer. | 1049 * given writer. |
| 1070 * | 1050 * |
| 1071 * @param writer the writer to which the source is to be written | 1051 * @param writer the writer to which the source is to be written |
| 1072 */ | 1052 */ |
| 1073 ToSourceVisitor(PrintWriter writer) { | 1053 ToSourceVisitor(this._writer); |
| 1074 this._writer = writer; | |
| 1075 } | |
| 1076 | 1054 |
| 1077 @override | 1055 @override |
| 1078 Object visitHtmlScriptTagNode(HtmlScriptTagNode node) => visitXmlTagNode(node)
; | 1056 Object visitHtmlScriptTagNode(HtmlScriptTagNode node) => visitXmlTagNode(node)
; |
| 1079 | 1057 |
| 1080 @override | 1058 @override |
| 1081 Object visitHtmlUnit(HtmlUnit node) { | 1059 Object visitHtmlUnit(HtmlUnit node) { |
| 1082 for (XmlTagNode child in node.tagNodes) { | 1060 for (XmlTagNode child in node.tagNodes) { |
| 1083 _visit(child); | 1061 _visit(child); |
| 1084 } | 1062 } |
| 1085 return null; | 1063 return null; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 } | 1115 } |
| 1138 | 1116 |
| 1139 /** | 1117 /** |
| 1140 * The enumeration `TokenType` defines the types of tokens that can be returned
by the | 1118 * The enumeration `TokenType` defines the types of tokens that can be returned
by the |
| 1141 * scanner. | 1119 * scanner. |
| 1142 */ | 1120 */ |
| 1143 class TokenType extends Enum<TokenType> { | 1121 class TokenType extends Enum<TokenType> { |
| 1144 /** | 1122 /** |
| 1145 * The type of the token that marks the end of the input. | 1123 * The type of the token that marks the end of the input. |
| 1146 */ | 1124 */ |
| 1147 static final TokenType EOF = new TokenType_EOF('EOF', 0, ""); | 1125 static const TokenType EOF = const TokenType_EOF('EOF', 0, ""); |
| 1148 | 1126 |
| 1149 static final TokenType EQ = new TokenType('EQ', 1, "="); | 1127 static const TokenType EQ = const TokenType('EQ', 1, "="); |
| 1150 | 1128 |
| 1151 static final TokenType GT = new TokenType('GT', 2, ">"); | 1129 static const TokenType GT = const TokenType('GT', 2, ">"); |
| 1152 | 1130 |
| 1153 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</"); | 1131 static const TokenType LT_SLASH = const TokenType('LT_SLASH', 3, "</"); |
| 1154 | 1132 |
| 1155 static final TokenType LT = new TokenType('LT', 4, "<"); | 1133 static const TokenType LT = const TokenType('LT', 4, "<"); |
| 1156 | 1134 |
| 1157 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>"); | 1135 static const TokenType SLASH_GT = const TokenType('SLASH_GT', 5, "/>"); |
| 1158 | 1136 |
| 1159 static final TokenType COMMENT = new TokenType('COMMENT', 6, null); | 1137 static const TokenType COMMENT = const TokenType('COMMENT', 6, null); |
| 1160 | 1138 |
| 1161 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null); | 1139 static const TokenType DECLARATION = const TokenType('DECLARATION', 7, null); |
| 1162 | 1140 |
| 1163 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null); | 1141 static const TokenType DIRECTIVE = const TokenType('DIRECTIVE', 8, null); |
| 1164 | 1142 |
| 1165 static final TokenType STRING = new TokenType('STRING', 9, null); | 1143 static const TokenType STRING = const TokenType('STRING', 9, null); |
| 1166 | 1144 |
| 1167 static final TokenType TAG = new TokenType('TAG', 10, null); | 1145 static const TokenType TAG = const TokenType('TAG', 10, null); |
| 1168 | 1146 |
| 1169 static final TokenType TEXT = new TokenType('TEXT', 11, null); | 1147 static const TokenType TEXT = const TokenType('TEXT', 11, null); |
| 1170 | 1148 |
| 1171 static final List<TokenType> values = [ | 1149 static const List<TokenType> values = const [ |
| 1172 EOF, | 1150 EOF, |
| 1173 EQ, | 1151 EQ, |
| 1174 GT, | 1152 GT, |
| 1175 LT_SLASH, | 1153 LT_SLASH, |
| 1176 LT, | 1154 LT, |
| 1177 SLASH_GT, | 1155 SLASH_GT, |
| 1178 COMMENT, | 1156 COMMENT, |
| 1179 DECLARATION, | 1157 DECLARATION, |
| 1180 DIRECTIVE, | 1158 DIRECTIVE, |
| 1181 STRING, | 1159 STRING, |
| 1182 TAG, | 1160 TAG, |
| 1183 TEXT]; | 1161 TEXT]; |
| 1184 | 1162 |
| 1185 /** | 1163 /** |
| 1186 * The lexeme that defines this type of token, or `null` if there is more than
one possible | 1164 * The lexeme that defines this type of token, or `null` if there is more than
one possible |
| 1187 * lexeme for this type of token. | 1165 * lexeme for this type of token. |
| 1188 */ | 1166 */ |
| 1189 String lexeme; | 1167 final String lexeme; |
| 1190 | 1168 |
| 1191 TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) { | 1169 const TokenType(String name, int ordinal, this.lexeme) : super(name, ordinal); |
| 1192 this.lexeme = lexeme; | |
| 1193 } | |
| 1194 } | 1170 } |
| 1195 | 1171 |
| 1196 class TokenType_EOF extends TokenType { | 1172 class TokenType_EOF extends TokenType { |
| 1197 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar
g0); | 1173 const TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordin
al, arg0); |
| 1198 | 1174 |
| 1199 @override | 1175 @override |
| 1200 String toString() => "-eof-"; | 1176 String toString() => "-eof-"; |
| 1201 } | 1177 } |
| 1202 | 1178 |
| 1203 /** | 1179 /** |
| 1204 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. | 1180 * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTa
gNode]. |
| 1205 */ | 1181 */ |
| 1206 class XmlAttributeNode extends XmlNode { | 1182 class XmlAttributeNode extends XmlNode { |
| 1207 Token _name; | 1183 final Token _name; |
| 1208 | 1184 |
| 1209 Token equals; | 1185 final Token equals; |
| 1210 | 1186 |
| 1211 Token _value; | 1187 final Token _value; |
| 1212 | 1188 |
| 1213 List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY; | 1189 List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY; |
| 1214 | 1190 |
| 1215 /** | 1191 /** |
| 1216 * Construct a new instance representing an XML attribute. | 1192 * Construct a new instance representing an XML attribute. |
| 1217 * | 1193 * |
| 1218 * @param name the name token (not `null`). This may be a zero length token if
the attribute | 1194 * @param name the name token (not `null`). This may be a zero length token if
the attribute |
| 1219 * is badly formed. | 1195 * is badly formed. |
| 1220 * @param equals the equals sign or `null` if none | 1196 * @param equals the equals sign or `null` if none |
| 1221 * @param value the value token (not `null`) | 1197 * @param value the value token (not `null`) |
| 1222 */ | 1198 */ |
| 1223 XmlAttributeNode(Token name, Token equals, Token value) { | 1199 XmlAttributeNode(this._name, this.equals, this._value); |
| 1224 this._name = name; | |
| 1225 this.equals = equals; | |
| 1226 this._value = value; | |
| 1227 } | |
| 1228 | 1200 |
| 1229 @override | 1201 @override |
| 1230 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); | 1202 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); |
| 1231 | 1203 |
| 1232 @override | 1204 @override |
| 1233 Token get beginToken => _name; | 1205 Token get beginToken => _name; |
| 1234 | 1206 |
| 1235 @override | 1207 @override |
| 1236 Token get endToken => _value; | 1208 Token get endToken => _value; |
| 1237 | 1209 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 } | 1339 } |
| 1368 | 1340 |
| 1369 /** | 1341 /** |
| 1370 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised | 1342 * Instances of the class `XmlParser` are used to parse tokens into a AST struct
ure comprised |
| 1371 * of [XmlNode]s. | 1343 * of [XmlNode]s. |
| 1372 */ | 1344 */ |
| 1373 class XmlParser { | 1345 class XmlParser { |
| 1374 /** | 1346 /** |
| 1375 * The source being parsed. | 1347 * The source being parsed. |
| 1376 */ | 1348 */ |
| 1377 Source source; | 1349 final Source source; |
| 1378 | 1350 |
| 1379 /** | 1351 /** |
| 1380 * The next token to be parsed. | 1352 * The next token to be parsed. |
| 1381 */ | 1353 */ |
| 1382 Token _currentToken; | 1354 Token _currentToken; |
| 1383 | 1355 |
| 1384 /** | 1356 /** |
| 1385 * Construct a parser for the specified source. | 1357 * Construct a parser for the specified source. |
| 1386 * | 1358 * |
| 1387 * @param source the source being parsed | 1359 * @param source the source being parsed |
| 1388 */ | 1360 */ |
| 1389 XmlParser(Source source) { | 1361 XmlParser(this.source); |
| 1390 this.source = source; | |
| 1391 } | |
| 1392 | 1362 |
| 1393 /** | 1363 /** |
| 1394 * Create a node representing an attribute. | 1364 * Create a node representing an attribute. |
| 1395 * | 1365 * |
| 1396 * @param name the name of the attribute | 1366 * @param name the name of the attribute |
| 1397 * @param equals the equals sign, or `null` if there is no value | 1367 * @param equals the equals sign, or `null` if there is no value |
| 1398 * @param value the value of the attribute | 1368 * @param value the value of the attribute |
| 1399 * @return the node that was created | 1369 * @return the node that was created |
| 1400 */ | 1370 */ |
| 1401 XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
new XmlAttributeNode(name, equals, value); | 1371 XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
new XmlAttributeNode(name, equals, value); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1428 * Parse the entire token stream and in the process, advance the current token
to the end of the | 1398 * Parse the entire token stream and in the process, advance the current token
to the end of the |
| 1429 * token stream. | 1399 * token stream. |
| 1430 * | 1400 * |
| 1431 * @return the list of tag nodes found (not `null`, contains no `null`) | 1401 * @return the list of tag nodes found (not `null`, contains no `null`) |
| 1432 */ | 1402 */ |
| 1433 List<XmlTagNode> parseTopTagNodes(Token firstToken) { | 1403 List<XmlTagNode> parseTopTagNodes(Token firstToken) { |
| 1434 _currentToken = firstToken; | 1404 _currentToken = firstToken; |
| 1435 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); | 1405 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); |
| 1436 TokenType type = _currentToken.type; | 1406 TokenType type = _currentToken.type; |
| 1437 while (type != TokenType.EOF) { | 1407 while (type != TokenType.EOF) { |
| 1438 if (identical(type, TokenType.LT)) { | 1408 if (type == TokenType.LT) { |
| 1439 tagNodes.add(_parseTagNode()); | 1409 tagNodes.add(_parseTagNode()); |
| 1440 } else if (identical(type, TokenType.DECLARATION) || identical(type, Token
Type.DIRECTIVE) || identical(type, TokenType.COMMENT)) { | 1410 } else if (type == TokenType.DECLARATION || type == TokenType.DIRECTIVE ||
type == TokenType.COMMENT) { |
| 1441 // ignored tokens | 1411 // ignored tokens |
| 1442 _currentToken = _currentToken.next; | 1412 _currentToken = _currentToken.next; |
| 1443 } else { | 1413 } else { |
| 1444 _reportUnexpectedToken(); | 1414 _reportUnexpectedToken(); |
| 1445 _currentToken = _currentToken.next; | 1415 _currentToken = _currentToken.next; |
| 1446 } | 1416 } |
| 1447 type = _currentToken.type; | 1417 type = _currentToken.type; |
| 1448 } | 1418 } |
| 1449 return tagNodes; | 1419 return tagNodes; |
| 1450 } | 1420 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1474 * attribute, but should not be called if the [currentToken] is not [TokenType
#TAG]. | 1444 * attribute, but should not be called if the [currentToken] is not [TokenType
#TAG]. |
| 1475 * | 1445 * |
| 1476 * @return the attribute (not `null`) | 1446 * @return the attribute (not `null`) |
| 1477 */ | 1447 */ |
| 1478 XmlAttributeNode _parseAttribute() { | 1448 XmlAttributeNode _parseAttribute() { |
| 1479 // Assume the current token is a tag | 1449 // Assume the current token is a tag |
| 1480 Token name = _currentToken; | 1450 Token name = _currentToken; |
| 1481 _currentToken = _currentToken.next; | 1451 _currentToken = _currentToken.next; |
| 1482 // Equals sign | 1452 // Equals sign |
| 1483 Token equals; | 1453 Token equals; |
| 1484 if (identical(_currentToken.type, TokenType.EQ)) { | 1454 if (_currentToken.type == TokenType.EQ) { |
| 1485 equals = _currentToken; | 1455 equals = _currentToken; |
| 1486 _currentToken = _currentToken.next; | 1456 _currentToken = _currentToken.next; |
| 1487 } else { | 1457 } else { |
| 1488 _reportUnexpectedToken(); | 1458 _reportUnexpectedToken(); |
| 1489 equals = _insertSyntheticToken(TokenType.EQ); | 1459 equals = _insertSyntheticToken(TokenType.EQ); |
| 1490 } | 1460 } |
| 1491 // String value | 1461 // String value |
| 1492 Token value; | 1462 Token value; |
| 1493 if (identical(_currentToken.type, TokenType.STRING)) { | 1463 if (_currentToken.type == TokenType.STRING) { |
| 1494 value = _currentToken; | 1464 value = _currentToken; |
| 1495 _currentToken = _currentToken.next; | 1465 _currentToken = _currentToken.next; |
| 1496 } else { | 1466 } else { |
| 1497 _reportUnexpectedToken(); | 1467 _reportUnexpectedToken(); |
| 1498 value = _insertSyntheticToken(TokenType.STRING); | 1468 value = _insertSyntheticToken(TokenType.STRING); |
| 1499 } | 1469 } |
| 1500 return createAttributeNode(name, equals, value); | 1470 return createAttributeNode(name, equals, value); |
| 1501 } | 1471 } |
| 1502 | 1472 |
| 1503 /** | 1473 /** |
| 1504 * Parse the stream for a sequence of attributes. This method advances the cur
rent token to the | 1474 * Parse the stream for a sequence of attributes. This method advances the cur
rent token to the |
| 1505 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF]. | 1475 * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF]. |
| 1506 * | 1476 * |
| 1507 * @return a collection of zero or more attributes (not `null`, contains no `n
ull`s) | 1477 * @return a collection of zero or more attributes (not `null`, contains no `n
ull`s) |
| 1508 */ | 1478 */ |
| 1509 List<XmlAttributeNode> _parseAttributes() { | 1479 List<XmlAttributeNode> _parseAttributes() { |
| 1510 TokenType type = _currentToken.type; | 1480 TokenType type = _currentToken.type; |
| 1511 if (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) ||
identical(type, TokenType.EOF)) { | 1481 if (type == TokenType.GT || type == TokenType.SLASH_GT || type == TokenType.
EOF) { |
| 1512 return XmlTagNode.NO_ATTRIBUTES; | 1482 return XmlTagNode.NO_ATTRIBUTES; |
| 1513 } | 1483 } |
| 1514 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); | 1484 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); |
| 1515 while (type != TokenType.GT && type != TokenType.SLASH_GT && type != TokenTy
pe.EOF) { | 1485 while (type != TokenType.GT && type != TokenType.SLASH_GT && type != TokenTy
pe.EOF) { |
| 1516 if (identical(type, TokenType.TAG)) { | 1486 if (type == TokenType.TAG) { |
| 1517 attributes.add(_parseAttribute()); | 1487 attributes.add(_parseAttribute()); |
| 1518 } else { | 1488 } else { |
| 1519 _reportUnexpectedToken(); | 1489 _reportUnexpectedToken(); |
| 1520 _currentToken = _currentToken.next; | 1490 _currentToken = _currentToken.next; |
| 1521 } | 1491 } |
| 1522 type = _currentToken.type; | 1492 type = _currentToken.type; |
| 1523 } | 1493 } |
| 1524 return attributes; | 1494 return attributes; |
| 1525 } | 1495 } |
| 1526 | 1496 |
| 1527 /** | 1497 /** |
| 1528 * Parse the stream for a sequence of tag nodes existing within a parent tag n
ode. This method | 1498 * Parse the stream for a sequence of tag nodes existing within a parent tag n
ode. This method |
| 1529 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E
OF]. | 1499 * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#E
OF]. |
| 1530 * | 1500 * |
| 1531 * @return a list of nodes (not `null`, contains no `null`s) | 1501 * @return a list of nodes (not `null`, contains no `null`s) |
| 1532 */ | 1502 */ |
| 1533 List<XmlTagNode> _parseChildTagNodes() { | 1503 List<XmlTagNode> _parseChildTagNodes() { |
| 1534 TokenType type = _currentToken.type; | 1504 TokenType type = _currentToken.type; |
| 1535 if (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) { | 1505 if (type == TokenType.LT_SLASH || type == TokenType.EOF) { |
| 1536 return XmlTagNode.NO_TAG_NODES; | 1506 return XmlTagNode.NO_TAG_NODES; |
| 1537 } | 1507 } |
| 1538 List<XmlTagNode> nodes = new List<XmlTagNode>(); | 1508 List<XmlTagNode> nodes = new List<XmlTagNode>(); |
| 1539 while (type != TokenType.LT_SLASH && type != TokenType.EOF) { | 1509 while (type != TokenType.LT_SLASH && type != TokenType.EOF) { |
| 1540 if (identical(type, TokenType.LT)) { | 1510 if (type == TokenType.LT) { |
| 1541 nodes.add(_parseTagNode()); | 1511 nodes.add(_parseTagNode()); |
| 1542 } else if (identical(type, TokenType.COMMENT)) { | 1512 } else if (type == TokenType.COMMENT) { |
| 1543 // ignored token | 1513 // ignored token |
| 1544 _currentToken = _currentToken.next; | 1514 _currentToken = _currentToken.next; |
| 1545 } else { | 1515 } else { |
| 1546 _reportUnexpectedToken(); | 1516 _reportUnexpectedToken(); |
| 1547 _currentToken = _currentToken.next; | 1517 _currentToken = _currentToken.next; |
| 1548 } | 1518 } |
| 1549 type = _currentToken.type; | 1519 type = _currentToken.type; |
| 1550 } | 1520 } |
| 1551 return nodes; | 1521 return nodes; |
| 1552 } | 1522 } |
| 1553 | 1523 |
| 1554 /** | 1524 /** |
| 1555 * Parse the token stream for the next tag node. This method advances current
token over the | 1525 * Parse the token stream for the next tag node. This method advances current
token over the |
| 1556 * parsed tag node, but should only be called if the current token is [TokenTy
pe#LT] | 1526 * parsed tag node, but should only be called if the current token is [TokenTy
pe#LT] |
| 1557 * | 1527 * |
| 1558 * @return the tag node or `null` if none found | 1528 * @return the tag node or `null` if none found |
| 1559 */ | 1529 */ |
| 1560 XmlTagNode _parseTagNode() { | 1530 XmlTagNode _parseTagNode() { |
| 1561 // Assume that the current node is a tag node start TokenType#LT | 1531 // Assume that the current node is a tag node start TokenType#LT |
| 1562 Token nodeStart = _currentToken; | 1532 Token nodeStart = _currentToken; |
| 1563 _currentToken = _currentToken.next; | 1533 _currentToken = _currentToken.next; |
| 1564 // Get the tag or create a synthetic tag and report an error | 1534 // Get the tag or create a synthetic tag and report an error |
| 1565 Token tag; | 1535 Token tag; |
| 1566 if (identical(_currentToken.type, TokenType.TAG)) { | 1536 if (_currentToken.type == TokenType.TAG) { |
| 1567 tag = _currentToken; | 1537 tag = _currentToken; |
| 1568 _currentToken = _currentToken.next; | 1538 _currentToken = _currentToken.next; |
| 1569 } else { | 1539 } else { |
| 1570 _reportUnexpectedToken(); | 1540 _reportUnexpectedToken(); |
| 1571 tag = _insertSyntheticToken(TokenType.TAG); | 1541 tag = _insertSyntheticToken(TokenType.TAG); |
| 1572 } | 1542 } |
| 1573 // Parse the attributes | 1543 // Parse the attributes |
| 1574 List<XmlAttributeNode> attributes = _parseAttributes(); | 1544 List<XmlAttributeNode> attributes = _parseAttributes(); |
| 1575 // Token ending attribute list | 1545 // Token ending attribute list |
| 1576 Token attributeEnd; | 1546 Token attributeEnd; |
| 1577 if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.t
ype, TokenType.SLASH_GT)) { | 1547 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenType.SL
ASH_GT) { |
| 1578 attributeEnd = _currentToken; | 1548 attributeEnd = _currentToken; |
| 1579 _currentToken = _currentToken.next; | 1549 _currentToken = _currentToken.next; |
| 1580 } else { | 1550 } else { |
| 1581 _reportUnexpectedToken(); | 1551 _reportUnexpectedToken(); |
| 1582 attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT); | 1552 attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT); |
| 1583 } | 1553 } |
| 1584 // If the node has no children, then return the node | 1554 // If the node has no children, then return the node |
| 1585 if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag))
{ | 1555 if (attributeEnd.type == TokenType.SLASH_GT || isSelfClosing(tag)) { |
| 1586 return createTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.
NO_TAG_NODES, _currentToken, null, attributeEnd); | 1556 return createTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.
NO_TAG_NODES, _currentToken, null, attributeEnd); |
| 1587 } | 1557 } |
| 1588 // Parse the child tag nodes | 1558 // Parse the child tag nodes |
| 1589 List<XmlTagNode> tagNodes = _parseChildTagNodes(); | 1559 List<XmlTagNode> tagNodes = _parseChildTagNodes(); |
| 1590 // Token ending child tag nodes | 1560 // Token ending child tag nodes |
| 1591 Token contentEnd; | 1561 Token contentEnd; |
| 1592 if (identical(_currentToken.type, TokenType.LT_SLASH)) { | 1562 if (_currentToken.type == TokenType.LT_SLASH) { |
| 1593 contentEnd = _currentToken; | 1563 contentEnd = _currentToken; |
| 1594 _currentToken = _currentToken.next; | 1564 _currentToken = _currentToken.next; |
| 1595 } else { | 1565 } else { |
| 1596 // TODO (danrubel): handle self closing HTML elements by inserting synthet
ic tokens | 1566 // TODO (danrubel): handle self closing HTML elements by inserting synthet
ic tokens |
| 1597 // but not reporting an error | 1567 // but not reporting an error |
| 1598 _reportUnexpectedToken(); | 1568 _reportUnexpectedToken(); |
| 1599 contentEnd = _insertSyntheticToken(TokenType.LT_SLASH); | 1569 contentEnd = _insertSyntheticToken(TokenType.LT_SLASH); |
| 1600 } | 1570 } |
| 1601 // Closing tag | 1571 // Closing tag |
| 1602 Token closingTag; | 1572 Token closingTag; |
| 1603 if (identical(_currentToken.type, TokenType.TAG)) { | 1573 if (_currentToken.type == TokenType.TAG) { |
| 1604 closingTag = _currentToken; | 1574 closingTag = _currentToken; |
| 1605 _currentToken = _currentToken.next; | 1575 _currentToken = _currentToken.next; |
| 1606 } else { | 1576 } else { |
| 1607 _reportUnexpectedToken(); | 1577 _reportUnexpectedToken(); |
| 1608 closingTag = _insertSyntheticToken(TokenType.TAG); | 1578 closingTag = _insertSyntheticToken(TokenType.TAG); |
| 1609 } | 1579 } |
| 1610 // Token ending node | 1580 // Token ending node |
| 1611 Token nodeEnd; | 1581 Token nodeEnd; |
| 1612 if (identical(_currentToken.type, TokenType.GT)) { | 1582 if (_currentToken.type == TokenType.GT) { |
| 1613 nodeEnd = _currentToken; | 1583 nodeEnd = _currentToken; |
| 1614 _currentToken = _currentToken.next; | 1584 _currentToken = _currentToken.next; |
| 1615 } else { | 1585 } else { |
| 1616 _reportUnexpectedToken(); | 1586 _reportUnexpectedToken(); |
| 1617 nodeEnd = _insertSyntheticToken(TokenType.GT); | 1587 nodeEnd = _insertSyntheticToken(TokenType.GT); |
| 1618 } | 1588 } |
| 1619 return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, con
tentEnd, closingTag, nodeEnd); | 1589 return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, con
tentEnd, closingTag, nodeEnd); |
| 1620 } | 1590 } |
| 1621 | 1591 |
| 1622 /** | 1592 /** |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1637 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); | 1607 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis
t<XmlAttributeNode>()); |
| 1638 | 1608 |
| 1639 /** | 1609 /** |
| 1640 * Constant representing empty list of tag nodes. | 1610 * Constant representing empty list of tag nodes. |
| 1641 */ | 1611 */ |
| 1642 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); | 1612 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa
gNode>()); |
| 1643 | 1613 |
| 1644 /** | 1614 /** |
| 1645 * The starting [TokenType#LT] token (not `null`). | 1615 * The starting [TokenType#LT] token (not `null`). |
| 1646 */ | 1616 */ |
| 1647 Token nodeStart; | 1617 final Token nodeStart; |
| 1648 | 1618 |
| 1649 /** | 1619 /** |
| 1650 * The [TokenType#TAG] token after the starting '<' (not `null`). | 1620 * The [TokenType#TAG] token after the starting '<' (not `null`). |
| 1651 */ | 1621 */ |
| 1652 Token _tag; | 1622 final Token _tag; |
| 1653 | 1623 |
| 1654 /** | 1624 /** |
| 1655 * The attributes contained by the receiver (not `null`, contains no `null`s). | 1625 * The attributes contained by the receiver (not `null`, contains no `null`s). |
| 1656 */ | 1626 */ |
| 1657 List<XmlAttributeNode> _attributes; | 1627 List<XmlAttributeNode> _attributes; |
| 1658 | 1628 |
| 1659 /** | 1629 /** |
| 1660 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not | 1630 * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not |
| 1661 * `null`). The token may be the same token as [nodeEnd] if there are no child | 1631 * `null`). The token may be the same token as [nodeEnd] if there are no child |
| 1662 * [tagNodes]. | 1632 * [tagNodes]. |
| 1663 */ | 1633 */ |
| 1664 Token attributeEnd; | 1634 final Token attributeEnd; |
| 1665 | 1635 |
| 1666 /** | 1636 /** |
| 1667 * The tag nodes contained in the receiver (not `null`, contains no `null`s). | 1637 * The tag nodes contained in the receiver (not `null`, contains no `null`s). |
| 1668 */ | 1638 */ |
| 1669 List<XmlTagNode> _tagNodes; | 1639 List<XmlTagNode> _tagNodes; |
| 1670 | 1640 |
| 1671 /** | 1641 /** |
| 1672 * The token (not `null`) after the content, which may be | 1642 * The token (not `null`) after the content, which may be |
| 1673 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or | 1643 * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or |
| 1674 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
self | 1644 * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
self |
| 1675 * closing or the attributeEnd is [TokenType#SLASH_GT], or | 1645 * closing or the attributeEnd is [TokenType#SLASH_GT], or |
| 1676 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la
st node in | 1646 * * (3) [TokenType#EOF] if the node does not have a closing tag and is the la
st node in |
| 1677 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there
is no | 1647 * the stream [TokenType#LT_SLASH] token after the content, or `null` if there
is no |
| 1678 * content and the attributes ended with [TokenType#SLASH_GT]. | 1648 * content and the attributes ended with [TokenType#SLASH_GT]. |
| 1679 */ | 1649 */ |
| 1680 Token contentEnd; | 1650 final Token contentEnd; |
| 1681 | 1651 |
| 1682 /** | 1652 /** |
| 1683 * The closing [TokenType#TAG] after the child elements or `null` if there is
no | 1653 * The closing [TokenType#TAG] after the child elements or `null` if there is
no |
| 1684 * content and the attributes ended with [TokenType#SLASH_GT] | 1654 * content and the attributes ended with [TokenType#SLASH_GT] |
| 1685 */ | 1655 */ |
| 1686 Token closingTag; | 1656 final Token closingTag; |
| 1687 | 1657 |
| 1688 /** | 1658 /** |
| 1689 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). | 1659 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). |
| 1690 */ | 1660 */ |
| 1691 Token nodeEnd; | 1661 final Token nodeEnd; |
| 1692 | 1662 |
| 1693 /** | 1663 /** |
| 1694 * The expressions that are embedded in the tag's content. | 1664 * The expressions that are embedded in the tag's content. |
| 1695 */ | 1665 */ |
| 1696 List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY; | 1666 List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY; |
| 1697 | 1667 |
| 1698 /** | 1668 /** |
| 1699 * Construct a new instance representing an XML or HTML element | 1669 * Construct a new instance representing an XML or HTML element |
| 1700 * | 1670 * |
| 1701 * @param nodeStart the starting [TokenType#LT] token (not `null`) | 1671 * @param nodeStart the starting [TokenType#LT] token (not `null`) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1712 * * (2) the [TokenType#LT] nodeStart of the next sibling node if thi
s node is | 1682 * * (2) the [TokenType#LT] nodeStart of the next sibling node if thi
s node is |
| 1713 * self closing or the attributeEnd is [TokenType#SLASH_GT], or | 1683 * self closing or the attributeEnd is [TokenType#SLASH_GT], or |
| 1714 * * (3) [TokenType#EOF] if the node does not have a closing tag and
is the last | 1684 * * (3) [TokenType#EOF] if the node does not have a closing tag and
is the last |
| 1715 * node in the stream [TokenType#LT_SLASH] token after the content, o
r `null` | 1685 * node in the stream [TokenType#LT_SLASH] token after the content, o
r `null` |
| 1716 * if there is no content and the attributes ended with [TokenType#SL
ASH_GT]. | 1686 * if there is no content and the attributes ended with [TokenType#SL
ASH_GT]. |
| 1717 * @param closingTag the closing [TokenType#TAG] after the child elements or `
null` if | 1687 * @param closingTag the closing [TokenType#TAG] after the child elements or `
null` if |
| 1718 * there is no content and the attributes ended with [TokenType#SLASH
_GT] | 1688 * there is no content and the attributes ended with [TokenType#SLASH
_GT] |
| 1719 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not | 1689 * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not |
| 1720 * `null`) | 1690 * `null`) |
| 1721 */ | 1691 */ |
| 1722 XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Toke
n attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, T
oken nodeEnd) { | 1692 XmlTagNode(this.nodeStart, this._tag, List<XmlAttributeNode> attributes, this.
attributeEnd, List<XmlTagNode> tagNodes, this.contentEnd, this.closingTag, this.
nodeEnd) { |
| 1723 this.nodeStart = nodeStart; | |
| 1724 this._tag = tag; | |
| 1725 this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES); | 1693 this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES); |
| 1726 this.attributeEnd = attributeEnd; | |
| 1727 this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES); | 1694 this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES); |
| 1728 this.contentEnd = contentEnd; | |
| 1729 this.closingTag = closingTag; | |
| 1730 this.nodeEnd = nodeEnd; | |
| 1731 } | 1695 } |
| 1732 | 1696 |
| 1733 @override | 1697 @override |
| 1734 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); | 1698 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); |
| 1735 | 1699 |
| 1736 /** | 1700 /** |
| 1737 * Answer the attribute with the specified name. | 1701 * Answer the attribute with the specified name. |
| 1738 * | 1702 * |
| 1739 * @param name the attribute name | 1703 * @param name the attribute name |
| 1740 * @return the attribute or `null` if no matching attribute is found | 1704 * @return the attribute or `null` if no matching attribute is found |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 if (identical(token, contentEnd)) { | 1748 if (identical(token, contentEnd)) { |
| 1785 return ""; | 1749 return ""; |
| 1786 } | 1750 } |
| 1787 //TODO (danrubel): handle CDATA and replace HTML character encodings with th
e actual characters | 1751 //TODO (danrubel): handle CDATA and replace HTML character encodings with th
e actual characters |
| 1788 String content = token.lexeme; | 1752 String content = token.lexeme; |
| 1789 token = token.next; | 1753 token = token.next; |
| 1790 if (identical(token, contentEnd)) { | 1754 if (identical(token, contentEnd)) { |
| 1791 return content; | 1755 return content; |
| 1792 } | 1756 } |
| 1793 JavaStringBuilder buffer = new JavaStringBuilder(); | 1757 JavaStringBuilder buffer = new JavaStringBuilder(); |
| 1794 while (token != contentEnd) { | 1758 while (!identical(token, contentEnd)) { |
| 1795 buffer.append(token.lexeme); | 1759 buffer.append(token.lexeme); |
| 1796 token = token.next; | 1760 token = token.next; |
| 1797 } | 1761 } |
| 1798 return buffer.toString(); | 1762 return buffer.toString(); |
| 1799 } | 1763 } |
| 1800 | 1764 |
| 1801 @override | 1765 @override |
| 1802 Token get endToken { | 1766 Token get endToken { |
| 1803 if (nodeEnd != null) { | 1767 if (nodeEnd != null) { |
| 1804 return nodeEnd; | 1768 return nodeEnd; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 */ | 1824 */ |
| 1861 class HtmlParser extends XmlParser { | 1825 class HtmlParser extends XmlParser { |
| 1862 /** | 1826 /** |
| 1863 * The line information associated with the source being parsed. | 1827 * The line information associated with the source being parsed. |
| 1864 */ | 1828 */ |
| 1865 LineInfo _lineInfo; | 1829 LineInfo _lineInfo; |
| 1866 | 1830 |
| 1867 /** | 1831 /** |
| 1868 * The error listener to which errors will be reported. | 1832 * The error listener to which errors will be reported. |
| 1869 */ | 1833 */ |
| 1870 AnalysisErrorListener _errorListener; | 1834 final AnalysisErrorListener _errorListener; |
| 1871 | 1835 |
| 1872 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\""; | 1836 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\""; |
| 1873 | 1837 |
| 1874 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'"; | 1838 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'"; |
| 1875 | 1839 |
| 1876 static String _SCRIPT = "script"; | 1840 static String _SCRIPT = "script"; |
| 1877 | 1841 |
| 1878 static String _TYPE = "type"; | 1842 static String _TYPE = "type"; |
| 1879 | 1843 |
| 1880 /** | 1844 /** |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1910 scanner.setSourceStart(location.lineNumber, location.columnNumber); | 1874 scanner.setSourceStart(location.lineNumber, location.columnNumber); |
| 1911 return scanner.tokenize(); | 1875 return scanner.tokenize(); |
| 1912 } | 1876 } |
| 1913 | 1877 |
| 1914 /** | 1878 /** |
| 1915 * Construct a parser for the specified source. | 1879 * Construct a parser for the specified source. |
| 1916 * | 1880 * |
| 1917 * @param source the source being parsed | 1881 * @param source the source being parsed |
| 1918 * @param errorListener the error listener to which errors will be reported | 1882 * @param errorListener the error listener to which errors will be reported |
| 1919 */ | 1883 */ |
| 1920 HtmlParser(Source source, AnalysisErrorListener errorListener) : super(source)
{ | 1884 HtmlParser(Source source, this._errorListener) : super(source); |
| 1921 this._errorListener = errorListener; | |
| 1922 } | |
| 1923 | 1885 |
| 1924 /** | 1886 /** |
| 1925 * Parse the given tokens. | 1887 * Parse the given tokens. |
| 1926 * | 1888 * |
| 1927 * @param token the first token in the stream of tokens to be parsed | 1889 * @param token the first token in the stream of tokens to be parsed |
| 1928 * @param lineInfo the line information created by the scanner | 1890 * @param lineInfo the line information created by the scanner |
| 1929 * @return the parse result (not `null`) | 1891 * @return the parse result (not `null`) |
| 1930 */ | 1892 */ |
| 1931 HtmlUnit parse(Token token, LineInfo lineInfo) { | 1893 HtmlUnit parse(Token token, LineInfo lineInfo) { |
| 1932 this._lineInfo = lineInfo; | 1894 this._lineInfo = lineInfo; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 } | 1946 } |
| 1985 } | 1947 } |
| 1986 | 1948 |
| 1987 /** | 1949 /** |
| 1988 * Instances of the class `HtmlUnit` represent the contents of an HTML file. | 1950 * Instances of the class `HtmlUnit` represent the contents of an HTML file. |
| 1989 */ | 1951 */ |
| 1990 class HtmlUnit extends XmlNode { | 1952 class HtmlUnit extends XmlNode { |
| 1991 /** | 1953 /** |
| 1992 * The first token in the token stream that was parsed to form this HTML unit. | 1954 * The first token in the token stream that was parsed to form this HTML unit. |
| 1993 */ | 1955 */ |
| 1994 Token beginToken; | 1956 final Token beginToken; |
| 1995 | 1957 |
| 1996 /** | 1958 /** |
| 1997 * The last token in the token stream that was parsed to form this compilation
unit. This token | 1959 * The last token in the token stream that was parsed to form this compilation
unit. This token |
| 1998 * should always have a type of [TokenType.EOF]. | 1960 * should always have a type of [TokenType.EOF]. |
| 1999 */ | 1961 */ |
| 2000 Token endToken; | 1962 final Token endToken; |
| 2001 | 1963 |
| 2002 /** | 1964 /** |
| 2003 * The tag nodes contained in the receiver (not `null`, contains no `null`s). | 1965 * The tag nodes contained in the receiver (not `null`, contains no `null`s). |
| 2004 */ | 1966 */ |
| 2005 List<XmlTagNode> _tagNodes; | 1967 List<XmlTagNode> _tagNodes; |
| 2006 | 1968 |
| 2007 /** | 1969 /** |
| 2008 * Construct a new instance representing the content of an HTML file. | 1970 * Construct a new instance representing the content of an HTML file. |
| 2009 * | 1971 * |
| 2010 * @param beginToken the first token in the file (not `null`) | 1972 * @param beginToken the first token in the file (not `null`) |
| 2011 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) | 1973 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) |
| 2012 * @param endToken the last token in the token stream which should be of type | 1974 * @param endToken the last token in the token stream which should be of type |
| 2013 * [TokenType.EOF] | 1975 * [TokenType.EOF] |
| 2014 */ | 1976 */ |
| 2015 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { | 1977 HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) { |
| 2016 this.beginToken = beginToken; | |
| 2017 this._tagNodes = becomeParentOfAll(tagNodes); | 1978 this._tagNodes = becomeParentOfAll(tagNodes); |
| 2018 this.endToken = endToken; | |
| 2019 } | 1979 } |
| 2020 | 1980 |
| 2021 @override | 1981 @override |
| 2022 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); | 1982 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); |
| 2023 | 1983 |
| 2024 /** | 1984 /** |
| 2025 * Return the element associated with this HTML unit. | 1985 * Return the element associated with this HTML unit. |
| 2026 * | 1986 * |
| 2027 * @return the element or `null` if the receiver is not resolved | 1987 * @return the element or `null` if the receiver is not resolved |
| 2028 */ | 1988 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2045 super.element = element; | 2005 super.element = element; |
| 2046 } | 2006 } |
| 2047 | 2007 |
| 2048 @override | 2008 @override |
| 2049 void visitChildren(XmlVisitor visitor) { | 2009 void visitChildren(XmlVisitor visitor) { |
| 2050 for (XmlTagNode node in _tagNodes) { | 2010 for (XmlTagNode node in _tagNodes) { |
| 2051 node.accept(visitor); | 2011 node.accept(visitor); |
| 2052 } | 2012 } |
| 2053 } | 2013 } |
| 2054 } | 2014 } |
| OLD | NEW |