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

Unified Diff: pkg/analyzer/lib/src/generated/html.dart

Issue 1502213002: Remove deprecated code (Closed) Base URL: https://github.com/dart-lang/sdk.git@analyzer-breaking-0.27
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/lib/src/generated/java_core.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/html.dart
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
deleted file mode 100644
index c0012c5d30e5417320628f20cc775b21ffb99c41..0000000000000000000000000000000000000000
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ /dev/null
@@ -1,1905 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.html;
-
-import 'dart:collection';
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisOptions, AnalysisEngine;
-import 'error.dart' show AnalysisErrorListener;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser;
-import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token;
-import 'source.dart';
-
-/**
- * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
- * required to implement the interface used to access the characters being scanned.
- */
-abstract class AbstractScanner {
- static List<String> _NO_PASS_THROUGH_ELEMENTS = <String>[];
-
- /**
- * The source being scanned.
- */
- final Source source;
-
- /**
- * The token pointing to the head of the linked list of tokens.
- */
- Token _tokens;
-
- /**
- * The last token that was scanned.
- */
- Token _tail;
-
- /**
- * A list containing the offsets of the first character of each line in the source code.
- */
- List<int> _lineStarts = new List<int>();
-
- /**
- * An array of element tags for which the content between tags should be consider a single token.
- */
- List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
-
- /**
- * Initialize a newly created scanner.
- *
- * @param source the source being scanned
- */
- AbstractScanner(this.source) {
- _tokens = new Token.con1(TokenType.EOF, -1);
- _tokens.setNext(_tokens);
- _tail = _tokens;
- recordStartOfLine();
- }
-
- /**
- * Return an array containing the offsets of the first character of each line in the source code.
- *
- * @return an array containing the offsets of the first character of each line in the source code
- */
- List<int> get lineStarts => _lineStarts;
-
- /**
- * Return the current offset relative to the beginning of the file. Return the initial offset if
- * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
- * the source code has been scanned.
- *
- * @return the current offset of the scanner in the source
- */
- int get offset;
-
- /**
- * Set array of element tags for which the content between tags should be consider a single token.
- */
- void set passThroughElements(List<String> passThroughElements) {
- this._passThroughElements = passThroughElements != null
- ? passThroughElements
- : _NO_PASS_THROUGH_ELEMENTS;
- }
-
- /**
- * Advance the current position and return the character at the new current position.
- *
- * @return the character at the new current position
- */
- int advance();
-
- /**
- * Return the substring of the source code between the start offset and the modified current
- * position. The current position is modified by adding the end delta.
- *
- * @param start the offset to the beginning of the string, relative to the start of the file
- * @param endDelta the number of character after the current location to be included in the
- * string, or the number of characters before the current location to be excluded if the
- * offset is negative
- * @return the specified substring of the source code
- */
- String getString(int start, int endDelta);
-
- /**
- * Return the character at the current position without changing the current position.
- *
- * @return the character at the current position
- */
- int peek();
-
- /**
- * Record the fact that we are at the beginning of a new line in the source.
- */
- void recordStartOfLine() {
- _lineStarts.add(offset);
- }
-
- /**
- * Scan the source code to produce a list of tokens representing the source.
- *
- * @return the first token in the list of tokens that were produced
- */
- Token tokenize() {
- _scan();
- _appendEofToken();
- return _firstToken();
- }
-
- void _appendEofToken() {
- Token eofToken = new Token.con1(TokenType.EOF, offset);
- // The EOF token points to itself so that there is always infinite
- // look-ahead.
- eofToken.setNext(eofToken);
- _tail = _tail.setNext(eofToken);
- }
-
- Token _emit(Token token) {
- _tail.setNext(token);
- _tail = token;
- return token;
- }
-
- Token _emitWithOffset(TokenType type, int start) =>
- _emit(new Token.con1(type, start));
-
- Token _emitWithOffsetAndLength(TokenType type, int start, int count) =>
- _emit(new Token.con2(type, start, getString(start, count)));
-
- Token _firstToken() => _tokens.next;
-
- int _recordStartOfLineAndAdvance(int c) {
- if (c == 0xD) {
- c = advance();
- if (c == 0xA) {
- c = advance();
- }
- recordStartOfLine();
- } else if (c == 0xA) {
- c = advance();
- recordStartOfLine();
- } else {
- c = advance();
- }
- return c;
- }
-
- void _scan() {
- bool inBrackets = false;
- String endPassThrough = null;
- int c = advance();
- while (c >= 0) {
- int start = offset;
- if (c == 0x3C) {
- c = advance();
- if (c == 0x21) {
- c = advance();
- if (c == 0x2D && peek() == 0x2D) {
- // handle a comment
- c = advance();
- int dashCount = 1;
- while (c >= 0) {
- if (c == 0x2D) {
- dashCount++;
- } else if (c == 0x3E && dashCount >= 2) {
- c = advance();
- break;
- } else {
- dashCount = 0;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.COMMENT, start, -1);
- // Capture <!--> and <!---> as tokens but report an error
- if (_tail.length < 7) {
- // TODO (danrubel): Report invalid HTML comment
- }
- } else {
- // handle a declaration
- while (c >= 0) {
- if (c == 0x3E) {
- c = advance();
- break;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.DECLARATION, start, -1);
- if (!StringUtilities.endsWithChar(_tail.lexeme, 0x3E)) {
- // TODO (danrubel): Report missing '>' in directive
- }
- }
- } else if (c == 0x3F) {
- // handle a directive
- while (c >= 0) {
- if (c == 0x3F) {
- c = advance();
- if (c == 0x3E) {
- c = advance();
- break;
- }
- } else {
- c = _recordStartOfLineAndAdvance(c);
- }
- }
- _emitWithOffsetAndLength(TokenType.DIRECTIVE, start, -1);
- if (_tail.length < 4) {
- // TODO (danrubel): Report invalid directive
- }
- } else if (c == 0x2F) {
- _emitWithOffset(TokenType.LT_SLASH, start);
- inBrackets = true;
- c = advance();
- } else {
- inBrackets = true;
- _emitWithOffset(TokenType.LT, start);
- // ignore whitespace in braces
- while (Character.isWhitespace(c)) {
- c = _recordStartOfLineAndAdvance(c);
- }
- // get tag
- if (Character.isLetterOrDigit(c)) {
- int tagStart = offset;
- c = advance();
- while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
- c = advance();
- }
- _emitWithOffsetAndLength(TokenType.TAG, tagStart, -1);
- // check tag against passThrough elements
- String tag = _tail.lexeme;
- for (String str in _passThroughElements) {
- if (str == tag) {
- endPassThrough = "</$str>";
- break;
- }
- }
- }
- }
- } else if (c == 0x3E) {
- _emitWithOffset(TokenType.GT, start);
- inBrackets = false;
- c = advance();
- // if passThrough != null, read until we match it
- if (endPassThrough != null) {
- bool endFound = false;
- int len = endPassThrough.length;
- int firstC = endPassThrough.codeUnitAt(0);
- int index = 0;
- int nextC = firstC;
- while (c >= 0) {
- if (c == nextC) {
- index++;
- if (index == len) {
- endFound = true;
- break;
- }
- nextC = endPassThrough.codeUnitAt(index);
- } else if (c == firstC) {
- index = 1;
- nextC = endPassThrough.codeUnitAt(1);
- } else {
- index = 0;
- nextC = firstC;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- if (start + 1 < offset) {
- if (endFound) {
- _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -len);
- _emitWithOffset(TokenType.LT_SLASH, offset - len + 1);
- _emitWithOffsetAndLength(TokenType.TAG, offset - len + 3, -1);
- } else {
- _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -1);
- }
- }
- endPassThrough = null;
- }
- } else if (c == 0x2F && peek() == 0x3E) {
- advance();
- _emitWithOffset(TokenType.SLASH_GT, start);
- inBrackets = false;
- c = advance();
- } else if (!inBrackets) {
- c = _recordStartOfLineAndAdvance(c);
- while (c != 0x3C && c >= 0) {
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.TEXT, start, -1);
- } else if (c == 0x22 || c == 0x27) {
- // read a string
- int endQuote = c;
- c = advance();
- while (c >= 0) {
- if (c == endQuote) {
- c = advance();
- break;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.STRING, start, -1);
- } else if (c == 0x3D) {
- // a non-char token
- _emitWithOffset(TokenType.EQ, start);
- c = advance();
- } else if (Character.isWhitespace(c)) {
- // ignore whitespace in braces
- do {
- c = _recordStartOfLineAndAdvance(c);
- } while (Character.isWhitespace(c));
- } else if (Character.isLetterOrDigit(c)) {
- c = advance();
- while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
- c = advance();
- }
- _emitWithOffsetAndLength(TokenType.TAG, start, -1);
- } else {
- // a non-char token
- _emitWithOffsetAndLength(TokenType.TEXT, start, 0);
- c = advance();
- }
- }
- }
-}
-
-/**
- * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class HtmlParser extends XmlParser {
- static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
-
- static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
-
- static String _SCRIPT = "script";
-
- static String _TYPE = "type";
-
- /**
- * A set containing the names of tags that do not have a closing tag.
- */
- static Set<String> SELF_CLOSING = new HashSet<String>.from(<String>[
- "area",
- "base",
- "basefont",
- "br",
- "col",
- "frame",
- "hr",
- "img",
- "input",
- "link",
- "meta",
- "param",
- "!"
- ]);
-
- /**
- * The line information associated with the source being parsed.
- */
- LineInfo _lineInfo;
-
- /**
- * The error listener to which errors will be reported.
- */
- final AnalysisErrorListener _errorListener;
-
- final AnalysisOptions _options;
-
- /**
- * Construct a parser for the specified source.
- *
- * [source] is the source being parsed. [_errorListener] is the error
- * listener to which errors will be reported. [_options] is the analysis
- * options which should be used for parsing.
- */
- HtmlParser(Source source, this._errorListener, this._options) : super(source);
-
- @override
- XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
- new XmlAttributeNode(name, equals, value);
-
- @override
- XmlTagNode createTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd) {
- if (_isScriptNode(tag, attributes, tagNodes)) {
- HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag,
- attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
- String contents = tagNode.content;
- int contentOffset = attributeEnd.end;
- LineInfo_Location location = _lineInfo.getLocation(contentOffset);
- sc.Scanner scanner = new sc.Scanner(source,
- new sc.SubSequenceReader(contents, contentOffset), _errorListener);
- scanner.setSourceStart(location.lineNumber, location.columnNumber);
- sc.Token firstToken = scanner.tokenize();
- Parser parser = new Parser(source, _errorListener);
- CompilationUnit unit = parser.parseCompilationUnit(firstToken);
- unit.lineInfo = _lineInfo;
- tagNode.script = unit;
- return tagNode;
- }
- return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
- }
-
- @override
- bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
-
- /**
- * Parse the given tokens.
- *
- * @param token the first token in the stream of tokens to be parsed
- * @param lineInfo the line information created by the scanner
- * @return the parse result (not `null`)
- */
- HtmlUnit parse(Token token, LineInfo lineInfo) {
- this._lineInfo = lineInfo;
- List<XmlTagNode> tagNodes = parseTopTagNodes(token);
- return new HtmlUnit(token, tagNodes, currentToken);
- }
-
- /**
- * Determine if the specified node is a Dart script.
- *
- * @param node the node to be tested (not `null`)
- * @return `true` if the node is a Dart script
- */
- bool _isScriptNode(
- Token tag, List<XmlAttributeNode> attributes, List<XmlTagNode> tagNodes) {
- if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) {
- return false;
- }
- for (XmlAttributeNode attribute in attributes) {
- if (attribute.name == _TYPE) {
- Token valueToken = attribute.valueToken;
- if (valueToken != null) {
- String value = valueToken.lexeme;
- if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES ||
- value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Given the contents of an embedded expression that occurs at the given offset, parse it as a
- * Dart expression. The contents should not include the expression's delimiters.
- *
- * @param source the source that contains that given token
- * @param token the token to start parsing from
- * @return the Dart expression that was parsed
- */
- static Expression parseEmbeddedExpression(
- Source source, sc.Token token, AnalysisErrorListener errorListener) {
- Parser parser = new Parser(source, errorListener);
- return parser.parseExpression(token);
- }
-
- /**
- * Given the contents of an embedded expression that occurs at the given offset, scans it as a
- * Dart code.
- *
- * @param source the source of that contains the given contents
- * @param contents the contents to scan
- * @param contentOffset the offset of the contents in the larger file
- * @return the first Dart token
- */
- static sc.Token scanDartSource(Source source, LineInfo lineInfo,
- String contents, int contentOffset, AnalysisErrorListener errorListener) {
- LineInfo_Location location = lineInfo.getLocation(contentOffset);
- sc.Scanner scanner = new sc.Scanner(source,
- new sc.SubSequenceReader(contents, contentOffset), errorListener);
- scanner.setSourceStart(location.lineNumber, location.columnNumber);
- return scanner.tokenize();
- }
-}
-
-/**
- * Instances of the class `HtmlScriptTagNode` represent a script tag within an HTML file that
- * references a Dart script.
- */
-@deprecated
-class HtmlScriptTagNode extends XmlTagNode {
- /**
- * The AST structure representing the Dart code within this tag.
- */
- CompilationUnit _script;
-
- /**
- * The element representing this script.
- */
- HtmlScriptElement scriptElement;
-
- /**
- * Initialize a newly created node to represent a script tag within an HTML file that references a
- * Dart script.
- *
- * @param nodeStart the token marking the beginning of the tag
- * @param tag the name of the tag
- * @param attributes the attributes in the tag
- * @param attributeEnd the token terminating the region where attributes can be
- * @param tagNodes the children of the tag
- * @param contentEnd the token that starts the closing tag
- * @param closingTag the name of the tag that occurs in the closing tag
- * @param nodeEnd the last token in the tag
- */
- HtmlScriptTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd)
- : super(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd,
- closingTag, nodeEnd);
-
- /**
- * Return the AST structure representing the Dart code within this tag, or `null` if this
- * tag references an external script.
- *
- * @return the AST structure representing the Dart code within this tag
- */
- CompilationUnit get script => _script;
-
- /**
- * Set the AST structure representing the Dart code within this tag to the given compilation unit.
- *
- * @param unit the AST structure representing the Dart code within this tag
- */
- void set script(CompilationUnit unit) {
- _script = unit;
- }
-
- @override
- accept(XmlVisitor visitor) => visitor.visitHtmlScriptTagNode(this);
-}
-
-/**
- * Instances of the class `HtmlUnit` represent the contents of an HTML file.
- */
-@deprecated
-class HtmlUnit extends XmlNode {
- /**
- * The first token in the token stream that was parsed to form this HTML unit.
- */
- final Token beginToken;
-
- /**
- * The last token in the token stream that was parsed to form this compilation unit. This token
- * should always have a type of [TokenType.EOF].
- */
- final Token endToken;
-
- /**
- * The tag nodes contained in the receiver (not `null`, contains no `null`s).
- */
- List<XmlTagNode> _tagNodes;
-
- /**
- * Construct a new instance representing the content of an HTML file.
- *
- * @param beginToken the first token in the file (not `null`)
- * @param tagNodes child tag nodes of the receiver (not `null`, contains no `null`s)
- * @param endToken the last token in the token stream which should be of type
- * [TokenType.EOF]
- */
- HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) {
- this._tagNodes = becomeParentOfAll(tagNodes);
- }
-
- /**
- * Return the element associated with this HTML unit.
- *
- * @return the element or `null` if the receiver is not resolved
- */
- @override
- HtmlElement get element => super.element as HtmlElement;
-
- @override
- void set element(Element element) {
- if (element != null && element is! HtmlElement) {
- throw new IllegalArgumentException(
- "HtmlElement expected, but ${element.runtimeType} given");
- }
- super.element = element;
- }
-
- /**
- * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
- * to edit the AST structure.
- *
- * @return the children (not `null`, contains no `null`s)
- */
- List<XmlTagNode> get tagNodes => _tagNodes;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
-
- @override
- void visitChildren(XmlVisitor visitor) {
- for (XmlTagNode node in _tagNodes) {
- node.accept(visitor);
- }
- }
-}
-
-/**
- * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
- * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
- * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
- * [XmlTagNode]s to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden visit method or must
- * explicitly ask the visited node to visit its children. Failure to do so will cause the children
- * of the visited node to not be visited.
- */
-class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
- @override
- R visitHtmlScriptTagNode(HtmlScriptTagNode node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitHtmlUnit(HtmlUnit node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitXmlAttributeNode(XmlAttributeNode node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitXmlTagNode(XmlTagNode node) {
- node.visitChildren(this);
- return null;
- }
-}
-
-/**
- * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
- * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
- * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
- * structure) and that only need to visit a small number of node types.
- */
-class SimpleXmlVisitor<R> implements XmlVisitor<R> {
- @override
- R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null;
-
- @override
- R visitHtmlUnit(HtmlUnit htmlUnit) => null;
-
- @override
- R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
-
- @override
- R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
-}
-
-/**
- * Instances of the class `StringScanner` implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- */
-class StringScanner extends AbstractScanner {
- /**
- * The string from which characters will be read.
- */
- final String _string;
-
- /**
- * The number of characters in the string.
- */
- int _stringLength = 0;
-
- /**
- * The index, relative to the string, of the last character that was read.
- */
- int _charOffset = 0;
-
- /**
- * Initialize a newly created scanner to scan the characters in the given string.
- *
- * @param source the source being scanned
- * @param string the string from which characters will be read
- */
- StringScanner(Source source, this._string) : super(source) {
- this._stringLength = _string.length;
- this._charOffset = -1;
- }
-
- @override
- int get offset => _charOffset;
-
- void set offset(int offset) {
- _charOffset = offset;
- }
-
- @override
- int advance() {
- if (++_charOffset < _stringLength) {
- return _string.codeUnitAt(_charOffset);
- }
- _charOffset = _stringLength;
- return -1;
- }
-
- @override
- String getString(int start, int endDelta) =>
- _string.substring(start, _charOffset + 1 + endDelta).toString();
-
- @override
- int peek() {
- if (_charOffset + 1 < _stringLength) {
- return _string.codeUnitAt(_charOffset + 1);
- }
- return -1;
- }
-}
-
-/**
- * Instances of the class `Token` represent a token that was scanned from the input. Each
- * token knows which token follows it, acting as the head of a linked list of tokens.
- */
-class Token {
- /**
- * The offset from the beginning of the file to the first character in the token.
- */
- final int offset;
-
- /**
- * The previous token in the token stream.
- */
- Token previous;
-
- /**
- * The next token in the token stream.
- */
- Token _next;
-
- /**
- * The type of the token.
- */
- final TokenType type;
-
- /**
- * The lexeme represented by this token.
- */
- String _value;
-
- /**
- * Initialize a newly created token.
- *
- * @param type the token type (not `null`)
- * @param offset the offset from the beginning of the file to the first character in the token
- */
- Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme);
-
- /**
- * Initialize a newly created token.
- *
- * @param type the token type (not `null`)
- * @param offset the offset from the beginning of the file to the first character in the token
- * @param value the lexeme represented by this token (not `null`)
- */
- Token.con2(this.type, this.offset, String value) {
- this._value = StringUtilities.intern(value);
- }
-
- /**
- * Return the offset from the beginning of the file to the character after last character of the
- * token.
- *
- * @return the offset from the beginning of the file to the first character after last character
- * of the token
- */
- int get end => offset + length;
-
- /**
- * Return `true` if this token is a synthetic token. A synthetic token is a token that was
- * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
- * have a length of zero (`0`).
- *
- * @return `true` if this token is a synthetic token
- */
- bool get isSynthetic => length == 0;
-
- /**
- * Return the number of characters in the node's source range.
- *
- * @return the number of characters in the node's source range
- */
- int get length => lexeme.length;
-
- /**
- * Return the lexeme that represents this token.
- *
- * @return the lexeme (not `null`)
- */
- String get lexeme => _value;
-
- /**
- * Return the next token in the token stream.
- *
- * @return the next token in the token stream
- */
- Token get next => _next;
-
- /**
- * Set the next token in the token stream to the given token. This has the side-effect of setting
- * this token to be the previous token for the given token.
- *
- * @param token the next token in the token stream
- * @return the token that was passed in
- */
- Token setNext(Token token) {
- _next = token;
- token.previous = this;
- return token;
- }
-
- @override
- String toString() => lexeme;
-}
-
-/**
- * The enumeration `TokenType` defines the types of tokens that can be returned by the
- * scanner.
- */
-class TokenType extends Enum<TokenType> {
- /**
- * The type of the token that marks the end of the input.
- */
- static const TokenType EOF = const TokenType_EOF('EOF', 0, "");
-
- static const TokenType EQ = const TokenType('EQ', 1, "=");
-
- static const TokenType GT = const TokenType('GT', 2, ">");
-
- static const TokenType LT_SLASH = const TokenType('LT_SLASH', 3, "</");
-
- static const TokenType LT = const TokenType('LT', 4, "<");
-
- static const TokenType SLASH_GT = const TokenType('SLASH_GT', 5, "/>");
-
- static const TokenType COMMENT = const TokenType('COMMENT', 6, null);
-
- static const TokenType DECLARATION = const TokenType('DECLARATION', 7, null);
-
- static const TokenType DIRECTIVE = const TokenType('DIRECTIVE', 8, null);
-
- static const TokenType STRING = const TokenType('STRING', 9, null);
-
- static const TokenType TAG = const TokenType('TAG', 10, null);
-
- static const TokenType TEXT = const TokenType('TEXT', 11, null);
-
- static const List<TokenType> values = const [
- EOF,
- EQ,
- GT,
- LT_SLASH,
- LT,
- SLASH_GT,
- COMMENT,
- DECLARATION,
- DIRECTIVE,
- STRING,
- TAG,
- TEXT
- ];
-
- /**
- * The lexeme that defines this type of token, or `null` if there is more than one possible
- * lexeme for this type of token.
- */
- final String lexeme;
-
- const TokenType(String name, int ordinal, this.lexeme) : super(name, ordinal);
-}
-
-class TokenType_EOF extends TokenType {
- const TokenType_EOF(String name, int ordinal, String arg0)
- : super(name, ordinal, arg0);
-
- @override
- String toString() => "-eof-";
-}
-
-/**
- * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
- * node (and all of it's children) to a writer.
- */
-class ToSourceVisitor implements XmlVisitor<Object> {
- /**
- * The writer to which the source is to be written.
- */
- final PrintWriter _writer;
-
- /**
- * Initialize a newly created visitor to write source code representing the visited nodes to the
- * given writer.
- *
- * @param writer the writer to which the source is to be written
- */
- ToSourceVisitor(this._writer);
-
- @override
- Object visitHtmlScriptTagNode(HtmlScriptTagNode node) =>
- visitXmlTagNode(node);
-
- @override
- Object visitHtmlUnit(HtmlUnit node) {
- for (XmlTagNode child in node.tagNodes) {
- _visit(child);
- }
- return null;
- }
-
- @override
- Object visitXmlAttributeNode(XmlAttributeNode node) {
- String name = node.name;
- Token value = node.valueToken;
- if (name.length == 0) {
- _writer.print("__");
- } else {
- _writer.print(name);
- }
- _writer.print("=");
- if (value == null) {
- _writer.print("__");
- } else {
- _writer.print(value.lexeme);
- }
- return null;
- }
-
- @override
- Object visitXmlTagNode(XmlTagNode node) {
- _writer.print("<");
- String tagName = node.tag;
- _writer.print(tagName);
- for (XmlAttributeNode attribute in node.attributes) {
- _writer.print(" ");
- _visit(attribute);
- }
- _writer.print(node.attributeEnd.lexeme);
- if (node.closingTag != null) {
- for (XmlTagNode child in node.tagNodes) {
- _visit(child);
- }
- _writer.print("</");
- _writer.print(tagName);
- _writer.print(">");
- }
- return null;
- }
-
- /**
- * Safely visit the given node.
- *
- * @param node the node to be visited
- */
- void _visit(XmlNode node) {
- if (node != null) {
- node.accept(this);
- }
- }
-}
-
-/**
- * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
- */
-class XmlAttributeNode extends XmlNode {
- /**
- * An empty list of XML attribute nodes.
- */
- static const List<XmlAttributeNode> EMPTY_LIST = const <XmlAttributeNode>[];
-
- final Token _name;
-
- final Token equals;
-
- final Token _value;
-
- List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
- /**
- * Construct a new instance representing an XML attribute.
- *
- * @param name the name token (not `null`). This may be a zero length token if the attribute
- * is badly formed.
- * @param equals the equals sign or `null` if none
- * @param value the value token (not `null`)
- */
- XmlAttributeNode(this._name, this.equals, this._value);
-
- @override
- Token get beginToken => _name;
-
- @override
- Token get endToken => _value;
-
- /**
- * Answer the attribute name. This may be a zero length string if the attribute is badly formed.
- *
- * @return the name (not `null`)
- */
- String get name => _name.lexeme;
-
- /**
- * Answer the attribute name token. This may be a zero length token if the attribute is badly
- * formed.
- *
- * @return the name token (not `null`)
- */
- Token get nameToken => _name;
-
- /**
- * Answer the lexeme for the value token without the leading and trailing quotes.
- *
- * @return the text or `null` if the value is not specified
- */
- String get text {
- if (_value == null) {
- return null;
- }
- //TODO (danrubel): replace HTML character encodings with the actual
- // characters
- String text = _value.lexeme;
- int len = text.length;
- if (len > 0) {
- if (text.codeUnitAt(0) == 0x22) {
- if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
- return text.substring(1, len - 1);
- } else {
- return text.substring(1);
- }
- } else if (text.codeUnitAt(0) == 0x27) {
- if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
- return text.substring(1, len - 1);
- } else {
- return text.substring(1);
- }
- }
- }
- return text;
- }
-
- /**
- * Answer the offset of the value after the leading quote.
- *
- * @return the offset of the value, or `-1` if the value is not specified
- */
- int get textOffset {
- if (_value == null) {
- return -1;
- }
- String text = _value.lexeme;
- if (StringUtilities.startsWithChar(text, 0x22) ||
- StringUtilities.startsWithChar(text, 0x27)) {
- return _value.offset + 1;
- }
- return _value.offset;
- }
-
- /**
- * Answer the attribute value token. A properly formed value will start and end with matching
- * quote characters, but the value returned may not be properly formed.
- *
- * @return the value token or `null` if this represents a badly formed attribute
- */
- Token get valueToken => _value;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
-
- @override
- void visitChildren(XmlVisitor visitor) {
- // no children to visit
- }
-}
-
-/**
- * Instances of the class `XmlExpression` represent an abstract expression embedded into
- * [XmlNode].
- */
-abstract class XmlExpression {
- /**
- * An empty list of expressions.
- */
- static const List<XmlExpression> EMPTY_ARRAY = const <XmlExpression>[];
-
- /**
- * Return the offset of the character immediately following the last character of this
- * expression's source range. This is equivalent to `getOffset() + getLength()`.
- *
- * @return the offset of the character just past the expression's source range
- */
- int get end;
-
- /**
- * Return the number of characters in the expression's source range.
- */
- int get length;
-
- /**
- * Return the offset of the first character in the expression's source range.
- */
- int get offset;
-
- /**
- * Check if the given offset belongs to the expression's source range.
- */
- bool contains(int offset) => this.offset <= offset && offset < end;
-
- /**
- * Return the [Reference] at the given offset.
- *
- * @param offset the offset from the beginning of the file
- * @return the [Reference] at the given offset, maybe `null`
- */
- XmlExpression_Reference getReference(int offset);
-}
-
-/**
- * The reference to the [Element].
- */
-class XmlExpression_Reference {
- Element element;
-
- int offset = 0;
-
- int length = 0;
-
- XmlExpression_Reference(this.element, this.offset, this.length);
-}
-
-/**
- * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
- */
-abstract class XmlNode {
- /**
- * The parent of the node, or `null` if the node is the root of an AST structure.
- */
- XmlNode _parent;
-
- /**
- * The element associated with this node or `null` if the receiver is not resolved.
- */
- Element _element;
-
- /**
- * Return the first token included in this node's source range.
- *
- * @return the first token or `null` if none
- */
- Token get beginToken;
-
- /**
- * Return the element associated with this node.
- *
- * @return the element or `null` if the receiver is not resolved
- */
- Element get element => _element;
-
- /**
- * Set the element associated with this node.
- *
- * @param element the element
- */
- void set element(Element element) {
- this._element = element;
- }
-
- /**
- * Return the offset of the character immediately following the last character of this node's
- * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
- * unit this will be equal to the length of the unit's source.
- *
- * @return the offset of the character just past the node's source range
- */
- int get end => offset + length;
-
- /**
- * Return the last token included in this node's source range.
- *
- * @return the last token or `null` if none
- */
- Token get endToken;
-
- /**
- * Return the number of characters in the node's source range.
- *
- * @return the number of characters in the node's source range
- */
- int get length {
- Token beginToken = this.beginToken;
- Token endToken = this.endToken;
- if (beginToken == null || endToken == null) {
- return -1;
- }
- return endToken.offset + endToken.length - beginToken.offset;
- }
-
- /**
- * Return the offset from the beginning of the file to the first character in the node's source
- * range.
- *
- * @return the offset from the beginning of the file to the first character in the node's source
- * range
- */
- int get offset {
- Token beginToken = this.beginToken;
- if (beginToken == null) {
- return -1;
- }
- return this.beginToken.offset;
- }
-
- /**
- * Return this node's parent node, or `null` if this node is the root of an AST structure.
- *
- * Note that the relationship between an AST node and its parent node may change over the lifetime
- * of a node.
- *
- * @return the parent of this node, or `null` if none
- */
- XmlNode get parent => _parent;
-
- /**
- * Set the parent of this node to the given node.
- *
- * @param newParent the node that is to be made the parent of this node
- */
- void set parent(XmlNode newParent) {
- XmlNode current = newParent;
- while (current != null) {
- if (identical(current, this)) {
- AnalysisEngine.instance.logger.logError(
- "Circular structure while setting an XML node's parent",
- new CaughtException(
- new ArgumentError(_buildRecursiveStructureMessage(newParent)),
- null));
- return;
- }
- current = current.parent;
- }
- _parent = newParent;
- }
-
- /**
- * Use the given visitor to visit this node.
- *
- * @param visitor the visitor that will visit this node
- * @return the value returned by the visitor as a result of visiting this node
- */
- accept(XmlVisitor visitor);
-
- /**
- * Make this node the parent of the given child node.
- *
- * @param child the node that will become a child of this node
- * @return the node that was made a child of this node
- */
- XmlNode becomeParentOf(XmlNode child) {
- if (child != null) {
- XmlNode node = child;
- node.parent = this;
- }
- return child;
- }
-
- /**
- * Make this node the parent of the given child nodes.
- *
- * @param children the nodes that will become the children of this node
- * @param ifEmpty the (empty) nodes to return if "children" is empty
- * @return the nodes that were made children of this node
- */
- List becomeParentOfAll(List children, {List ifEmpty}) {
- if (children == null || children.isEmpty) {
- if (ifEmpty != null) {
- return ifEmpty;
- }
- }
- if (children != null) {
- children.forEach((XmlNode node) {
- node.parent = this;
- });
- }
- return children;
- }
-
- @override
- String toString() {
- PrintStringWriter writer = new PrintStringWriter();
- accept(new ToSourceVisitor(writer));
- return writer.toString();
- }
-
- /**
- * Use the given visitor to visit all of the children of this node. The children will be visited
- * in source order.
- *
- * @param visitor the visitor that will be used to visit the children of this node
- */
- void visitChildren(XmlVisitor visitor);
-
- /**
- * This method exists for debugging purposes only.
- */
- void _appendIdentifier(StringBuffer buffer, XmlNode node) {
- if (node is XmlTagNode) {
- buffer.write(node.tag);
- } else if (node is XmlAttributeNode) {
- buffer.write(node.name);
- } else {
- buffer.write("htmlUnit");
- }
- }
-
- /**
- * This method exists for debugging purposes only.
- */
- String _buildRecursiveStructureMessage(XmlNode newParent) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Attempt to create recursive structure: ");
- XmlNode current = newParent;
- while (current != null) {
- if (!identical(current, newParent)) {
- buffer.write(" -> ");
- }
- if (identical(current, this)) {
- buffer.writeCharCode(0x2A);
- _appendIdentifier(buffer, current);
- buffer.writeCharCode(0x2A);
- } else {
- _appendIdentifier(buffer, current);
- }
- current = current.parent;
- }
- return buffer.toString();
- }
-}
-
-/**
- * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class XmlParser {
- /**
- * The source being parsed.
- */
- final Source source;
-
- /**
- * The next token to be parsed.
- */
- Token _currentToken;
-
- /**
- * Construct a parser for the specified source.
- *
- * @param source the source being parsed
- */
- XmlParser(this.source);
-
- /**
- * Answer the current token.
- *
- * @return the current token
- */
- Token get currentToken => _currentToken;
-
- /**
- * Create a node representing an attribute.
- *
- * @param name the name of the attribute
- * @param equals the equals sign, or `null` if there is no value
- * @param value the value of the attribute
- * @return the node that was created
- */
- XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
- new XmlAttributeNode(name, equals, value);
-
- /**
- * Create a node representing a tag.
- *
- * @param nodeStart the token marking the beginning of the tag
- * @param tag the name of the tag
- * @param attributes the attributes in the tag
- * @param attributeEnd the token terminating the region where attributes can be
- * @param tagNodes the children of the tag
- * @param contentEnd the token that starts the closing tag
- * @param closingTag the name of the tag that occurs in the closing tag
- * @param nodeEnd the last token in the tag
- * @return the node that was created
- */
- XmlTagNode createTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd) =>
- new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
-
- /**
- * Answer `true` if the specified tag is self closing and thus should never have content or
- * child tag nodes.
- *
- * @param tag the tag (not `null`)
- * @return `true` if self closing
- */
- bool isSelfClosing(Token tag) => false;
-
- /**
- * Parse the entire token stream and in the process, advance the current token to the end of the
- * token stream.
- *
- * @return the list of tag nodes found (not `null`, contains no `null`)
- */
- List<XmlTagNode> parseTopTagNodes(Token firstToken) {
- _currentToken = firstToken;
- List<XmlTagNode> tagNodes = new List<XmlTagNode>();
- TokenType type = _currentToken.type;
- while (type != TokenType.EOF) {
- if (type == TokenType.LT) {
- tagNodes.add(_parseTagNode());
- } else if (type == TokenType.DECLARATION ||
- type == TokenType.DIRECTIVE ||
- type == TokenType.COMMENT) {
- // ignored tokens
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return tagNodes;
- }
-
- /**
- * Insert a synthetic token of the specified type before the current token
- *
- * @param type the type of token to be inserted (not `null`)
- * @return the synthetic token that was inserted (not `null`)
- */
- Token _insertSyntheticToken(TokenType type) {
- Token token = new Token.con2(type, _currentToken.offset, "");
- _currentToken.previous.setNext(token);
- token.setNext(_currentToken);
- return token;
- }
-
- /**
- * Parse the token stream for an attribute. This method advances the current token over the
- * attribute, but should not be called if the [currentToken] is not [TokenType.TAG].
- *
- * @return the attribute (not `null`)
- */
- XmlAttributeNode _parseAttribute() {
- // Assume the current token is a tag
- Token name = _currentToken;
- _currentToken = _currentToken.next;
- // Equals sign
- Token equals;
- if (_currentToken.type == TokenType.EQ) {
- equals = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- equals = _insertSyntheticToken(TokenType.EQ);
- }
- // String value
- Token value;
- if (_currentToken.type == TokenType.STRING) {
- value = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- value = _insertSyntheticToken(TokenType.STRING);
- }
- return createAttributeNode(name, equals, value);
- }
-
- /**
- * Parse the stream for a sequence of attributes. This method advances the current token to the
- * next [TokenType.GT], [TokenType.SLASH_GT], or [TokenType.EOF].
- *
- * @return a collection of zero or more attributes (not `null`, contains no `null`s)
- */
- List<XmlAttributeNode> _parseAttributes() {
- TokenType type = _currentToken.type;
- if (type == TokenType.GT ||
- type == TokenType.SLASH_GT ||
- type == TokenType.EOF) {
- return XmlTagNode.NO_ATTRIBUTES;
- }
- List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
- while (type != TokenType.GT &&
- type != TokenType.SLASH_GT &&
- type != TokenType.EOF) {
- if (type == TokenType.TAG) {
- attributes.add(_parseAttribute());
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return attributes;
- }
-
- /**
- * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
- * advances the current token to the next [TokenType.LT_SLASH] or [TokenType.EOF].
- *
- * @return a list of nodes (not `null`, contains no `null`s)
- */
- List<XmlTagNode> _parseChildTagNodes() {
- TokenType type = _currentToken.type;
- if (type == TokenType.LT_SLASH || type == TokenType.EOF) {
- return XmlTagNode.NO_TAG_NODES;
- }
- List<XmlTagNode> nodes = new List<XmlTagNode>();
- while (type != TokenType.LT_SLASH && type != TokenType.EOF) {
- if (type == TokenType.LT) {
- nodes.add(_parseTagNode());
- } else if (type == TokenType.COMMENT) {
- // ignored token
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return nodes;
- }
-
- /**
- * Parse the token stream for the next tag node. This method advances current token over the
- * parsed tag node, but should only be called if the current token is [TokenType.LT]
- *
- * @return the tag node or `null` if none found
- */
- XmlTagNode _parseTagNode() {
- // Assume that the current node is a tag node start TokenType.LT
- Token nodeStart = _currentToken;
- _currentToken = _currentToken.next;
- // Get the tag or create a synthetic tag and report an error
- Token tag;
- if (_currentToken.type == TokenType.TAG) {
- tag = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- tag = _insertSyntheticToken(TokenType.TAG);
- }
- // Parse the attributes
- List<XmlAttributeNode> attributes = _parseAttributes();
- // Token ending attribute list
- Token attributeEnd;
- if (_currentToken.type == TokenType.GT ||
- _currentToken.type == TokenType.SLASH_GT) {
- attributeEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT);
- }
- // If the node has no children, then return the node
- if (attributeEnd.type == TokenType.SLASH_GT || isSelfClosing(tag)) {
- return createTagNode(nodeStart, tag, attributes, attributeEnd,
- XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
- }
- // Parse the child tag nodes
- List<XmlTagNode> tagNodes = _parseChildTagNodes();
- // Token ending child tag nodes
- Token contentEnd;
- if (_currentToken.type == TokenType.LT_SLASH) {
- contentEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- // TODO (danrubel): handle self closing HTML elements by inserting
- // synthetic tokens but not reporting an error
- _reportUnexpectedToken();
- contentEnd = _insertSyntheticToken(TokenType.LT_SLASH);
- }
- // Closing tag
- Token closingTag;
- if (_currentToken.type == TokenType.TAG) {
- closingTag = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- closingTag = _insertSyntheticToken(TokenType.TAG);
- }
- // Token ending node
- Token nodeEnd;
- if (_currentToken.type == TokenType.GT) {
- nodeEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- nodeEnd = _insertSyntheticToken(TokenType.GT);
- }
- return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
- }
-
- /**
- * Report the current token as unexpected
- */
- void _reportUnexpectedToken() {
- // TODO (danrubel): report unexpected token
- }
-}
-
-/**
- * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
- * `<body foo="bar"> ... </body>`.
- */
-class XmlTagNode extends XmlNode {
- /**
- * Constant representing empty list of attributes.
- */
- static List<XmlAttributeNode> NO_ATTRIBUTES =
- new UnmodifiableListView(new List<XmlAttributeNode>());
-
- /**
- * Constant representing empty list of tag nodes.
- */
- static List<XmlTagNode> NO_TAG_NODES =
- new UnmodifiableListView(new List<XmlTagNode>());
-
- /**
- * The starting [TokenType.LT] token (not `null`).
- */
- final Token nodeStart;
-
- /**
- * The [TokenType.TAG] token after the starting '&lt;' (not `null`).
- */
- final Token _tag;
-
- /**
- * The attributes contained by the receiver (not `null`, contains no `null`s).
- */
- List<XmlAttributeNode> _attributes;
-
- /**
- * The [TokenType.GT] or [TokenType.SLASH_GT] token after the attributes (not
- * `null`). The token may be the same token as [nodeEnd] if there are no child
- * [tagNodes].
- */
- final Token attributeEnd;
-
- /**
- * The tag nodes contained in the receiver (not `null`, contains no `null`s).
- */
- List<XmlTagNode> _tagNodes;
-
- /**
- * The token (not `null`) after the content, which may be
- * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
- * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is self
- * closing or the attributeEnd is [TokenType.SLASH_GT], or
- * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last node in
- * the stream [TokenType.LT_SLASH] token after the content, or `null` if there is no
- * content and the attributes ended with [TokenType.SLASH_GT].
- */
- final Token contentEnd;
-
- /**
- * The closing [TokenType.TAG] after the child elements or `null` if there is no
- * content and the attributes ended with [TokenType.SLASH_GT]
- */
- final Token closingTag;
-
- /**
- * The ending [TokenType.GT] or [TokenType.SLASH_GT] token (not `null`).
- */
- final Token nodeEnd;
-
- /**
- * The expressions that are embedded in the tag's content.
- */
- List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
- /**
- * Construct a new instance representing an XML or HTML element
- *
- * @param nodeStart the starting [TokenType.LT] token (not `null`)
- * @param tag the [TokenType.TAG] token after the starting '&lt;' (not `null`).
- * @param attributes the attributes associated with this element or [NO_ATTRIBUTES] (not
- * `null`, contains no `null`s)
- * @param attributeEnd The [TokenType.GT] or [TokenType.SLASH_GT] token after the
- * attributes (not `null`). The token may be the same token as [nodeEnd] if
- * there are no child [tagNodes].
- * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `null`,
- * contains no `null`s)
- * @param contentEnd the token (not `null`) after the content, which may be
- * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
- * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is
- * self closing or the attributeEnd is [TokenType.SLASH_GT], or
- * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last
- * node in the stream [TokenType.LT_SLASH] token after the content, or `null`
- * if there is no content and the attributes ended with [TokenType.SLASH_GT].
- * @param closingTag the closing [TokenType.TAG] after the child elements or `null` if
- * there is no content and the attributes ended with [TokenType.SLASH_GT]
- * @param nodeEnd the ending [TokenType.GT] or [TokenType.SLASH_GT] token (not
- * `null`)
- */
- XmlTagNode(
- this.nodeStart,
- this._tag,
- List<XmlAttributeNode> attributes,
- this.attributeEnd,
- List<XmlTagNode> tagNodes,
- this.contentEnd,
- this.closingTag,
- this.nodeEnd) {
- this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES);
- this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES);
- }
-
- /**
- * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
- * AST structure.
- *
- * @return the attributes (not `null`, contains no `null`s)
- */
- List<XmlAttributeNode> get attributes => _attributes;
-
- @override
- Token get beginToken => nodeStart;
-
- /**
- * Return a string representing the content contained in the receiver. This
- * includes the textual representation of any child tag nodes ([getTagNodes]).
- * Whitespace between '&lt;', '&lt;/', and '>', '/>' is discarded, but all
- * other whitespace is preserved.
- */
- String get content {
- Token token = attributeEnd.next;
- if (identical(token, contentEnd)) {
- return "";
- }
- // TODO(danrubel) Handle CDATA and replace HTML character encodings with
- // the actual characters.
- String content = token.lexeme;
- token = token.next;
- if (identical(token, contentEnd)) {
- return content;
- }
- StringBuffer buffer = new StringBuffer();
- buffer.write(content);
- while (!identical(token, contentEnd)) {
- buffer.write(token.lexeme);
- token = token.next;
- }
- return buffer.toString();
- }
-
- @override
- Token get endToken {
- if (nodeEnd != null) {
- return nodeEnd;
- }
- if (closingTag != null) {
- return closingTag;
- }
- if (contentEnd != null) {
- return contentEnd;
- }
- if (!_tagNodes.isEmpty) {
- return _tagNodes[_tagNodes.length - 1].endToken;
- }
- if (attributeEnd != null) {
- return attributeEnd;
- }
- if (!_attributes.isEmpty) {
- return _attributes[_attributes.length - 1].endToken;
- }
- return _tag;
- }
-
- /**
- * Answer the tag name after the starting '&lt;'.
- *
- * @return the tag name (not `null`)
- */
- String get tag => _tag.lexeme;
-
- /**
- * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
- * to edit the AST structure.
- *
- * @return the children (not `null`, contains no `null`s)
- */
- List<XmlTagNode> get tagNodes => _tagNodes;
-
- /**
- * Answer the [TokenType.TAG] token after the starting '&lt;'.
- *
- * @return the token (not `null`)
- */
- Token get tagToken => _tag;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
-
- /**
- * Answer the attribute with the specified name.
- *
- * @param name the attribute name
- * @return the attribute or `null` if no matching attribute is found
- */
- XmlAttributeNode getAttribute(String name) {
- for (XmlAttributeNode attribute in _attributes) {
- if (attribute.name == name) {
- return attribute;
- }
- }
- return null;
- }
-
- /**
- * Find the attribute with the given name (see [getAttribute] and answer the lexeme
- * for the attribute's value token without the leading and trailing quotes (see
- * [XmlAttributeNode.getText]).
- *
- * @param name the attribute name
- * @return the attribute text or `null` if no matching attribute is found
- */
- String getAttributeText(String name) {
- XmlAttributeNode attribute = getAttribute(name);
- return attribute != null ? attribute.text : null;
- }
-
- @override
- void visitChildren(XmlVisitor visitor) {
- for (XmlAttributeNode node in _attributes) {
- node.accept(visitor);
- }
- for (XmlTagNode node in _tagNodes) {
- node.accept(visitor);
- }
- }
-}
-
-/**
- * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an
- * [XmlNode] structure.
- */
-abstract class XmlVisitor<R> {
- R visitHtmlScriptTagNode(HtmlScriptTagNode node);
-
- R visitHtmlUnit(HtmlUnit htmlUnit);
-
- R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
-
- R visitXmlTagNode(XmlTagNode xmlTagNode);
-}
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/lib/src/generated/java_core.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698