| OLD | NEW |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
| 2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
| 3 | 3 |
| 4 library engine.html; | 4 library engine.html; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'java_core.dart'; | 7 import 'java_core.dart'; |
| 8 import 'java_engine.dart'; | 8 import 'java_engine.dart'; |
| 9 import 'source.dart'; | 9 import 'source.dart'; |
| 10 import 'error.dart' show AnalysisErrorListener; | 10 import 'error.dart' show AnalysisErrorListener; |
| 11 import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token; | 11 import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token; |
| 12 import 'parser.dart' show Parser; | 12 import 'parser.dart' show Parser; |
| 13 import 'ast.dart' show ASTVisitor, CompilationUnit, Expression; | 13 import 'ast.dart'; |
| 14 import 'element.dart' show HtmlElementImpl, HtmlScriptElement; | 14 import 'element.dart'; |
| 15 import 'engine.dart' show AnalysisEngine; | 15 import 'engine.dart' show AnalysisEngine; |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Instances of the class `Token` represent a token that was scanned from the in
put. Each | 18 * Instances of the class `Token` represent a token that was scanned from the in
put. Each |
| 19 * token knows which token follows it, acting as the head of a linked list of to
kens. | 19 * token knows which token follows it, acting as the head of a linked list of to
kens. |
| 20 * | 20 * |
| 21 * @coverage dart.engine.html | 21 * @coverage dart.engine.html |
| 22 */ | 22 */ |
| 23 class Token { | 23 class Token { |
| 24 /** | 24 /** |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 | 188 |
| 189 /** | 189 /** |
| 190 * Answer the unit generated by parsing the source | 190 * Answer the unit generated by parsing the source |
| 191 * | 191 * |
| 192 * @return the unit (not `null`) | 192 * @return the unit (not `null`) |
| 193 */ | 193 */ |
| 194 HtmlUnit get htmlUnit => _unit; | 194 HtmlUnit get htmlUnit => _unit; |
| 195 } | 195 } |
| 196 | 196 |
| 197 /** | 197 /** |
| 198 * Instances of the class `TagWithEmbeddedExpressions` represent a tag whose tex
t content | |
| 199 * contains one or more embedded expressions. | |
| 200 */ | |
| 201 class TagWithEmbeddedExpressions extends XmlTagNode { | |
| 202 /** | |
| 203 * The expressions that are embedded in the tag's content. | |
| 204 */ | |
| 205 final List<EmbeddedExpression> expressions; | |
| 206 | |
| 207 /** | |
| 208 * Initialize a newly created tag whose text content contains one or more embe
dded expressions. | |
| 209 * | |
| 210 * @param nodeStart the token marking the beginning of the tag | |
| 211 * @param tag the name of the tag | |
| 212 * @param attributes the attributes in the tag | |
| 213 * @param attributeEnd the token terminating the region where attributes can b
e | |
| 214 * @param tagNodes the children of the tag | |
| 215 * @param contentEnd the token that starts the closing tag | |
| 216 * @param closingTag the name of the tag that occurs in the closing tag | |
| 217 * @param nodeEnd the last token in the tag | |
| 218 * @param expressions the expressions that are embedded in the value | |
| 219 */ | |
| 220 TagWithEmbeddedExpressions(Token nodeStart, Token tag, List<XmlAttributeNode>
attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Tok
en closingTag, Token nodeEnd, this.expressions) : super(nodeStart, tag, attribut
es, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd); | |
| 221 } | |
| 222 | |
| 223 /** | |
| 224 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively | 198 * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that wi
ll recursively |
| 225 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit | 199 * visit all of the nodes in an XML structure. For example, using an instance of
this class to visit |
| 226 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and | 200 * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and |
| 227 * [XmlTagNode]s to be visited. | 201 * [XmlTagNode]s to be visited. |
| 228 * | 202 * |
| 229 * Subclasses that override a visit method must either invoke the overridden vis
it method or must | 203 * Subclasses that override a visit method must either invoke the overridden vis
it method or must |
| 230 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children | 204 * explicitly ask the visited node to visit its children. Failure to do so will
cause the children |
| 231 * of the visited node to not be visited. | 205 * of the visited node to not be visited. |
| 232 * | 206 * |
| 233 * @coverage dart.engine.html | 207 * @coverage dart.engine.html |
| (...skipping 14 matching lines...) Expand all Loading... |
| 248 return null; | 222 return null; |
| 249 } | 223 } |
| 250 | 224 |
| 251 R visitXmlTagNode(XmlTagNode node) { | 225 R visitXmlTagNode(XmlTagNode node) { |
| 252 node.visitChildren(this); | 226 node.visitChildren(this); |
| 253 return null; | 227 return null; |
| 254 } | 228 } |
| 255 } | 229 } |
| 256 | 230 |
| 257 /** | 231 /** |
| 232 * Utilities locating [Expression]s and [Element]s in [HtmlUnit]. |
| 233 */ |
| 234 class HtmlUnitUtils { |
| 235 /** |
| 236 * Returns the best [Element] of the given [Expression]. |
| 237 */ |
| 238 static Element getElement(Expression expression) { |
| 239 if (expression == null) { |
| 240 return null; |
| 241 } |
| 242 return ElementLocator.locate(expression); |
| 243 } |
| 244 |
| 245 /** |
| 246 * Returns the [Element] of the [Expression] in the given [HtmlUnit], enclosin
g |
| 247 * the given offset. |
| 248 */ |
| 249 static Element getElement2(HtmlUnit htmlUnit, int offset) { |
| 250 Expression expression = getExpression(htmlUnit, offset); |
| 251 return getElement(expression); |
| 252 } |
| 253 |
| 254 /** |
| 255 * Returns the [Element] to open when requested at the given [Expression]. |
| 256 */ |
| 257 static Element getElementToOpen(HtmlUnit htmlUnit, Expression expression) { |
| 258 Element element = getElement(expression); |
| 259 if (isAngular(htmlUnit)) { |
| 260 if (element is VariableElement) { |
| 261 VariableElement variable = element as VariableElement; |
| 262 Type2 type = variable.type; |
| 263 if (variable.nameOffset == 0 && type is InterfaceType) { |
| 264 element = (type as InterfaceType).element; |
| 265 } |
| 266 } |
| 267 } |
| 268 return element; |
| 269 } |
| 270 |
| 271 /** |
| 272 * Returns the [Expression] that is part of the given [HtmlUnit] and encloses
the |
| 273 * given offset. |
| 274 */ |
| 275 static Expression getExpression(HtmlUnit htmlUnit, int offset) { |
| 276 if (htmlUnit == null) { |
| 277 return null; |
| 278 } |
| 279 List<Expression> result = [null]; |
| 280 try { |
| 281 htmlUnit.accept(new RecursiveXmlVisitor_7(offset, result)); |
| 282 } on HtmlUnitUtils_FoundExpressionError catch (e) { |
| 283 return result[0]; |
| 284 } |
| 285 return null; |
| 286 } |
| 287 |
| 288 /** |
| 289 * Returns `true` if the given [HtmlUnit] has Angular annotation. |
| 290 */ |
| 291 static bool isAngular(HtmlUnit htmlUnit) => false; // AngularHtmlUnitResolver.
hasAngularAnnotation(htmlUnit); |
| 292 |
| 293 /** |
| 294 * Returns the [Expression] that is part of the given root [ASTNode] and enclo
ses the |
| 295 * given offset. |
| 296 */ |
| 297 static Expression getExpressionAt(ASTNode root, int offset) { |
| 298 if (root.offset <= offset && offset < root.end) { |
| 299 ASTNode dartNode = new NodeLocator.con1(offset).searchWithin(root); |
| 300 if (dartNode is Expression) { |
| 301 return dartNode as Expression; |
| 302 } |
| 303 } |
| 304 return null; |
| 305 } |
| 306 } |
| 307 |
| 308 class HtmlUnitUtils_FoundExpressionError extends Error { |
| 309 } |
| 310 |
| 311 class RecursiveXmlVisitor_7 extends RecursiveXmlVisitor<Object> { |
| 312 int offset = 0; |
| 313 |
| 314 List<Expression> result; |
| 315 |
| 316 RecursiveXmlVisitor_7(this.offset, this.result) : super(); |
| 317 |
| 318 Object visitXmlAttributeNode(XmlAttributeNode node) { |
| 319 findExpression(offset, result, node.expressions); |
| 320 return super.visitXmlAttributeNode(node); |
| 321 } |
| 322 |
| 323 Object visitXmlTagNode(XmlTagNode node) { |
| 324 findExpression(offset, result, node.expressions); |
| 325 return super.visitXmlTagNode(node); |
| 326 } |
| 327 |
| 328 void findExpression(int offset, List<Expression> result, List<EmbeddedExpressi
on> expressions) { |
| 329 for (EmbeddedExpression embeddedExpression in expressions) { |
| 330 Expression expression = embeddedExpression.expression; |
| 331 Expression at = HtmlUnitUtils.getExpressionAt(expression, offset); |
| 332 if (at != null) { |
| 333 result[0] = at; |
| 334 throw new HtmlUnitUtils_FoundExpressionError(); |
| 335 } |
| 336 } |
| 337 } |
| 338 } |
| 339 |
| 340 /** |
| 258 * Instances of the class `HtmlScriptTagNode` represent a script tag within an H
TML file that | 341 * Instances of the class `HtmlScriptTagNode` represent a script tag within an H
TML file that |
| 259 * references a Dart script. | 342 * references a Dart script. |
| 260 */ | 343 */ |
| 261 class HtmlScriptTagNode extends XmlTagNode { | 344 class HtmlScriptTagNode extends XmlTagNode { |
| 262 /** | 345 /** |
| 263 * The AST structure representing the Dart code within this tag. | 346 * The AST structure representing the Dart code within this tag. |
| 264 */ | 347 */ |
| 265 CompilationUnit _script; | 348 CompilationUnit _script; |
| 266 | 349 |
| 267 /** | 350 /** |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu
ildRecursiveStructureMessage(newParent))); | 561 AnalysisEngine.instance.logger.logError3(new IllegalArgumentException(bu
ildRecursiveStructureMessage(newParent))); |
| 479 return; | 562 return; |
| 480 } | 563 } |
| 481 current = current.parent; | 564 current = current.parent; |
| 482 } | 565 } |
| 483 _parent = newParent; | 566 _parent = newParent; |
| 484 } | 567 } |
| 485 } | 568 } |
| 486 | 569 |
| 487 /** | 570 /** |
| 488 * Instances of the class `AttributeWithEmbeddedExpressions` represent an attrib
ute whose | |
| 489 * value contains one or more embedded expressions. | |
| 490 */ | |
| 491 class AttributeWithEmbeddedExpressions extends XmlAttributeNode { | |
| 492 /** | |
| 493 * The expressions that are embedded in the attribute's value. | |
| 494 */ | |
| 495 final List<EmbeddedExpression> expressions; | |
| 496 | |
| 497 /** | |
| 498 * Initialize a newly created attribute whose value contains one or more embed
ded expressions. | |
| 499 * | |
| 500 * @param name the name of the attribute | |
| 501 * @param equals the equals sign separating the name from the value | |
| 502 * @param value the value of the attribute | |
| 503 * @param expressions the expressions that are embedded in the value | |
| 504 */ | |
| 505 AttributeWithEmbeddedExpressions(Token name, Token equals, Token value, this.e
xpressions) : super(name, equals, value); | |
| 506 } | |
| 507 | |
| 508 /** | |
| 509 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will
do nothing | 571 * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will
do nothing |
| 510 * when visiting an AST node. It is intended to be a superclass for classes that
use the visitor | 572 * when visiting an AST node. It is intended to be a superclass for classes that
use the visitor |
| 511 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel
y visit a whole | 573 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel
y visit a whole |
| 512 * structure) and that only need to visit a small number of node types. | 574 * structure) and that only need to visit a small number of node types. |
| 513 */ | 575 */ |
| 514 class SimpleXmlVisitor<R> implements XmlVisitor<R> { | 576 class SimpleXmlVisitor<R> implements XmlVisitor<R> { |
| 515 R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null; | 577 R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null; |
| 516 | 578 |
| 517 R visitHtmlUnit(HtmlUnit htmlUnit) => null; | 579 R visitHtmlUnit(HtmlUnit htmlUnit) => null; |
| 518 | 580 |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 * | 1175 * |
| 1114 * @coverage dart.engine.html | 1176 * @coverage dart.engine.html |
| 1115 */ | 1177 */ |
| 1116 class XmlAttributeNode extends XmlNode { | 1178 class XmlAttributeNode extends XmlNode { |
| 1117 final Token name; | 1179 final Token name; |
| 1118 | 1180 |
| 1119 final Token equals; | 1181 final Token equals; |
| 1120 | 1182 |
| 1121 final Token value; | 1183 final Token value; |
| 1122 | 1184 |
| 1185 List<EmbeddedExpression> expressions = EmbeddedExpression.EMPTY_ARRAY; |
| 1186 |
| 1123 /** | 1187 /** |
| 1124 * Construct a new instance representing an XML attribute. | 1188 * Construct a new instance representing an XML attribute. |
| 1125 * | 1189 * |
| 1126 * @param name the name token (not `null`). This may be a zero length token if
the attribute | 1190 * @param name the name token (not `null`). This may be a zero length token if
the attribute |
| 1127 * is badly formed. | 1191 * is badly formed. |
| 1128 * @param equals the equals sign or `null` if none | 1192 * @param equals the equals sign or `null` if none |
| 1129 * @param value the value token (not `null`) | 1193 * @param value the value token (not `null`) |
| 1130 */ | 1194 */ |
| 1131 XmlAttributeNode(this.name, this.equals, this.value); | 1195 XmlAttributeNode(this.name, this.equals, this.value); |
| 1132 | 1196 |
| 1133 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); | 1197 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); |
| 1134 | 1198 |
| 1135 Token get beginToken => name; | 1199 Token get beginToken => name; |
| 1136 | 1200 |
| 1137 Token get endToken => value; | 1201 Token get endToken => value; |
| 1138 | 1202 |
| 1139 /** | 1203 /** |
| 1140 * Return the expressions that are embedded in the attribute's value. | |
| 1141 * | |
| 1142 * @return the expressions that are embedded in the attribute's value | |
| 1143 */ | |
| 1144 List<EmbeddedExpression> get expressions => EmbeddedExpression.EMPTY_ARRAY; | |
| 1145 | |
| 1146 /** | |
| 1147 * Answer the lexeme for the value token without the leading and trailing quot
es. | 1204 * Answer the lexeme for the value token without the leading and trailing quot
es. |
| 1148 * | 1205 * |
| 1149 * @return the text or `null` if the value is not specified | 1206 * @return the text or `null` if the value is not specified |
| 1150 */ | 1207 */ |
| 1151 String get text { | 1208 String get text { |
| 1152 if (value == null) { | 1209 if (value == null) { |
| 1153 return null; | 1210 return null; |
| 1154 } | 1211 } |
| 1155 String text = value.lexeme; | 1212 String text = value.lexeme; |
| 1156 int len = text.length; | 1213 int len = text.length; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 * content and the attributes ended with [TokenType#SLASH_GT] | 1680 * content and the attributes ended with [TokenType#SLASH_GT] |
| 1624 */ | 1681 */ |
| 1625 final Token closingTag; | 1682 final Token closingTag; |
| 1626 | 1683 |
| 1627 /** | 1684 /** |
| 1628 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). | 1685 * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`). |
| 1629 */ | 1686 */ |
| 1630 final Token nodeEnd; | 1687 final Token nodeEnd; |
| 1631 | 1688 |
| 1632 /** | 1689 /** |
| 1690 * The expressions that are embedded in the tag's content. |
| 1691 */ |
| 1692 List<EmbeddedExpression> expressions = EmbeddedExpression.EMPTY_ARRAY; |
| 1693 |
| 1694 /** |
| 1633 * Construct a new instance representing an XML or HTML element | 1695 * Construct a new instance representing an XML or HTML element |
| 1634 * | 1696 * |
| 1635 * @param nodeStart the starting [TokenType#LT] token (not `null`) | 1697 * @param nodeStart the starting [TokenType#LT] token (not `null`) |
| 1636 * @param tag the [TokenType#TAG] token after the starting '<' (not `null`)
. | 1698 * @param tag the [TokenType#TAG] token after the starting '<' (not `null`)
. |
| 1637 * @param attributes the attributes associated with this element or [NO_ATTRIB
UTES] (not | 1699 * @param attributes the attributes associated with this element or [NO_ATTRIB
UTES] (not |
| 1638 * `null`, contains no `null`s) | 1700 * `null`, contains no `null`s) |
| 1639 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after
the | 1701 * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after
the |
| 1640 * attributes (not `null`). The token may be the same token as [nodeE
nd] if | 1702 * attributes (not `null`). The token may be the same token as [nodeE
nd] if |
| 1641 * there are no child [tagNodes]. | 1703 * there are no child [tagNodes]. |
| 1642 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul
l`, | 1704 * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `nul
l`, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1741 if (attributeEnd != null) { | 1803 if (attributeEnd != null) { |
| 1742 return attributeEnd; | 1804 return attributeEnd; |
| 1743 } | 1805 } |
| 1744 if (!_attributes.isEmpty) { | 1806 if (!_attributes.isEmpty) { |
| 1745 return _attributes[_attributes.length - 1].endToken; | 1807 return _attributes[_attributes.length - 1].endToken; |
| 1746 } | 1808 } |
| 1747 return tag; | 1809 return tag; |
| 1748 } | 1810 } |
| 1749 | 1811 |
| 1750 /** | 1812 /** |
| 1751 * Return the expressions that are embedded in the tag's content. | |
| 1752 * | |
| 1753 * @return the expressions that are embedded in the tag's content | |
| 1754 */ | |
| 1755 List<EmbeddedExpression> get expressions => EmbeddedExpression.EMPTY_ARRAY; | |
| 1756 | |
| 1757 /** | |
| 1758 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list | 1813 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list |
| 1759 * to edit the AST structure. | 1814 * to edit the AST structure. |
| 1760 * | 1815 * |
| 1761 * @return the children (not `null`, contains no `null`s) | 1816 * @return the children (not `null`, contains no `null`s) |
| 1762 */ | 1817 */ |
| 1763 List<XmlTagNode> get tagNodes => _tagNodes; | 1818 List<XmlTagNode> get tagNodes => _tagNodes; |
| 1764 | 1819 |
| 1765 void visitChildren(XmlVisitor visitor) { | 1820 void visitChildren(XmlVisitor visitor) { |
| 1766 for (XmlAttributeNode node in _attributes) { | 1821 for (XmlAttributeNode node in _attributes) { |
| 1767 node.accept(visitor); | 1822 node.accept(visitor); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1796 | 1851 |
| 1797 /** | 1852 /** |
| 1798 * The error listener to which errors will be reported. | 1853 * The error listener to which errors will be reported. |
| 1799 */ | 1854 */ |
| 1800 AnalysisErrorListener _errorListener; | 1855 AnalysisErrorListener _errorListener; |
| 1801 | 1856 |
| 1802 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\""; | 1857 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\""; |
| 1803 | 1858 |
| 1804 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'"; | 1859 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'"; |
| 1805 | 1860 |
| 1806 static String _OPENING_DELIMITER = "{{"; | |
| 1807 | |
| 1808 static String _CLOSING_DELIMITER = "}}"; | |
| 1809 | |
| 1810 static String _SCRIPT = "script"; | 1861 static String _SCRIPT = "script"; |
| 1811 | 1862 |
| 1812 static String _TYPE = "type"; | 1863 static String _TYPE = "type"; |
| 1813 | 1864 |
| 1814 /** | 1865 /** |
| 1815 * A set containing the names of tags that do not have a closing tag. | 1866 * A set containing the names of tags that do not have a closing tag. |
| 1816 */ | 1867 */ |
| 1817 static Set<String> SELF_CLOSING = new Set<String>(); | 1868 static Set<String> SELF_CLOSING = new Set<String>(); |
| 1818 | 1869 |
| 1819 /** | 1870 /** |
| 1871 * Given the contents of an embedded expression that occurs at the given offse
t, parse it as a |
| 1872 * Dart expression. The contents should not include the expression's delimiter
s. |
| 1873 * |
| 1874 * @param source the source that contains that given token |
| 1875 * @param token the token to start parsing from |
| 1876 * @return the Dart expression that was parsed |
| 1877 */ |
| 1878 static Expression parseEmbeddedExpression(Source source, sc.Token token, Analy
sisErrorListener errorListener) { |
| 1879 Parser parser = new Parser(source, errorListener); |
| 1880 return parser.parseExpression(token); |
| 1881 } |
| 1882 |
| 1883 /** |
| 1884 * Given the contents of an embedded expression that occurs at the given offse
t, scans it as a |
| 1885 * Dart code. |
| 1886 * |
| 1887 * @param source the source of that contains the given contents |
| 1888 * @param contents the contents to scan |
| 1889 * @param contentOffset the offset of the contents in the larger file |
| 1890 * @return the first Dart token |
| 1891 */ |
| 1892 static sc.Token scanDartSource(Source source, LineInfo lineInfo, String conten
ts, int contentOffset, AnalysisErrorListener errorListener) { |
| 1893 LineInfo_Location location = lineInfo.getLocation(contentOffset); |
| 1894 sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new Cha
rSequence(contents), contentOffset), errorListener); |
| 1895 scanner.setSourceStart(location.lineNumber, location.columnNumber); |
| 1896 return scanner.tokenize(); |
| 1897 } |
| 1898 |
| 1899 /** |
| 1820 * Construct a parser for the specified source. | 1900 * Construct a parser for the specified source. |
| 1821 * | 1901 * |
| 1822 * @param source the source being parsed | 1902 * @param source the source being parsed |
| 1823 * @param errorListener the error listener to which errors will be reported | 1903 * @param errorListener the error listener to which errors will be reported |
| 1824 */ | 1904 */ |
| 1825 HtmlParser(Source source, AnalysisErrorListener errorListener) : super(source)
{ | 1905 HtmlParser(Source source, AnalysisErrorListener errorListener) : super(source)
{ |
| 1826 this._errorListener = errorListener; | 1906 this._errorListener = errorListener; |
| 1827 } | 1907 } |
| 1828 | 1908 |
| 1829 Token getEndToken(Token tag, List<XmlAttributeNode> attributes, Token attribut
eEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeE
nd) { | |
| 1830 if (nodeEnd != null) { | |
| 1831 return nodeEnd; | |
| 1832 } | |
| 1833 if (closingTag != null) { | |
| 1834 return closingTag; | |
| 1835 } | |
| 1836 if (contentEnd != null) { | |
| 1837 return contentEnd; | |
| 1838 } | |
| 1839 if (!tagNodes.isEmpty) { | |
| 1840 return tagNodes[tagNodes.length - 1].endToken; | |
| 1841 } | |
| 1842 if (attributeEnd != null) { | |
| 1843 return attributeEnd; | |
| 1844 } | |
| 1845 if (!attributes.isEmpty) { | |
| 1846 return attributes[attributes.length - 1].endToken; | |
| 1847 } | |
| 1848 return tag; | |
| 1849 } | |
| 1850 | |
| 1851 /** | 1909 /** |
| 1852 * Parse the tokens specified by the given scan result. | 1910 * Parse the tokens specified by the given scan result. |
| 1853 * | 1911 * |
| 1854 * @param scanResult the result of scanning an HTML source (not `null`) | 1912 * @param scanResult the result of scanning an HTML source (not `null`) |
| 1855 * @return the parse result (not `null`) | 1913 * @return the parse result (not `null`) |
| 1856 */ | 1914 */ |
| 1857 HtmlParseResult parse(HtmlScanResult scanResult) { | 1915 HtmlParseResult parse(HtmlScanResult scanResult) { |
| 1858 List<int> lineStarts = scanResult.lineStarts; | 1916 List<int> lineStarts = scanResult.lineStarts; |
| 1859 _lineInfo = new LineInfo(lineStarts); | 1917 _lineInfo = new LineInfo(lineStarts); |
| 1860 Token firstToken = scanResult.token; | 1918 Token firstToken = scanResult.token; |
| 1861 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken); | 1919 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken); |
| 1862 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken); | 1920 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken); |
| 1863 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu
lt.lineStarts, unit); | 1921 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu
lt.lineStarts, unit); |
| 1864 } | 1922 } |
| 1865 | 1923 |
| 1866 /** | 1924 /** |
| 1867 * Scan then parse the specified source. | 1925 * Scan then parse the specified source. |
| 1868 * | 1926 * |
| 1869 * @param source the source to be scanned and parsed (not `null`) | 1927 * @param source the source to be scanned and parsed (not `null`) |
| 1870 * @return the parse result (not `null`) | 1928 * @return the parse result (not `null`) |
| 1871 */ | 1929 */ |
| 1872 HtmlParseResult parse2(Source source) { | 1930 HtmlParseResult parse2(Source source) { |
| 1873 HtmlScanner scanner = new HtmlScanner(source); | 1931 HtmlScanner scanner = new HtmlScanner(source); |
| 1874 source.getContents(scanner); | 1932 source.getContents(scanner); |
| 1875 return parse(scanner.result); | 1933 return parse(scanner.result); |
| 1876 } | 1934 } |
| 1877 | 1935 |
| 1878 XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) { | 1936 XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
new XmlAttributeNode(name, equals, value); |
| 1879 List<EmbeddedExpression> expressions = new List<EmbeddedExpression>(); | |
| 1880 addEmbeddedExpressions(expressions, value); | |
| 1881 if (expressions.isEmpty) { | |
| 1882 return new XmlAttributeNode(name, equals, value); | |
| 1883 } | |
| 1884 return new AttributeWithEmbeddedExpressions(name, equals, value, new List.fr
om(expressions)); | |
| 1885 } | |
| 1886 | 1937 |
| 1887 XmlTagNode createTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> at
tributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token
closingTag, Token nodeEnd) { | 1938 XmlTagNode createTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> at
tributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token
closingTag, Token nodeEnd) { |
| 1888 if (isScriptNode(tag, attributes, tagNodes)) { | 1939 if (isScriptNode(tag, attributes, tagNodes)) { |
| 1889 HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag, attribut
es, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd); | 1940 HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag, attribut
es, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd); |
| 1890 String contents = tagNode.content; | 1941 String contents = tagNode.content; |
| 1891 int contentOffset = attributeEnd.end; | 1942 int contentOffset = attributeEnd.end; |
| 1892 LineInfo_Location location = _lineInfo.getLocation(contentOffset); | 1943 LineInfo_Location location = _lineInfo.getLocation(contentOffset); |
| 1893 sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new C
harSequence(contents), contentOffset), _errorListener); | 1944 sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new C
harSequence(contents), contentOffset), _errorListener); |
| 1894 scanner.setSourceStart(location.lineNumber, location.columnNumber); | 1945 scanner.setSourceStart(location.lineNumber, location.columnNumber); |
| 1895 sc.Token firstToken = scanner.tokenize(); | 1946 sc.Token firstToken = scanner.tokenize(); |
| 1896 Parser parser = new Parser(source, _errorListener); | 1947 Parser parser = new Parser(source, _errorListener); |
| 1897 CompilationUnit unit = parser.parseCompilationUnit(firstToken); | 1948 CompilationUnit unit = parser.parseCompilationUnit(firstToken); |
| 1898 unit.lineInfo = _lineInfo; | 1949 unit.lineInfo = _lineInfo; |
| 1899 tagNode.script = unit; | 1950 tagNode.script = unit; |
| 1900 return tagNode; | 1951 return tagNode; |
| 1901 } | 1952 } |
| 1902 Token token = nodeStart; | 1953 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co
ntentEnd, closingTag, nodeEnd); |
| 1903 Token endToken = getEndToken(tag, attributes, attributeEnd, tagNodes, conten
tEnd, closingTag, nodeEnd); | |
| 1904 List<EmbeddedExpression> expressions = new List<EmbeddedExpression>(); | |
| 1905 while (token != endToken) { | |
| 1906 if (identical(token.type, TokenType.TEXT)) { | |
| 1907 addEmbeddedExpressions(expressions, token); | |
| 1908 } | |
| 1909 token = token.next; | |
| 1910 } | |
| 1911 if (expressions.isEmpty) { | |
| 1912 return super.createTagNode(nodeStart, tag, attributes, attributeEnd, tagNo
des, contentEnd, closingTag, nodeEnd); | |
| 1913 } | |
| 1914 return new TagWithEmbeddedExpressions(nodeStart, tag, attributes, attributeE
nd, tagNodes, contentEnd, closingTag, nodeEnd, new List.from(expressions)); | |
| 1915 } | 1954 } |
| 1916 | 1955 |
| 1917 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); | 1956 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); |
| 1918 | 1957 |
| 1919 /** | 1958 /** |
| 1920 * Parse the value of the given token for embedded expressions, and add any em
bedded expressions | |
| 1921 * that are found to the given list of expressions. | |
| 1922 * | |
| 1923 * @param expressions the list to which embedded expressions are to be added | |
| 1924 * @param token the token whose value is to be parsed | |
| 1925 */ | |
| 1926 void addEmbeddedExpressions(List<EmbeddedExpression> expressions, Token token)
{ | |
| 1927 String lexeme = token.lexeme; | |
| 1928 int startIndex = lexeme.indexOf(_OPENING_DELIMITER); | |
| 1929 while (startIndex >= 0) { | |
| 1930 int endIndex = JavaString.indexOf(lexeme, _CLOSING_DELIMITER, startIndex +
2); | |
| 1931 if (endIndex < 0) { | |
| 1932 return; | |
| 1933 } else if (startIndex + 2 < endIndex) { | |
| 1934 int offset = token.offset; | |
| 1935 expressions.add(new EmbeddedExpression(startIndex, parseEmbeddedExpressi
on(lexeme.substring(startIndex + 2, endIndex), offset + startIndex), endIndex)); | |
| 1936 } | |
| 1937 startIndex = JavaString.indexOf(lexeme, _OPENING_DELIMITER, endIndex + 2); | |
| 1938 } | |
| 1939 } | |
| 1940 | |
| 1941 /** | |
| 1942 * Determine if the specified node is a Dart script. | 1959 * Determine if the specified node is a Dart script. |
| 1943 * | 1960 * |
| 1944 * @param node the node to be tested (not `null`) | 1961 * @param node the node to be tested (not `null`) |
| 1945 * @return `true` if the node is a Dart script | 1962 * @return `true` if the node is a Dart script |
| 1946 */ | 1963 */ |
| 1947 bool isScriptNode(Token tag, List<XmlAttributeNode> attributes, List<XmlTagNod
e> tagNodes) { | 1964 bool isScriptNode(Token tag, List<XmlAttributeNode> attributes, List<XmlTagNod
e> tagNodes) { |
| 1948 if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) { | 1965 if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) { |
| 1949 return false; | 1966 return false; |
| 1950 } | 1967 } |
| 1951 for (XmlAttributeNode attribute in attributes) { | 1968 for (XmlAttributeNode attribute in attributes) { |
| 1952 if (attribute.name.lexeme == _TYPE) { | 1969 if (attribute.name.lexeme == _TYPE) { |
| 1953 Token valueToken = attribute.value; | 1970 Token valueToken = attribute.value; |
| 1954 if (valueToken != null) { | 1971 if (valueToken != null) { |
| 1955 String value = valueToken.lexeme; | 1972 String value = valueToken.lexeme; |
| 1956 if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATI
ON_DART_IN_SINGLE_QUOTES) { | 1973 if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATI
ON_DART_IN_SINGLE_QUOTES) { |
| 1957 return true; | 1974 return true; |
| 1958 } | 1975 } |
| 1959 } | 1976 } |
| 1960 } | 1977 } |
| 1961 } | 1978 } |
| 1962 return false; | 1979 return false; |
| 1963 } | 1980 } |
| 1964 | |
| 1965 /** | |
| 1966 * Given the contents of an embedded expression that occurs at the given offse
t, parse it as a | |
| 1967 * Dart expression. The contents should not include the expression's delimiter
s. | |
| 1968 * | |
| 1969 * @param contents the contents of the expression | |
| 1970 * @param contentOffset the offset of the expression in the larger file | |
| 1971 * @return the Dart expression that was parsed | |
| 1972 */ | |
| 1973 Expression parseEmbeddedExpression(String contents, int contentOffset) { | |
| 1974 LineInfo_Location location = _lineInfo.getLocation(contentOffset); | |
| 1975 sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new Cha
rSequence(contents), contentOffset), _errorListener); | |
| 1976 scanner.setSourceStart(location.lineNumber, location.columnNumber); | |
| 1977 sc.Token firstToken = scanner.tokenize(); | |
| 1978 Parser parser = new Parser(source, _errorListener); | |
| 1979 return parser.parseExpression(firstToken); | |
| 1980 } | |
| 1981 } | 1981 } |
| 1982 | 1982 |
| 1983 /** | 1983 /** |
| 1984 * Instances of the class `HtmlUnit` represent the contents of an HTML file. | 1984 * Instances of the class `HtmlUnit` represent the contents of an HTML file. |
| 1985 * | 1985 * |
| 1986 * @coverage dart.engine.html | 1986 * @coverage dart.engine.html |
| 1987 */ | 1987 */ |
| 1988 class HtmlUnit extends XmlNode { | 1988 class HtmlUnit extends XmlNode { |
| 1989 /** | 1989 /** |
| 1990 * The first token in the token stream that was parsed to form this HTML unit. | 1990 * The first token in the token stream that was parsed to form this HTML unit. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2001 * The tag nodes contained in the receiver (not `null`, contains no `null`s). | 2001 * The tag nodes contained in the receiver (not `null`, contains no `null`s). |
| 2002 */ | 2002 */ |
| 2003 List<XmlTagNode> _tagNodes; | 2003 List<XmlTagNode> _tagNodes; |
| 2004 | 2004 |
| 2005 /** | 2005 /** |
| 2006 * The element associated with this HTML unit or `null` if the receiver is not
resolved. | 2006 * The element associated with this HTML unit or `null` if the receiver is not
resolved. |
| 2007 */ | 2007 */ |
| 2008 HtmlElementImpl element; | 2008 HtmlElementImpl element; |
| 2009 | 2009 |
| 2010 /** | 2010 /** |
| 2011 * The element associated with Dart pieces in this HTML unit or `null` if the
receiver is |
| 2012 * not resolved. |
| 2013 */ |
| 2014 CompilationUnitElement compilationUnitElement; |
| 2015 |
| 2016 /** |
| 2011 * Construct a new instance representing the content of an HTML file. | 2017 * Construct a new instance representing the content of an HTML file. |
| 2012 * | 2018 * |
| 2013 * @param beginToken the first token in the file (not `null`) | 2019 * @param beginToken the first token in the file (not `null`) |
| 2014 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) | 2020 * @param tagNodes child tag nodes of the receiver (not `null`, contains no `n
ull`s) |
| 2015 * @param endToken the last token in the token stream which should be of type | 2021 * @param endToken the last token in the token stream which should be of type |
| 2016 * [TokenType.EOF] | 2022 * [TokenType.EOF] |
| 2017 */ | 2023 */ |
| 2018 HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) { | 2024 HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) { |
| 2019 this._tagNodes = becomeParentOf(tagNodes); | 2025 this._tagNodes = becomeParentOf(tagNodes); |
| 2020 } | 2026 } |
| 2021 | 2027 |
| 2022 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); | 2028 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); |
| 2023 | 2029 |
| 2024 /** | 2030 /** |
| 2025 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list | 2031 * Answer the tag nodes contained in the receiver. Callers should not manipula
te the returned list |
| 2026 * to edit the AST structure. | 2032 * to edit the AST structure. |
| 2027 * | 2033 * |
| 2028 * @return the children (not `null`, contains no `null`s) | 2034 * @return the children (not `null`, contains no `null`s) |
| 2029 */ | 2035 */ |
| 2030 List<XmlTagNode> get tagNodes => _tagNodes; | 2036 List<XmlTagNode> get tagNodes => _tagNodes; |
| 2031 | 2037 |
| 2032 void visitChildren(XmlVisitor visitor) { | 2038 void visitChildren(XmlVisitor visitor) { |
| 2033 for (XmlTagNode node in _tagNodes) { | 2039 for (XmlTagNode node in _tagNodes) { |
| 2034 node.accept(visitor); | 2040 node.accept(visitor); |
| 2035 } | 2041 } |
| 2036 } | 2042 } |
| 2037 } | 2043 } |
| OLD | NEW |