| Index: pkg/analyzer_experimental/lib/src/generated/html.dart
|
| diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer_experimental/lib/src/generated/html.dart
|
| deleted file mode 100644
|
| index f5286bc5a6363f1b9e0506b2afb64c0d9210c744..0000000000000000000000000000000000000000
|
| --- a/pkg/analyzer_experimental/lib/src/generated/html.dart
|
| +++ /dev/null
|
| @@ -1,1535 +0,0 @@
|
| -// This code was auto-generated, is not intended to be edited, and is subject to
|
| -// significant change. Please see the README file for more information.
|
| -library engine.html;
|
| -import 'dart:collection';
|
| -import 'java_core.dart';
|
| -import 'java_engine.dart';
|
| -import 'source.dart';
|
| -import 'element.dart' show HtmlElementImpl;
|
| -import 'engine.dart' show AnalysisEngine;
|
| -/**
|
| - * 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.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class Token {
|
| -
|
| - /**
|
| - * The offset from the beginning of the file to the first character in the token.
|
| - */
|
| - int offset = 0;
|
| -
|
| - /**
|
| - * The previous token in the token stream.
|
| - */
|
| - Token previous;
|
| -
|
| - /**
|
| - * The next token in the token stream.
|
| - */
|
| - Token next;
|
| -
|
| - /**
|
| - * The type of the token.
|
| - */
|
| - TokenType type;
|
| -
|
| - /**
|
| - * The lexeme represented by this token.
|
| - */
|
| - String 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
|
| - */
|
| - 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(TokenType type, int offset, String value) {
|
| - this.type = type;
|
| - this.lexeme = StringUtilities.intern(value);
|
| - this.offset = offset;
|
| - }
|
| -
|
| - /**
|
| - * 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 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 `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;
|
| -
|
| - /**
|
| - * 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;
|
| - }
|
| - String toString() => lexeme;
|
| -}
|
| -/**
|
| - * Instances of `HtmlParseResult` hold the result of parsing an HTML file.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class HtmlParseResult extends HtmlScanResult {
|
| -
|
| - /**
|
| - * The unit containing the parsed information (not `null`).
|
| - */
|
| - HtmlUnit htmlUnit;
|
| - HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlUnit unit) : super(modificationTime, token, lineStarts) {
|
| - this.htmlUnit = unit;
|
| - }
|
| -}
|
| -/**
|
| - * 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.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
|
| - R visitHtmlUnit(HtmlUnit node) {
|
| - node.visitChildren(this);
|
| - return null;
|
| - }
|
| - R visitXmlAttributeNode(XmlAttributeNode node) {
|
| - node.visitChildren(this);
|
| - return null;
|
| - }
|
| - R visitXmlTagNode(XmlTagNode node) {
|
| - node.visitChildren(this);
|
| - return null;
|
| - }
|
| -}
|
| -/**
|
| - * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -abstract class XmlNode {
|
| -
|
| - /**
|
| - * The parent of the node, or `null` if the node is the root of an AST structure.
|
| - */
|
| - XmlNode _parent;
|
| -
|
| - /**
|
| - * 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);
|
| -
|
| - /**
|
| - * Return the first token included in this node's source range.
|
| - *
|
| - * @return the first token or `null` if none
|
| - */
|
| - Token get beginToken;
|
| -
|
| - /**
|
| - * 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;
|
| - 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);
|
| -
|
| - /**
|
| - * Make this node the parent of the given child nodes.
|
| - *
|
| - * @param children the nodes that will become the children of this node
|
| - * @return the nodes that were made children of this node
|
| - */
|
| - List becomeParentOf(List children) {
|
| - if (children != null) {
|
| - for (JavaIterator iter = new JavaIterator(children); iter.hasNext;) {
|
| - XmlNode node = iter.next();
|
| - node.parent = this;
|
| - }
|
| - return new List.from(children);
|
| - }
|
| - return children;
|
| - }
|
| -
|
| - /**
|
| - * 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 becomeParentOf2(XmlNode child) {
|
| - if (child != null) {
|
| - XmlNode node = child;
|
| - node.parent = this;
|
| - }
|
| - return child;
|
| - }
|
| -
|
| - /**
|
| - * This method exists for debugging purposes only.
|
| - */
|
| - void appendIdentifier(JavaStringBuilder builder, XmlNode node) {
|
| - if (node is XmlTagNode) {
|
| - builder.append(((node as XmlTagNode)).tag.lexeme);
|
| - } else if (node is XmlAttributeNode) {
|
| - builder.append(((node as XmlAttributeNode)).name.lexeme);
|
| - } else {
|
| - builder.append("htmlUnit");
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * This method exists for debugging purposes only.
|
| - */
|
| - String buildRecursiveStructureMessage(XmlNode newParent) {
|
| - JavaStringBuilder builder = new JavaStringBuilder();
|
| - builder.append("Attempt to create recursive structure: ");
|
| - XmlNode current = newParent;
|
| - while (current != null) {
|
| - if (current != newParent) {
|
| - builder.append(" -> ");
|
| - }
|
| - if (identical(current, this)) {
|
| - builder.appendChar(0x2A);
|
| - appendIdentifier(builder, current);
|
| - builder.appendChar(0x2A);
|
| - } else {
|
| - appendIdentifier(builder, current);
|
| - }
|
| - current = current.parent;
|
| - }
|
| - return builder.toString();
|
| - }
|
| -
|
| - /**
|
| - * 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.logError3(new IllegalArgumentException(buildRecursiveStructureMessage(newParent)));
|
| - return;
|
| - }
|
| - current = current.parent;
|
| - }
|
| - _parent = newParent;
|
| - }
|
| -}
|
| -/**
|
| - * 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> {
|
| - R visitHtmlUnit(HtmlUnit htmlUnit) => null;
|
| - R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
|
| - R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
|
| -}
|
| -/**
|
| - * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
|
| - * required to implement the interface used to access the characters being scanned.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -abstract class AbstractScanner {
|
| - static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
|
| -
|
| - /**
|
| - * The source being scanned.
|
| - */
|
| - 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(Source source) {
|
| - this.source = 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;
|
| - }
|
| -
|
| - /**
|
| - * 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();
|
| - }
|
| -
|
| - /**
|
| - * 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);
|
| - }
|
| - void appendEofToken() {
|
| - Token eofToken = new Token.con1(TokenType.EOF, offset);
|
| - eofToken.setNext(eofToken);
|
| - _tail = _tail.setNext(eofToken);
|
| - }
|
| - Token emit(Token token) {
|
| - _tail.setNext(token);
|
| - _tail = token;
|
| - return token;
|
| - }
|
| - Token emit2(TokenType type, int start) => emit(new Token.con1(type, start));
|
| - Token emit3(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) {
|
| - 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);
|
| - }
|
| - emit3(TokenType.COMMENT, start, -1);
|
| - if (_tail.length < 7) {
|
| - }
|
| - } else {
|
| - while (c >= 0) {
|
| - if (c == 0x3E) {
|
| - c = advance();
|
| - break;
|
| - }
|
| - c = recordStartOfLineAndAdvance(c);
|
| - }
|
| - emit3(TokenType.DECLARATION, start, -1);
|
| - if (!_tail.lexeme.endsWith(">")) {
|
| - }
|
| - }
|
| - } else if (c == 0x3F) {
|
| - while (c >= 0) {
|
| - if (c == 0x3F) {
|
| - c = advance();
|
| - if (c == 0x3E) {
|
| - c = advance();
|
| - break;
|
| - }
|
| - } else {
|
| - c = recordStartOfLineAndAdvance(c);
|
| - }
|
| - }
|
| - emit3(TokenType.DIRECTIVE, start, -1);
|
| - if (_tail.length < 4) {
|
| - }
|
| - } else if (c == 0x2F) {
|
| - emit2(TokenType.LT_SLASH, start);
|
| - inBrackets = true;
|
| - c = advance();
|
| - } else {
|
| - inBrackets = true;
|
| - emit2(TokenType.LT, start);
|
| - while (Character.isWhitespace(c)) {
|
| - c = recordStartOfLineAndAdvance(c);
|
| - }
|
| - if (Character.isLetterOrDigit(c)) {
|
| - int tagStart = offset;
|
| - c = advance();
|
| - while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
|
| - c = advance();
|
| - }
|
| - emit3(TokenType.TAG, tagStart, -1);
|
| - String tag = _tail.lexeme;
|
| - for (String str in _passThroughElements) {
|
| - if (str == tag) {
|
| - endPassThrough = "</${str}>";
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - } else if (c == 0x3E) {
|
| - emit2(TokenType.GT, start);
|
| - inBrackets = false;
|
| - c = advance();
|
| - 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) {
|
| - emit3(TokenType.TEXT, start + 1, -len);
|
| - emit2(TokenType.LT_SLASH, offset - len + 1);
|
| - emit3(TokenType.TAG, offset - len + 3, -1);
|
| - } else {
|
| - emit3(TokenType.TEXT, start + 1, -1);
|
| - }
|
| - }
|
| - endPassThrough = null;
|
| - }
|
| - } else if (c == 0x2F && peek() == 0x3E) {
|
| - advance();
|
| - emit2(TokenType.SLASH_GT, start);
|
| - inBrackets = false;
|
| - c = advance();
|
| - } else if (!inBrackets) {
|
| - c = recordStartOfLineAndAdvance(c);
|
| - while (c != 0x3C && c >= 0) {
|
| - c = recordStartOfLineAndAdvance(c);
|
| - }
|
| - emit3(TokenType.TEXT, start, -1);
|
| - } else if (c == 0x22 || c == 0x27) {
|
| - int endQuote = c;
|
| - c = advance();
|
| - while (c >= 0) {
|
| - if (c == endQuote) {
|
| - c = advance();
|
| - break;
|
| - }
|
| - c = recordStartOfLineAndAdvance(c);
|
| - }
|
| - emit3(TokenType.STRING, start, -1);
|
| - } else if (c == 0x3D) {
|
| - emit2(TokenType.EQ, start);
|
| - c = advance();
|
| - } else if (Character.isWhitespace(c)) {
|
| - 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();
|
| - }
|
| - emit3(TokenType.TAG, start, -1);
|
| - } else {
|
| - emit3(TokenType.TEXT, start, 0);
|
| - c = advance();
|
| - }
|
| - }
|
| - }
|
| -}
|
| -/**
|
| - * Instances of `HtmlScanResult` hold the result of scanning an HTML file.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class HtmlScanResult {
|
| -
|
| - /**
|
| - * The time at which the contents of the source were last set.
|
| - */
|
| - int modificationTime = 0;
|
| -
|
| - /**
|
| - * The first token in the token stream (not `null`).
|
| - */
|
| - Token token;
|
| -
|
| - /**
|
| - * The line start information that was produced.
|
| - */
|
| - List<int> lineStarts;
|
| - HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) {
|
| - this.modificationTime = modificationTime;
|
| - this.token = token;
|
| - this.lineStarts = lineStarts;
|
| - }
|
| -}
|
| -/**
|
| - * Instances of the class `StringScanner` implement a scanner that reads from a string. The
|
| - * scanning logic is in the superclass.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class StringScanner extends AbstractScanner {
|
| -
|
| - /**
|
| - * The string from which characters will be read.
|
| - */
|
| - 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, String string) : super(source) {
|
| - this._string = string;
|
| - this._stringLength = string.length;
|
| - this._charOffset = -1;
|
| - }
|
| - int get offset => _charOffset;
|
| - void set offset(int offset) {
|
| - _charOffset = offset;
|
| - }
|
| - int advance() {
|
| - if (++_charOffset < _stringLength) {
|
| - return _string.codeUnitAt(_charOffset);
|
| - }
|
| - _charOffset = _stringLength;
|
| - return -1;
|
| - }
|
| - String getString(int start, int endDelta) => _string.substring(start, _charOffset + 1 + endDelta);
|
| - int peek() {
|
| - if (_charOffset + 1 < _stringLength) {
|
| - return _string.codeUnitAt(_charOffset + 1);
|
| - }
|
| - return -1;
|
| - }
|
| -}
|
| -/**
|
| - * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
|
| - * buffer. The scanning logic is in the superclass.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class CharBufferScanner extends AbstractScanner {
|
| -
|
| - /**
|
| - * The buffer from which characters will be read.
|
| - */
|
| - CharSequence _buffer;
|
| -
|
| - /**
|
| - * The number of characters in the buffer.
|
| - */
|
| - int _bufferLength = 0;
|
| -
|
| - /**
|
| - * The index of the last character that was read.
|
| - */
|
| - int _charOffset = 0;
|
| -
|
| - /**
|
| - * Initialize a newly created scanner to scan the characters in the given character buffer.
|
| - *
|
| - * @param source the source being scanned
|
| - * @param buffer the buffer from which characters will be read
|
| - */
|
| - CharBufferScanner(Source source, CharSequence buffer) : super(source) {
|
| - this._buffer = buffer;
|
| - this._bufferLength = buffer.length();
|
| - this._charOffset = -1;
|
| - }
|
| - int get offset => _charOffset;
|
| - int advance() {
|
| - if (++_charOffset < _bufferLength) {
|
| - return _buffer.charAt(_charOffset);
|
| - }
|
| - _charOffset = _bufferLength;
|
| - return -1;
|
| - }
|
| - String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
|
| - int peek() {
|
| - if (_charOffset + 1 < _bufferLength) {
|
| - return _buffer.charAt(_charOffset + 1);
|
| - }
|
| - return -1;
|
| - }
|
| -}
|
| -/**
|
| - * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
|
| - * node (and all of it's children) to a writer.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class ToSourceVisitor implements XmlVisitor<Object> {
|
| -
|
| - /**
|
| - * The writer to which the source is to be written.
|
| - */
|
| - 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(PrintWriter writer) {
|
| - this._writer = writer;
|
| - }
|
| - Object visitHtmlUnit(HtmlUnit node) {
|
| - for (XmlTagNode child in node.tagNodes) {
|
| - visit(child);
|
| - }
|
| - return null;
|
| - }
|
| - Object visitXmlAttributeNode(XmlAttributeNode node) {
|
| - String name = node.name.lexeme;
|
| - Token value = node.value;
|
| - if (name.length == 0) {
|
| - _writer.print("__");
|
| - } else {
|
| - _writer.print(name);
|
| - }
|
| - _writer.print("=");
|
| - if (value == null) {
|
| - _writer.print("__");
|
| - } else {
|
| - _writer.print(value.lexeme);
|
| - }
|
| - return null;
|
| - }
|
| - Object visitXmlTagNode(XmlTagNode node) {
|
| - _writer.print("<");
|
| - String tagName = node.tag.lexeme;
|
| - _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);
|
| - }
|
| - }
|
| -}
|
| -/**
|
| - * The enumeration `TokenType` defines the types of tokens that can be returned by the
|
| - * scanner.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class TokenType extends Enum<TokenType> {
|
| -
|
| - /**
|
| - * The type of the token that marks the end of the input.
|
| - */
|
| - static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
|
| - static final TokenType EQ = new TokenType('EQ', 1, "=");
|
| - static final TokenType GT = new TokenType('GT', 2, ">");
|
| - static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</");
|
| - static final TokenType LT = new TokenType('LT', 4, "<");
|
| - static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>");
|
| - static final TokenType COMMENT = new TokenType('COMMENT', 6, null);
|
| - static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null);
|
| - static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null);
|
| - static final TokenType STRING = new TokenType('STRING', 9, null);
|
| - static final TokenType TAG = new TokenType('TAG', 10, null);
|
| - static final TokenType TEXT = new TokenType('TEXT', 11, null);
|
| - static final List<TokenType> values = [
|
| - 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.
|
| - */
|
| - String lexeme;
|
| - TokenType(String name, int ordinal, String lexeme) : super(name, ordinal) {
|
| - this.lexeme = lexeme;
|
| - }
|
| -}
|
| -class TokenType_EOF extends TokenType {
|
| - TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, arg0);
|
| - String toString() => "-eof-";
|
| -}
|
| -/**
|
| - * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class XmlAttributeNode extends XmlNode {
|
| - Token name;
|
| - Token equals;
|
| - Token value;
|
| -
|
| - /**
|
| - * 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(Token name, Token equals, Token value) {
|
| - this.name = name;
|
| - this.equals = equals;
|
| - this.value = value;
|
| - }
|
| - accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
|
| - Token get beginToken => name;
|
| - Token get endToken => value;
|
| -
|
| - /**
|
| - * 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;
|
| - }
|
| - 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;
|
| - }
|
| - void visitChildren(XmlVisitor visitor) {
|
| - }
|
| -}
|
| -/**
|
| - * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an
|
| - * [XmlNode] structure.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -abstract class XmlVisitor<R> {
|
| - R visitHtmlUnit(HtmlUnit htmlUnit);
|
| - R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
|
| - R visitXmlTagNode(XmlTagNode xmlTagNode);
|
| -}
|
| -/**
|
| - * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/>
|
| - * For example, the following code scans HTML source and returns the result:
|
| - *
|
| - * <pre>
|
| - * HtmlScanner scanner = new HtmlScanner(source);
|
| - * source.getContents(scanner);
|
| - * return scanner.getResult();
|
| - * </pre>
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class HtmlScanner implements Source_ContentReceiver {
|
| - List<String> _SCRIPT_TAG = <String> ["script"];
|
| -
|
| - /**
|
| - * The source being scanned (not `null`)
|
| - */
|
| - Source _source;
|
| -
|
| - /**
|
| - * The time at which the contents of the source were last set.
|
| - */
|
| - int _modificationTime = 0;
|
| -
|
| - /**
|
| - * The scanner used to scan the source
|
| - */
|
| - AbstractScanner _scanner;
|
| -
|
| - /**
|
| - * The first token in the token stream.
|
| - */
|
| - Token _token;
|
| -
|
| - /**
|
| - * Construct a new instance to scan the specified source.
|
| - *
|
| - * @param source the source to be scanned (not `null`)
|
| - */
|
| - HtmlScanner(Source source) {
|
| - this._source = source;
|
| - }
|
| - void accept(CharBuffer contents, int modificationTime) {
|
| - this._modificationTime = modificationTime;
|
| - _scanner = new CharBufferScanner(_source, contents);
|
| - _scanner.passThroughElements = _SCRIPT_TAG;
|
| - _token = _scanner.tokenize();
|
| - }
|
| - void accept2(String contents, int modificationTime) {
|
| - this._modificationTime = modificationTime;
|
| - _scanner = new StringScanner(_source, contents);
|
| - _scanner.passThroughElements = _SCRIPT_TAG;
|
| - _token = _scanner.tokenize();
|
| - }
|
| -
|
| - /**
|
| - * Answer the result of scanning the source
|
| - *
|
| - * @return the result (not `null`)
|
| - */
|
| - HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _scanner.lineStarts);
|
| -}
|
| -/**
|
| - * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
|
| - * of [XmlNode]s.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class XmlParser {
|
| -
|
| - /**
|
| - * The source being parsed.
|
| - */
|
| - Source source;
|
| -
|
| - /**
|
| - * The next token to be parsed.
|
| - */
|
| - Token currentToken;
|
| -
|
| - /**
|
| - * Construct a parser for the specified source.
|
| - *
|
| - * @param source the source being parsed
|
| - */
|
| - XmlParser(Source source) {
|
| - this.source = source;
|
| - }
|
| -
|
| - /**
|
| - * 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>();
|
| - while (true) {
|
| - while (true) {
|
| - if (currentToken.type == TokenType.LT) {
|
| - tagNodes.add(parseTagNode());
|
| - } else if (currentToken.type == TokenType.DECLARATION || currentToken.type == TokenType.DIRECTIVE || currentToken.type == TokenType.COMMENT) {
|
| - currentToken = currentToken.next;
|
| - } else if (currentToken.type == TokenType.EOF) {
|
| - return tagNodes;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - currentToken = currentToken.next;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * 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() {
|
| - Token name = currentToken;
|
| - currentToken = currentToken.next;
|
| - Token equals;
|
| - if (identical(currentToken.type, TokenType.EQ)) {
|
| - equals = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - equals = insertSyntheticToken(TokenType.EQ);
|
| - }
|
| - Token value;
|
| - if (identical(currentToken.type, TokenType.STRING)) {
|
| - value = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - value = insertSyntheticToken(TokenType.STRING);
|
| - }
|
| - return new XmlAttributeNode(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 (identical(type, TokenType.GT) || identical(type, TokenType.SLASH_GT) || identical(type, TokenType.EOF)) {
|
| - return XmlTagNode.NO_ATTRIBUTES;
|
| - }
|
| - List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
|
| - while (true) {
|
| - while (true) {
|
| - if (currentToken.type == TokenType.GT || currentToken.type == TokenType.SLASH_GT || currentToken.type == TokenType.EOF) {
|
| - return attributes;
|
| - } else if (currentToken.type == TokenType.TAG) {
|
| - attributes.add(parseAttribute());
|
| - } else {
|
| - reportUnexpectedToken();
|
| - currentToken = currentToken.next;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * 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 (identical(type, TokenType.LT_SLASH) || identical(type, TokenType.EOF)) {
|
| - return XmlTagNode.NO_TAG_NODES;
|
| - }
|
| - List<XmlTagNode> nodes = new List<XmlTagNode>();
|
| - while (true) {
|
| - while (true) {
|
| - if (currentToken.type == TokenType.LT) {
|
| - nodes.add(parseTagNode());
|
| - } else if (currentToken.type == TokenType.LT_SLASH || currentToken.type == TokenType.EOF) {
|
| - return nodes;
|
| - } else if (currentToken.type == TokenType.COMMENT) {
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - currentToken = currentToken.next;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * 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() {
|
| - Token nodeStart = currentToken;
|
| - currentToken = currentToken.next;
|
| - Token tag;
|
| - if (identical(currentToken.type, TokenType.TAG)) {
|
| - tag = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - tag = insertSyntheticToken(TokenType.TAG);
|
| - }
|
| - List<XmlAttributeNode> attributes = parseAttributes();
|
| - Token attributeEnd;
|
| - if (identical(currentToken.type, TokenType.GT) || identical(currentToken.type, TokenType.SLASH_GT)) {
|
| - attributeEnd = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - attributeEnd = insertSyntheticToken(TokenType.SLASH_GT);
|
| - }
|
| - if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag)) {
|
| - return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.NO_TAG_NODES, currentToken, null, attributeEnd);
|
| - }
|
| - List<XmlTagNode> tagNodes = parseChildTagNodes();
|
| - Token contentEnd;
|
| - if (identical(currentToken.type, TokenType.LT_SLASH)) {
|
| - contentEnd = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - contentEnd = insertSyntheticToken(TokenType.LT_SLASH);
|
| - }
|
| - Token closingTag;
|
| - if (identical(currentToken.type, TokenType.TAG)) {
|
| - closingTag = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - closingTag = insertSyntheticToken(TokenType.TAG);
|
| - }
|
| - Token nodeEnd;
|
| - if (identical(currentToken.type, TokenType.GT)) {
|
| - nodeEnd = currentToken;
|
| - currentToken = currentToken.next;
|
| - } else {
|
| - reportUnexpectedToken();
|
| - nodeEnd = insertSyntheticToken(TokenType.GT);
|
| - }
|
| - return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
|
| - }
|
| -
|
| - /**
|
| - * Report the current token as unexpected
|
| - */
|
| - void reportUnexpectedToken() {
|
| - }
|
| -}
|
| -/**
|
| - * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
|
| - * `<body foo="bar"> ... </body>`.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -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`).
|
| - */
|
| - Token nodeStart;
|
| -
|
| - /**
|
| - * The [TokenType#TAG] token after the starting '<' (not `null`).
|
| - */
|
| - 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].
|
| - */
|
| - 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].
|
| - *
|
| - */
|
| - 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]
|
| - */
|
| - Token closingTag;
|
| -
|
| - /**
|
| - * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`).
|
| - */
|
| - Token nodeEnd;
|
| -
|
| - /**
|
| - * 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 '<' (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(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
|
| - this.nodeStart = nodeStart;
|
| - this.tag = tag;
|
| - this.attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES);
|
| - this.attributeEnd = attributeEnd;
|
| - this.tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES);
|
| - this.contentEnd = contentEnd;
|
| - this.closingTag = closingTag;
|
| - this.nodeEnd = nodeEnd;
|
| - }
|
| - 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.lexeme == 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;
|
| - }
|
| - Token get beginToken => nodeStart;
|
| -
|
| - /**
|
| - * Answer a string representing the content contained in the receiver. This includes the textual
|
| - * representation of any child tag nodes ([getTagNodes]). Whitespace between '<',
|
| - * '</', and '>', '/>' is discarded, but all other whitespace is preserved.
|
| - *
|
| - * @return the content (not `null`)
|
| - */
|
| - String get content {
|
| - Token token = attributeEnd.next;
|
| - if (identical(token, contentEnd)) {
|
| - return "";
|
| - }
|
| - String content = token.lexeme;
|
| - token = token.next;
|
| - if (identical(token, contentEnd)) {
|
| - return content;
|
| - }
|
| - JavaStringBuilder buffer = new JavaStringBuilder();
|
| - while (token != contentEnd) {
|
| - buffer.append(token.lexeme);
|
| - token = token.next;
|
| - }
|
| - return buffer.toString();
|
| - }
|
| - 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;
|
| - }
|
| - void visitChildren(XmlVisitor visitor) {
|
| - for (XmlAttributeNode node in attributes) {
|
| - node.accept(visitor);
|
| - }
|
| - for (XmlTagNode node in tagNodes) {
|
| - node.accept(visitor);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empty
|
| - */
|
| - List becomeParentOfEmpty(List children, List ifEmpty) {
|
| - if (children != null && children.isEmpty) {
|
| - return ifEmpty;
|
| - }
|
| - return becomeParentOf(children);
|
| - }
|
| -}
|
| -/**
|
| - * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
|
| - * of [XmlNode]s.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class HtmlParser extends XmlParser {
|
| - static Set<String> SELF_CLOSING = new Set<String>();
|
| -
|
| - /**
|
| - * Construct a parser for the specified source.
|
| - *
|
| - * @param source the source being parsed
|
| - */
|
| - HtmlParser(Source source) : super(source);
|
| -
|
| - /**
|
| - * Parse the tokens specified by the given scan result.
|
| - *
|
| - * @param scanResult the result of scanning an HTML source (not `null`)
|
| - * @return the parse result (not `null`)
|
| - */
|
| - HtmlParseResult parse(HtmlScanResult scanResult) {
|
| - Token firstToken = scanResult.token;
|
| - List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
|
| - HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
|
| - return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResult.lineStarts, unit);
|
| - }
|
| -
|
| - /**
|
| - * Scan then parse the specified source.
|
| - *
|
| - * @param source the source to be scanned and parsed (not `null`)
|
| - * @return the parse result (not `null`)
|
| - */
|
| - HtmlParseResult parse2(Source source) {
|
| - HtmlScanner scanner = new HtmlScanner(source);
|
| - source.getContents(scanner);
|
| - return parse(scanner.result);
|
| - }
|
| - bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
|
| -}
|
| -/**
|
| - * Instances of the class `HtmlUnit` represent the contents of an HTML file.
|
| - *
|
| - * @coverage dart.engine.html
|
| - */
|
| -class HtmlUnit extends XmlNode {
|
| -
|
| - /**
|
| - * The first token in the token stream that was parsed to form this HTML unit.
|
| - */
|
| - 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].
|
| - */
|
| - Token _endToken;
|
| -
|
| - /**
|
| - * The tag nodes contained in the receiver (not `null`, contains no `null`s).
|
| - */
|
| - List<XmlTagNode> tagNodes;
|
| -
|
| - /**
|
| - * The element associated with this HTML unit or `null` if the receiver is not resolved.
|
| - */
|
| - HtmlElementImpl element;
|
| -
|
| - /**
|
| - * 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(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
|
| - this._beginToken = beginToken;
|
| - this.tagNodes = becomeParentOf(tagNodes);
|
| - this._endToken = endToken;
|
| - }
|
| - accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
|
| - Token get beginToken => _beginToken;
|
| - Token get endToken => _endToken;
|
| - void visitChildren(XmlVisitor visitor) {
|
| - for (XmlTagNode node in tagNodes) {
|
| - node.accept(visitor);
|
| - }
|
| - }
|
| -}
|
|
|