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

Unified Diff: pkg/analyzer-experimental/lib/src/generated/scanner.dart

Issue 12197019: Drop of generated scanner and example scanner driver. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months 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
Index: pkg/analyzer-experimental/lib/src/generated/scanner.dart
===================================================================
--- pkg/analyzer-experimental/lib/src/generated/scanner.dart (revision 0)
+++ pkg/analyzer-experimental/lib/src/generated/scanner.dart (revision 0)
@@ -0,0 +1,1859 @@
+// 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.scanner;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'source.dart';
+import 'error.dart';
+import 'instrumentation.dart';
+
+/**
+ * The enumeration {@code Keyword} defines the keywords in the Dart programming language.
+ */
+class Keyword {
+ static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert");
+ static final Keyword BREAK = new Keyword.con1('BREAK', 1, "break");
+ static final Keyword CASE = new Keyword.con1('CASE', 2, "case");
+ static final Keyword CATCH = new Keyword.con1('CATCH', 3, "catch");
+ static final Keyword CLASS = new Keyword.con1('CLASS', 4, "class");
+ static final Keyword CONST = new Keyword.con1('CONST', 5, "const");
+ static final Keyword CONTINUE = new Keyword.con1('CONTINUE', 6, "continue");
+ static final Keyword DEFAULT = new Keyword.con1('DEFAULT', 7, "default");
+ static final Keyword DO = new Keyword.con1('DO', 8, "do");
+ static final Keyword ELSE = new Keyword.con1('ELSE', 9, "else");
+ static final Keyword EXTENDS = new Keyword.con1('EXTENDS', 10, "extends");
+ static final Keyword FALSE = new Keyword.con1('FALSE', 11, "false");
+ static final Keyword FINAL = new Keyword.con1('FINAL', 12, "final");
+ static final Keyword FINALLY = new Keyword.con1('FINALLY', 13, "finally");
+ static final Keyword FOR = new Keyword.con1('FOR', 14, "for");
+ static final Keyword IF = new Keyword.con1('IF', 15, "if");
+ static final Keyword IN = new Keyword.con1('IN', 16, "in");
+ static final Keyword IS = new Keyword.con1('IS', 17, "is");
+ static final Keyword NEW = new Keyword.con1('NEW', 18, "new");
+ static final Keyword NULL = new Keyword.con1('NULL', 19, "null");
+ static final Keyword RETURN = new Keyword.con1('RETURN', 20, "return");
+ static final Keyword SUPER = new Keyword.con1('SUPER', 21, "super");
+ static final Keyword SWITCH = new Keyword.con1('SWITCH', 22, "switch");
+ static final Keyword THIS = new Keyword.con1('THIS', 23, "this");
+ static final Keyword THROW = new Keyword.con1('THROW', 24, "throw");
+ static final Keyword TRUE = new Keyword.con1('TRUE', 25, "true");
+ static final Keyword TRY = new Keyword.con1('TRY', 26, "try");
+ static final Keyword VAR = new Keyword.con1('VAR', 27, "var");
+ static final Keyword VOID = new Keyword.con1('VOID', 28, "void");
+ static final Keyword WHILE = new Keyword.con1('WHILE', 29, "while");
+ static final Keyword WITH = new Keyword.con1('WITH', 30, "with");
+ static final Keyword ABSTRACT = new Keyword.con2('ABSTRACT', 31, "abstract", true);
+ static final Keyword AS = new Keyword.con2('AS', 32, "as", true);
+ static final Keyword DYNAMIC = new Keyword.con2('DYNAMIC', 33, "dynamic", true);
+ static final Keyword EXPORT = new Keyword.con2('EXPORT', 34, "export", true);
+ static final Keyword EXTERNAL = new Keyword.con2('EXTERNAL', 35, "external", true);
+ static final Keyword FACTORY = new Keyword.con2('FACTORY', 36, "factory", true);
+ static final Keyword GET = new Keyword.con2('GET', 37, "get", true);
+ static final Keyword IMPLEMENTS = new Keyword.con2('IMPLEMENTS', 38, "implements", true);
+ static final Keyword IMPORT = new Keyword.con2('IMPORT', 39, "import", true);
+ static final Keyword LIBRARY = new Keyword.con2('LIBRARY', 40, "library", true);
+ static final Keyword OPERATOR = new Keyword.con2('OPERATOR', 41, "operator", true);
+ static final Keyword PART = new Keyword.con2('PART', 42, "part", true);
+ static final Keyword SET = new Keyword.con2('SET', 43, "set", true);
+ static final Keyword STATIC = new Keyword.con2('STATIC', 44, "static", true);
+ static final Keyword TYPEDEF = new Keyword.con2('TYPEDEF', 45, "typedef", true);
+ static final List<Keyword> values = [ASSERT, BREAK, CASE, CATCH, CLASS, CONST, CONTINUE, DEFAULT, DO, ELSE, EXTENDS, FALSE, FINAL, FINALLY, FOR, IF, IN, IS, NEW, NULL, RETURN, SUPER, SWITCH, THIS, THROW, TRUE, TRY, VAR, VOID, WHILE, WITH, ABSTRACT, AS, DYNAMIC, EXPORT, EXTERNAL, FACTORY, GET, IMPLEMENTS, IMPORT, LIBRARY, OPERATOR, PART, SET, STATIC, TYPEDEF];
+ String __name;
+ int __ordinal = 0;
+ /**
+ * The lexeme for the keyword.
+ */
+ String _syntax;
+ /**
+ * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords can be used as
+ * identifiers.
+ */
+ bool _isPseudoKeyword2 = false;
+ /**
+ * A table mapping the lexemes of keywords to the corresponding keyword.
+ */
+ static Map<String, Keyword> keywords = createKeywordMap();
+ /**
+ * Create a table mapping the lexemes of keywords to the corresponding keyword.
+ * @return the table that was created
+ */
+ static Map<String, Keyword> createKeywordMap() {
+ LinkedHashMap<String, Keyword> result = new LinkedHashMap<String, Keyword>();
+ for (Keyword keyword in values) {
+ result[keyword._syntax] = keyword;
+ }
+ return result;
+ }
+ /**
+ * Initialize a newly created keyword to have the given syntax. The keyword is not a
+ * pseudo-keyword.
+ * @param syntax the lexeme for the keyword
+ */
+ Keyword.con1(String ___name, int ___ordinal, String syntax) {
+ _jtd_constructor_215_impl(___name, ___ordinal, syntax);
+ }
+ _jtd_constructor_215_impl(String ___name, int ___ordinal, String syntax) {
+ _jtd_constructor_216_impl(___name, ___ordinal, syntax, false);
+ }
+ /**
+ * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
+ * the given flag is {@code true}.
+ * @param syntax the lexeme for the keyword
+ * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword
+ */
+ Keyword.con2(String ___name, int ___ordinal, String syntax, bool isPseudoKeyword) {
+ _jtd_constructor_216_impl(___name, ___ordinal, syntax, isPseudoKeyword);
+ }
+ _jtd_constructor_216_impl(String ___name, int ___ordinal, String syntax, bool isPseudoKeyword) {
+ __name = ___name;
+ __ordinal = ___ordinal;
+ this._syntax = syntax;
+ this._isPseudoKeyword2 = isPseudoKeyword;
+ }
+ /**
+ * Return the lexeme for the keyword.
+ * @return the lexeme for the keyword
+ */
+ String get syntax => _syntax;
+ /**
+ * Return {@code true} if this keyword is a pseudo-keyword. Pseudo keywords can be used as
+ * identifiers.
+ * @return {@code true} if this keyword is a pseudo-keyword
+ */
+ bool isPseudoKeyword() => _isPseudoKeyword2;
+ String toString() => __name;
+}
+/**
+ * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * buffer. The scanning logic is in the superclass.
+ */
+class CharBufferScanner extends AbstractScanner {
+ /**
+ * The buffer from which characters will be read.
+ */
+ CharBuffer _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
+ * @param errorListener the error listener that will be informed of any errors that are found
+ */
+ CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
+ this._buffer = buffer;
+ this._bufferLength = buffer.length();
+ this._charOffset = -1;
+ }
+ int get offset => _charOffset;
+ int advance() {
+ if (_charOffset + 1 >= _bufferLength) {
+ return -1;
+ }
+ return _buffer.charAt(++_charOffset);
+ }
+ String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
+ int peek() {
+ if (_charOffset + 1 >= _buffer.length()) {
+ return -1;
+ }
+ return _buffer.charAt(_charOffset + 1);
+ }
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
+ * comments.
+ */
+class TokenWithComment extends Token {
+ /**
+ * The first comment in the list of comments that precede this token.
+ */
+ Token _precedingComment;
+ /**
+ * Initialize a newly created token to have the given type and offset and to be preceded by the
+ * comments reachable from the given comment.
+ * @param type the type of the token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ * @param precedingComment the first comment in the list of comments that precede this token
+ */
+ TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+ this._precedingComment = precedingComment;
+ }
+ Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code 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 type of the token.
+ */
+ TokenType _type;
+ /**
+ * 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;
+ /**
+ * Initialize a newly created token to have the given type and offset.
+ * @param type the type of the token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ */
+ Token(TokenType type, int offset) {
+ this._type = type;
+ 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 the lexeme that represents this token.
+ * @return the lexeme that represents this token
+ */
+ String get lexeme => _type.lexeme;
+ /**
+ * Return the next token in the token stream.
+ * @return the next token in the token stream
+ */
+ Token get next => _next;
+ /**
+ * Return the offset from the beginning of the file to the first character in the token.
+ * @return the offset from the beginning of the file to the first character in the token
+ */
+ int get offset => _offset;
+ /**
+ * Return the first comment in the list of comments that precede this token, or {@code null} if
+ * there are no comments preceding this token. Additional comments can be reached by following the
+ * token stream using {@link #getNext()} until {@code null} is returned.
+ * @return the first comment in the list of comments that precede this token
+ */
+ Token get precedingComments => null;
+ /**
+ * Return the previous token in the token stream.
+ * @return the previous token in the token stream
+ */
+ Token get previous => _previous;
+ /**
+ * Return the type of the token.
+ * @return the type of the token
+ */
+ TokenType get type => _type;
+ /**
+ * Return {@code true} if this token represents an operator.
+ * @return {@code true} if this token represents an operator
+ */
+ bool isOperator() => _type.isOperator();
+ /**
+ * Return {@code 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 ({@code 0}).
+ * @return {@code true} if this token is a synthetic token
+ */
+ bool isSynthetic() => length == 0;
+ /**
+ * Return {@code true} if this token represents an operator that can be defined by users.
+ * @return {@code true} if this token represents an operator that can be defined by users
+ */
+ bool isUserDefinableOperator() => _type.isUserDefinableOperator();
+ /**
+ * 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.previous2 = this;
+ return token;
+ }
+ /**
+ * Set the next token in the token stream to the given token without changing which token is the
+ * previous token for the given token.
+ * @param token the next token in the token stream
+ * @return the token that was passed in
+ */
+ Token setNextWithoutSettingPrevious(Token token) {
+ _next = token;
+ return token;
+ }
+ /**
+ * Set the offset from the beginning of the file to the first character in the token to the given
+ * offset.
+ * @param offset the offset from the beginning of the file to the first character in the token
+ */
+ void set offset2(int offset) {
+ this._offset = offset;
+ }
+ String toString() => lexeme;
+ /**
+ * Return the value of this token. For keyword tokens, this is the keyword associated with the
+ * token, for other tokens it is the lexeme associated with the token.
+ * @return the value of this token
+ */
+ Object value() => _type.lexeme;
+ /**
+ * Set the previous token in the token stream to the given token.
+ * @param previous the previous token in the token stream
+ */
+ void set previous2(Token previous) {
+ this._previous = previous;
+ }
+}
+/**
+ * Instances of the class {@code KeywordToken} represent a keyword in the language.
+ */
+class KeywordToken extends Token {
+ /**
+ * The keyword being represented by this token.
+ */
+ Keyword _keyword;
+ /**
+ * Initialize a newly created token to represent the given keyword.
+ * @param keyword the keyword being represented by this token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ */
+ KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
+ this._keyword = keyword;
+ }
+ /**
+ * Return the keyword being represented by this token.
+ * @return the keyword being represented by this token
+ */
+ Keyword get keyword => _keyword;
+ String get lexeme => _keyword.syntax;
+ Keyword value() => _keyword;
+}
+/**
+ * Instances of the class {@code StringToken} represent a token whose value is independent of it's
+ * type.
+ */
+class StringToken extends Token {
+ /**
+ * The lexeme represented by this token.
+ */
+ String _value2;
+ /**
+ * Initialize a newly created token to represent a token of the given type with the given value.
+ * @param type the type of the token
+ * @param value the lexeme represented by this token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ */
+ StringToken(TokenType type, String value, int offset) : super(type, offset) {
+ this._value2 = value;
+ }
+ String get lexeme => _value2;
+ String value() => _value2;
+}
+/**
+ * The enumeration {@code ScannerErrorCode} defines the error codes used for errors detected by the
+ * scanner.
+ */
+class ScannerErrorCode implements ErrorCode {
+ static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGAL_CHARACTER', 0, "Illegal character %x");
+ static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DIGIT', 1, "Decimal digit expected");
+ static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSING_HEX_DIGIT', 2, "Hexidecimal digit expected");
+ static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QUOTE', 3, "Expected quote (' or \")");
+ static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErrorCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
+ static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCode('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
+ static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT, MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATED_STRING_LITERAL];
+ final String __name;
+ final int __ordinal;
+ /**
+ * The message template used to create the message to be displayed for this error.
+ */
+ String _message;
+ /**
+ * Initialize a newly created error code to have the given message.
+ * @param message the message template used to create the message to be displayed for this error
+ */
+ ScannerErrorCode(this.__name, this.__ordinal, String message) {
+ this._message = message;
+ }
+ ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+ String get message => _message;
+ ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+ bool needsRecompilation() => true;
+ String toString() => __name;
+}
+/**
+ * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
+ * comments.
+ */
+class BeginTokenWithComment extends BeginToken {
+ /**
+ * The first comment in the list of comments that precede this token.
+ */
+ Token _precedingComment;
+ /**
+ * Initialize a newly created token to have the given type and offset and to be preceded by the
+ * comments reachable from the given comment.
+ * @param type the type of the token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ * @param precedingComment the first comment in the list of comments that precede this token
+ */
+ BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+ this._precedingComment = precedingComment;
+ }
+ Token get precedingComments => _precedingComment;
+}
+/**
+ * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * scanner.
+ */
+class TokenType {
+ /**
+ * The type of the token that marks the end of the input.
+ */
+ static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
+ static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
+ static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
+ static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
+ static final TokenType INT = new TokenType.con1('INT', 4);
+ static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
+ static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COMMENT', 6);
+ static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
+ static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_COMMENT', 8);
+ static final TokenType STRING = new TokenType.con1('STRING', 9);
+ static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&");
+ static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMPERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
+ static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "&=");
+ static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
+ static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!");
+ static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!=");
+ static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|");
+ static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||");
+ static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|=");
+ static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
+ static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
+ static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^");
+ static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=");
+ static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_BRACKET', 23, null, "}");
+ static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, null, ")");
+ static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE_BRACKET', 25, null, "]");
+ static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "=");
+ static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "==");
+ static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=>");
+ static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">");
+ static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">=");
+ static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>");
+ static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>=");
+ static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
+ static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]");
+ static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");
+ static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is");
+ static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<");
+ static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<=");
+ static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<");
+ static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<=");
+ static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-");
+ static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=");
+ static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, TokenClass.UNARY_PREFIX_OPERATOR, "--");
+ static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRACKET', 44, null, "{");
+ static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR, "(");
+ static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_BRACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
+ static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%");
+ static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=");
+ static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".");
+ static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
+ static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+");
+ static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+=");
+ static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "++");
+ static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?");
+ static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, ";");
+ static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/");
+ static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=");
+ static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*");
+ static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*=");
+ static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('STRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
+ static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('STRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
+ static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~");
+ static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, TokenClass.MULTIPLICATIVE_OPERATOR, "~/");
+ static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 64, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
+ static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`");
+ static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, "\\");
+ static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD_PERIOD', 67, null, "...");
+ static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, INT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERSAND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_BRACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET, OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, PLUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, STRING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLASH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
+ String __name;
+ int __ordinal = 0;
+ /**
+ * The class of the token.
+ */
+ TokenClass _tokenClass;
+ /**
+ * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+ * lexeme for this type of token.
+ */
+ String _lexeme;
+ TokenType.con1(String ___name, int ___ordinal) {
+ _jtd_constructor_227_impl(___name, ___ordinal);
+ }
+ _jtd_constructor_227_impl(String ___name, int ___ordinal) {
+ _jtd_constructor_228_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
+ }
+ TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass, String lexeme) {
+ _jtd_constructor_228_impl(___name, ___ordinal, tokenClass, lexeme);
+ }
+ _jtd_constructor_228_impl(String ___name, int ___ordinal, TokenClass tokenClass, String lexeme) {
+ __name = ___name;
+ __ordinal = ___ordinal;
+ this._tokenClass = tokenClass == null ? TokenClass.NO_CLASS : tokenClass;
+ this._lexeme = lexeme;
+ }
+ /**
+ * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+ * possible lexeme for this type of token.
+ * @return the lexeme that defines this type of token
+ */
+ String get lexeme => _lexeme;
+ /**
+ * Return the precedence of the token, or {@code 0} if the token does not represent an operator.
+ * @return the precedence of the token
+ */
+ int get precedence => _tokenClass.precedence;
+ /**
+ * Return {@code true} if this type of token represents an additive operator.
+ * @return {@code true} if this type of token represents an additive operator
+ */
+ bool isAdditiveOperator() => _tokenClass == TokenClass.ADDITIVE_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents an assignment operator.
+ * @return {@code true} if this type of token represents an assignment operator
+ */
+ bool isAssignmentOperator() => _tokenClass == TokenClass.ASSIGNMENT_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents an equality operator.
+ * @return {@code true} if this type of token represents an equality operator
+ */
+ bool isEqualityOperator() => _tokenClass == TokenClass.EQUALITY_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents an increment operator.
+ * @return {@code true} if this type of token represents an increment operator
+ */
+ bool isIncrementOperator() => _lexeme == "++" || _lexeme == "--";
+ /**
+ * Return {@code true} if this type of token represents a multiplicative operator.
+ * @return {@code true} if this type of token represents a multiplicative operator
+ */
+ bool isMultiplicativeOperator() => _tokenClass == TokenClass.MULTIPLICATIVE_OPERATOR;
+ /**
+ * Return {@code true} if this token type represents an operator.
+ * @return {@code true} if this token type represents an operator
+ */
+ bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != TokenType.OPEN_PAREN && this != TokenType.OPEN_SQUARE_BRACKET && this != TokenType.PERIOD;
+ /**
+ * Return {@code true} if this type of token represents a relational operator.
+ * @return {@code true} if this type of token represents a relational operator
+ */
+ bool isRelationalOperator() => _tokenClass == TokenClass.RELATIONAL_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents a shift operator.
+ * @return {@code true} if this type of token represents a shift operator
+ */
+ bool isShiftOperator() => _tokenClass == TokenClass.SHIFT_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents a unary postfix operator.
+ * @return {@code true} if this type of token represents a unary postfix operator
+ */
+ bool isUnaryPostfixOperator() => _tokenClass == TokenClass.UNARY_POSTFIX_OPERATOR;
+ /**
+ * Return {@code true} if this type of token represents a unary prefix operator.
+ * @return {@code true} if this type of token represents a unary prefix operator
+ */
+ bool isUnaryPrefixOperator() => _tokenClass == TokenClass.UNARY_PREFIX_OPERATOR;
+ /**
+ * Return {@code true} if this token type represents an operator that can be defined by users.
+ * @return {@code true} if this token type represents an operator that can be defined by users
+ */
+ bool isUserDefinableOperator() => _lexeme == "==" || _lexeme == "~" || _lexeme == "[]" || _lexeme == "[]=" || _lexeme == "*" || _lexeme == "/" || _lexeme == "%" || _lexeme == "~/" || _lexeme == "+" || _lexeme == "-" || _lexeme == "<<" || _lexeme == ">>" || _lexeme == ">=" || _lexeme == ">" || _lexeme == "<=" || _lexeme == "<" || _lexeme == "&" || _lexeme == "^" || _lexeme == "|";
+ String toString() => __name;
+}
+class TokenType_EOF extends TokenType {
+ TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
+ String toString() => "-eof-";
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
+ * comments.
+ */
+class StringTokenWithComment extends StringToken {
+ /**
+ * The first comment in the list of comments that precede this token.
+ */
+ Token _precedingComment;
+ /**
+ * Initialize a newly created token to have the given type and offset and to be preceded by the
+ * comments reachable from the given comment.
+ * @param type the type of the token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ * @param precedingComment the first comment in the list of comments that precede this token
+ */
+ StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
+ this._precedingComment = precedingComment;
+ }
+ Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code BeginToken} represent the opening half of a grouping pair of
+ * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
+ */
+class BeginToken extends Token {
+ /**
+ * The token that corresponds to this token.
+ */
+ Token _endToken;
+ /**
+ * Initialize a newly created token representing the opening half of a grouping pair of tokens.
+ * @param type the type of the token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ */
+ BeginToken(TokenType type, int offset) : super(type, offset) {
+ assert((type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.OPEN_PAREN || type == TokenType.OPEN_SQUARE_BRACKET || type == TokenType.STRING_INTERPOLATION_EXPRESSION));
+ }
+ /**
+ * Return the token that corresponds to this token.
+ * @return the token that corresponds to this token
+ */
+ Token get endToken => _endToken;
+ /**
+ * Set the token that corresponds to this token to the given token.
+ * @param token the token that corresponds to this token
+ */
+ void set endToken2(Token token) {
+ this._endToken = token;
+ }
+}
+/**
+ * The enumeration {@code TokenClass} represents classes (or groups) of tokens with a similar use.
+ */
+class TokenClass {
+ /**
+ * A value used to indicate that the token type is not part of any specific class of token.
+ */
+ static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
+ /**
+ * A value used to indicate that the token type is an additive operator.
+ */
+ static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPERATOR', 1, 12);
+ /**
+ * A value used to indicate that the token type is an assignment operator.
+ */
+ static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1);
+ /**
+ * A value used to indicate that the token type is a bitwise-and operator.
+ */
+ static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AND_OPERATOR', 3, 8);
+ /**
+ * A value used to indicate that the token type is a bitwise-or operator.
+ */
+ static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_OPERATOR', 4, 6);
+ /**
+ * A value used to indicate that the token type is a bitwise-xor operator.
+ */
+ static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 7);
+ /**
+ * A value used to indicate that the token type is a cascade operator.
+ */
+ static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERATOR', 6, 2);
+ /**
+ * A value used to indicate that the token type is a conditional operator.
+ */
+ static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3);
+ /**
+ * A value used to indicate that the token type is an equality operator.
+ */
+ static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPERATOR', 8, 9);
+ /**
+ * A value used to indicate that the token type is a logical-and operator.
+ */
+ static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5);
+ /**
+ * A value used to indicate that the token type is a logical-or operator.
+ */
+ static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4);
+ /**
+ * A value used to indicate that the token type is a multiplicative operator.
+ */
+ static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13);
+ /**
+ * A value used to indicate that the token type is a relational operator.
+ */
+ static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_OPERATOR', 12, 10);
+ /**
+ * A value used to indicate that the token type is a shift operator.
+ */
+ static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
+ /**
+ * A value used to indicate that the token type is a unary operator.
+ */
+ static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15);
+ /**
+ * A value used to indicate that the token type is a unary operator.
+ */
+ static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14);
+ static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMENT_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CASCADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LOGICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
+ String __name;
+ int __ordinal = 0;
+ /**
+ * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
+ * operator.
+ */
+ int _precedence = 0;
+ TokenClass.con1(String ___name, int ___ordinal) {
+ _jtd_constructor_225_impl(___name, ___ordinal);
+ }
+ _jtd_constructor_225_impl(String ___name, int ___ordinal) {
+ _jtd_constructor_226_impl(___name, ___ordinal, 0);
+ }
+ TokenClass.con2(String ___name, int ___ordinal, int precedence) {
+ _jtd_constructor_226_impl(___name, ___ordinal, precedence);
+ }
+ _jtd_constructor_226_impl(String ___name, int ___ordinal, int precedence) {
+ __name = ___name;
+ __ordinal = ___ordinal;
+ this._precedence = precedence;
+ }
+ /**
+ * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
+ * an operator.
+ * @return the precedence of tokens of this class
+ */
+ int get precedence => _precedence;
+ String toString() => __name;
+}
+/**
+ * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * scanning logic is in the superclass.
+ */
+class StringScanner extends AbstractScanner {
+ /**
+ * The offset from the beginning of the file to the beginning of the source being scanned.
+ */
+ int _offsetDelta = 0;
+ /**
+ * 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
+ * @param errorListener the error listener that will be informed of any errors that are found
+ */
+ StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
+ this._offsetDelta = 0;
+ this._string = string;
+ this._stringLength = string.length;
+ this._charOffset = -1;
+ }
+ int get offset => _offsetDelta + _charOffset;
+ /**
+ * Record that the source begins on the given line and column at the given offset. The line starts
+ * for lines before the given line will not be correct.
+ * <p>
+ * This method must be invoked at most one time and must be invoked before scanning begins. The
+ * values provided must be sensible. The results are undefined if these conditions are violated.
+ * @param line the one-based index of the line containing the first character of the source
+ * @param column the one-based index of the column in which the first character of the source
+ * occurs
+ * @param offset the zero-based offset from the beginning of the larger context to the first
+ * character of the source
+ */
+ void setSourceStart(int line, int column, int offset) {
+ if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
+ return;
+ }
+ _offsetDelta = 1;
+ for (int i = 2; i < line; i++) {
+ recordStartOfLine();
+ }
+ _offsetDelta = offset - column + 1;
+ recordStartOfLine();
+ _offsetDelta = offset;
+ }
+ int advance() {
+ if (_charOffset + 1 >= _stringLength) {
+ return -1;
+ }
+ return _string.charCodeAt(++_charOffset);
+ }
+ String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
+ int peek() {
+ if (_charOffset + 1 >= _string.length) {
+ return -1;
+ }
+ return _string.charCodeAt(_charOffset + 1);
+ }
+}
+/**
+ * The abstract class {@code AbstractScanner} implements a scanner for Dart code. Subclasses are
+ * required to implement the interface used to access the characters being scanned.
+ * <p>
+ * The lexical structure of Dart is ambiguous without knowledge of the context in which a token is
+ * being scanned. For example, without context we cannot determine whether source of the form "<<"
+ * should be scanned as a single left-shift operator or as two left angle brackets. This scanner
+ * does not have any context, so it always resolves such conflicts by scanning the longest possible
+ * token.
+ */
+abstract class AbstractScanner {
+ /**
+ * The source being scanned.
+ */
+ Source _source;
+ /**
+ * The error listener that will be informed of any errors that are found during the scan.
+ */
+ AnalysisErrorListener _errorListener;
+ /**
+ * The token pointing to the head of the linked list of tokens.
+ */
+ Token _tokens;
+ /**
+ * The last token that was scanned.
+ */
+ Token _tail;
+ /**
+ * The first token in the list of comment tokens found since the last non-comment token.
+ */
+ Token _firstComment;
+ /**
+ * The last token in the list of comment tokens found since the last non-comment token.
+ */
+ Token _lastComment;
+ /**
+ * The index of the first character of the current token.
+ */
+ int _tokenStart = 0;
+ /**
+ * A list containing the offsets of the first character of each line in the source code.
+ */
+ List<int> _lineStarts = new List<int>();
+ /**
+ * A list, treated something like a stack, of tokens representing the beginning of a matched pair.
+ * It is used to pair the end tokens with the begin tokens.
+ */
+ List<BeginToken> _groupingStack = new List<BeginToken>();
+ /**
+ * A flag indicating whether any unmatched groups were found during the parse.
+ */
+ bool _hasUnmatchedGroups2 = false;
+ /**
+ * A non-breaking space, which is allowed by this scanner as a white-space character.
+ */
+ static int _$NBSP = 160;
+ /**
+ * Initialize a newly created scanner.
+ * @param source the source being scanned
+ * @param errorListener the error listener that will be informed of any errors that are found
+ */
+ AbstractScanner(Source source, AnalysisErrorListener errorListener) {
+ this._source = source;
+ this._errorListener = errorListener;
+ _tokens = new Token(TokenType.EOF, -1);
+ _tokens.setNext(_tokens);
+ _tail = _tokens;
+ _tokenStart = -1;
+ _lineStarts.add(0);
+ }
+ /**
+ * 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;
+ /**
+ * Return {@code true} if any unmatched groups were found during the parse.
+ * @return {@code true} if any unmatched groups were found during the parse
+ */
+ bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
+ /**
+ * 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() {
+ int startTime = System.currentTimeMillis();
+ int next = advance();
+ while (next != -1) {
+ next = bigSwitch(next);
+ }
+ appendEofToken();
+ int endTime = System.currentTimeMillis();
+ Instrumentation.metric2("Engine-Scanner", endTime - startTime).with3("chars", offset).log();
+ 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 appendBeginToken(TokenType type) {
+ BeginToken token;
+ if (_firstComment == null) {
+ token = new BeginToken(type, _tokenStart);
+ } else {
+ token = new BeginTokenWithComment(type, _tokenStart, _firstComment);
+ _firstComment = null;
+ _lastComment = null;
+ }
+ _tail = _tail.setNext(token);
+ _groupingStack.add(token);
+ }
+ void appendCommentToken(TokenType type, String value) {
+ if (_firstComment == null) {
+ _firstComment = new StringToken(type, value, _tokenStart);
+ _lastComment = _firstComment;
+ } else {
+ _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
+ }
+ }
+ void appendEndToken(TokenType type, TokenType beginType) {
+ Token token;
+ if (_firstComment == null) {
+ token = new Token(type, _tokenStart);
+ } else {
+ token = new TokenWithComment(type, _tokenStart, _firstComment);
+ _firstComment = null;
+ _lastComment = null;
+ }
+ _tail = _tail.setNext(token);
+ int last = _groupingStack.length - 1;
+ if (last >= 0) {
+ BeginToken begin = _groupingStack[last];
+ if (begin.type == beginType) {
+ begin.endToken2 = token;
+ _groupingStack.removeAt(last);
+ }
+ }
+ }
+ void appendEofToken() {
+ Token eofToken;
+ if (_firstComment == null) {
+ eofToken = new Token(TokenType.EOF, offset + 1);
+ } else {
+ eofToken = new TokenWithComment(TokenType.EOF, offset + 1, _firstComment);
+ _firstComment = null;
+ _lastComment = null;
+ }
+ eofToken.setNext(eofToken);
+ _tail = _tail.setNext(eofToken);
+ if (!_groupingStack.isEmpty) {
+ _hasUnmatchedGroups2 = true;
+ }
+ }
+ void appendKeywordToken(Keyword keyword) {
+ if (_firstComment == null) {
+ _tail = _tail.setNext(new KeywordToken(keyword, _tokenStart));
+ } else {
+ _tail = _tail.setNext(new KeywordTokenWithComment(keyword, _tokenStart, _firstComment));
+ _firstComment = null;
+ _lastComment = null;
+ }
+ }
+ void appendStringToken(TokenType type, String value) {
+ if (_firstComment == null) {
+ _tail = _tail.setNext(new StringToken(type, value, _tokenStart));
+ } else {
+ _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart, _firstComment));
+ _firstComment = null;
+ _lastComment = null;
+ }
+ }
+ void appendStringToken2(TokenType type, String value, int offset) {
+ if (_firstComment == null) {
+ _tail = _tail.setNext(new StringToken(type, value, _tokenStart + offset));
+ } else {
+ _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart + offset, _firstComment));
+ _firstComment = null;
+ _lastComment = null;
+ }
+ }
+ void appendToken(TokenType type) {
+ if (_firstComment == null) {
+ _tail = _tail.setNext(new Token(type, _tokenStart));
+ } else {
+ _tail = _tail.setNext(new TokenWithComment(type, _tokenStart, _firstComment));
+ _firstComment = null;
+ _lastComment = null;
+ }
+ }
+ void appendToken2(TokenType type, int offset) {
+ if (_firstComment == null) {
+ _tail = _tail.setNext(new Token(type, offset));
+ } else {
+ _tail = _tail.setNext(new TokenWithComment(type, offset, _firstComment));
+ _firstComment = null;
+ _lastComment = null;
+ }
+ }
+ void beginToken() {
+ _tokenStart = offset;
+ }
+ int bigSwitch(int next) {
+ beginToken();
+ if (next == 0xd) {
+ next = advance();
+ if (next == 0xa) {
+ next = advance();
+ }
+ recordStartOfLine();
+ return next;
+ } else if (next == 0xa) {
+ recordStartOfLine();
+ return advance();
+ } else if (next == 0x9 || next == 0x20) {
+ return advance();
+ }
+ if (next == 0x72) {
+ int peek3 = peek();
+ if (peek3 == 0x22 || peek3 == 0x27) {
+ int start = offset;
+ return tokenizeString(advance(), start, true);
+ }
+ }
+ if (0x61 <= next && next <= 0x7a) {
+ return tokenizeKeywordOrIdentifier(next, true);
+ }
+ if ((0x41 <= next && next <= 0x5a) || next == 0x5f || next == 0x24) {
+ return tokenizeIdentifier(next, offset, true);
+ }
+ if (next == 0x3c) {
+ return tokenizeLessThan(next);
+ }
+ if (next == 0x3e) {
+ return tokenizeGreaterThan(next);
+ }
+ if (next == 0x3d) {
+ return tokenizeEquals(next);
+ }
+ if (next == 0x21) {
+ return tokenizeExclamation(next);
+ }
+ if (next == 0x2b) {
+ return tokenizePlus(next);
+ }
+ if (next == 0x2d) {
+ return tokenizeMinus(next);
+ }
+ if (next == 0x2a) {
+ return tokenizeMultiply(next);
+ }
+ if (next == 0x25) {
+ return tokenizePercent(next);
+ }
+ if (next == 0x26) {
+ return tokenizeAmpersand(next);
+ }
+ if (next == 0x7c) {
+ return tokenizeBar(next);
+ }
+ if (next == 0x5e) {
+ return tokenizeCaret(next);
+ }
+ if (next == 0x5b) {
+ return tokenizeOpenSquareBracket(next);
+ }
+ if (next == 0x7e) {
+ return tokenizeTilde(next);
+ }
+ if (next == 0x5c) {
+ appendToken(TokenType.BACKSLASH);
+ return advance();
+ }
+ if (next == 0x23) {
+ return tokenizeTag(next);
+ }
+ if (next == 0x28) {
+ appendBeginToken(TokenType.OPEN_PAREN);
+ return advance();
+ }
+ if (next == 0x29) {
+ appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
+ return advance();
+ }
+ if (next == 0x2c) {
+ appendToken(TokenType.COMMA);
+ return advance();
+ }
+ if (next == 0x3a) {
+ appendToken(TokenType.COLON);
+ return advance();
+ }
+ if (next == 0x3b) {
+ appendToken(TokenType.SEMICOLON);
+ return advance();
+ }
+ if (next == 0x3f) {
+ appendToken(TokenType.QUESTION);
+ return advance();
+ }
+ if (next == 0x5d) {
+ appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
+ return advance();
+ }
+ if (next == 0x60) {
+ appendToken(TokenType.BACKPING);
+ return advance();
+ }
+ if (next == 0x7b) {
+ appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
+ return advance();
+ }
+ if (next == 0x7d) {
+ appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
+ return advance();
+ }
+ if (next == 0x2f) {
+ return tokenizeSlashOrComment(next);
+ }
+ if (next == 0x40) {
+ appendToken(TokenType.AT);
+ return advance();
+ }
+ if (next == 0x22 || next == 0x27) {
+ return tokenizeString(next, offset, false);
+ }
+ if (next == 0x2e) {
+ return tokenizeDotOrNumber(next);
+ }
+ if (next == 0x30) {
+ return tokenizeHexOrNumber(next);
+ }
+ if (0x31 <= next && next <= 0x39) {
+ return tokenizeNumber(next);
+ }
+ if (next == -1) {
+ return -1;
+ }
+ if (Character.isLetter(next)) {
+ return tokenizeIdentifier(next, offset, true);
+ }
+ if (next == AbstractScanner._$NBSP) {
+ return advance();
+ }
+ reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
+ return advance();
+ }
+ /**
+ * Return the beginning token corresponding to a closing brace that was found while scanning
+ * inside a string interpolation expression. Tokens that cannot be matched with the closing brace
+ * will be dropped from the stack.
+ * @return the token to be paired with the closing brace
+ */
+ BeginToken findTokenMatchingClosingBraceInInterpolationExpression() {
+ int last = _groupingStack.length - 1;
+ while (last >= 0) {
+ BeginToken begin = _groupingStack[last];
+ if (begin.type == TokenType.OPEN_CURLY_BRACKET || begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+ return begin;
+ }
+ _hasUnmatchedGroups2 = true;
+ _groupingStack.removeAt(last);
+ last--;
+ }
+ return null;
+ }
+ Token firstToken() => _tokens.next;
+ /**
+ * Return the source being scanned.
+ * @return the source being scanned
+ */
+ Source get source => _source;
+ /**
+ * Report an error at the current offset.
+ * @param errorCode the error code indicating the nature of the error
+ * @param arguments any arguments needed to complete the error message
+ */
+ void reportError(ScannerErrorCode errorCode, List<Object> arguments) {
+ _errorListener.onError(new AnalysisError.con2(source, offset, 1, errorCode, [arguments]));
+ }
+ int select(int choice, TokenType yesType, TokenType noType) {
+ int next = advance();
+ if (next == choice) {
+ appendToken(yesType);
+ return advance();
+ } else {
+ appendToken(noType);
+ return next;
+ }
+ }
+ int select2(int choice, TokenType yesType, TokenType noType, int offset) {
+ int next = advance();
+ if (next == choice) {
+ appendToken2(yesType, offset);
+ return advance();
+ } else {
+ appendToken2(noType, offset);
+ return next;
+ }
+ }
+ int tokenizeAmpersand(int next) {
+ next = advance();
+ if (next == 0x26) {
+ appendToken(TokenType.AMPERSAND_AMPERSAND);
+ return advance();
+ } else if (next == 0x3d) {
+ appendToken(TokenType.AMPERSAND_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.AMPERSAND);
+ return next;
+ }
+ }
+ int tokenizeBar(int next) {
+ next = advance();
+ if (next == 0x7c) {
+ appendToken(TokenType.BAR_BAR);
+ return advance();
+ } else if (next == 0x3d) {
+ appendToken(TokenType.BAR_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.BAR);
+ return next;
+ }
+ }
+ int tokenizeCaret(int next) => select(0x3d, TokenType.CARET_EQ, TokenType.CARET);
+ int tokenizeDotOrNumber(int next) {
+ int start = offset;
+ next = advance();
+ if ((0x30 <= next && next <= 0x39)) {
+ return tokenizeFractionPart(next, start);
+ } else if (0x2e == next) {
+ return select(0x2e, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
+ } else {
+ appendToken(TokenType.PERIOD);
+ return next;
+ }
+ }
+ int tokenizeEquals(int next) {
+ next = advance();
+ if (next == 0x3d) {
+ appendToken(TokenType.EQ_EQ);
+ return advance();
+ } else if (next == 0x3e) {
+ appendToken(TokenType.FUNCTION);
+ return advance();
+ }
+ appendToken(TokenType.EQ);
+ return next;
+ }
+ int tokenizeExclamation(int next) {
+ next = advance();
+ if (next == 0x3d) {
+ appendToken(TokenType.BANG_EQ);
+ return advance();
+ }
+ appendToken(TokenType.BANG);
+ return next;
+ }
+ int tokenizeExponent(int next) {
+ if (next == 0x2b || next == 0x2d) {
+ next = advance();
+ }
+ bool hasDigits = false;
+ while (true) {
+ if (0x30 <= next && next <= 0x39) {
+ hasDigits = true;
+ } else {
+ if (!hasDigits) {
+ reportError(ScannerErrorCode.MISSING_DIGIT, []);
+ }
+ return next;
+ }
+ next = advance();
+ }
+ }
+ int tokenizeFractionPart(int next, int start) {
+ bool done = false;
+ bool hasDigit = false;
+ LOOP: while (!done) {
+ if (0x30 <= next && next <= 0x39) {
+ hasDigit = true;
+ } else if (0x65 == next || 0x45 == next) {
+ hasDigit = true;
+ next = tokenizeExponent(advance());
+ done = true;
+ continue LOOP;
+ } else {
+ done = true;
+ continue LOOP;
+ }
+ next = advance();
+ }
+ if (!hasDigit) {
+ appendStringToken(TokenType.INT, getString(start, -2));
+ if (0x2e == next) {
+ return select2(0x2e, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
+ }
+ appendToken2(TokenType.PERIOD, offset - 1);
+ return bigSwitch(next);
+ }
+ if (next == 0x64 || next == 0x44) {
+ next = advance();
+ }
+ appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
+ return next;
+ }
+ int tokenizeGreaterThan(int next) {
+ next = advance();
+ if (0x3d == next) {
+ appendToken(TokenType.GT_EQ);
+ return advance();
+ } else if (0x3e == next) {
+ next = advance();
+ if (0x3d == next) {
+ appendToken(TokenType.GT_GT_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.GT_GT);
+ return next;
+ }
+ } else {
+ appendToken(TokenType.GT);
+ return next;
+ }
+ }
+ int tokenizeHex(int next) {
+ int start = offset - 1;
+ bool hasDigits = false;
+ while (true) {
+ next = advance();
+ if ((0x30 <= next && next <= 0x39) || (0x41 <= next && next <= 0x46) || (0x61 <= next && next <= 0x66)) {
+ hasDigits = true;
+ } else {
+ if (!hasDigits) {
+ reportError(ScannerErrorCode.MISSING_HEX_DIGIT, []);
+ }
+ appendStringToken(TokenType.HEXADECIMAL, getString(start, next < 0 ? 0 : -1));
+ return next;
+ }
+ }
+ }
+ int tokenizeHexOrNumber(int next) {
+ int x = peek();
+ if (x == 0x78 || x == 0x58) {
+ advance();
+ return tokenizeHex(x);
+ }
+ return tokenizeNumber(next);
+ }
+ int tokenizeIdentifier(int next, int start, bool allowDollar) {
+ while ((0x61 <= next && next <= 0x7a) || (0x41 <= next && next <= 0x5a) || (0x30 <= next && next <= 0x39) || next == 0x5f || (next == 0x24 && allowDollar) || Character.isLetterOrDigit(next)) {
+ next = advance();
+ }
+ appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
+ return next;
+ }
+ int tokenizeInterpolatedExpression(int next, int start) {
+ appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
+ next = advance();
+ while (next != -1) {
+ if (next == 0x7d) {
+ BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
+ if (begin == null) {
+ beginToken();
+ appendToken(TokenType.CLOSE_CURLY_BRACKET);
+ next = advance();
+ beginToken();
+ return next;
+ } else if (begin.type == TokenType.OPEN_CURLY_BRACKET) {
+ beginToken();
+ appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
+ next = advance();
+ beginToken();
+ } else if (begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+ beginToken();
+ appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
+ next = advance();
+ beginToken();
+ return next;
+ }
+ } else {
+ next = bigSwitch(next);
+ }
+ }
+ if (next == -1) {
+ return next;
+ }
+ next = advance();
+ beginToken();
+ return next;
+ }
+ int tokenizeInterpolatedIdentifier(int next, int start) {
+ appendStringToken2(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
+ beginToken();
+ next = tokenizeKeywordOrIdentifier(next, false);
+ beginToken();
+ return next;
+ }
+ int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
+ KeywordState state = KeywordState.KEYWORD_STATE;
+ int start = offset;
+ while (state != null && 0x61 <= next && next <= 0x7a) {
+ state = state.next(next as int);
+ next = advance();
+ }
+ if (state == null || state.keyword() == null) {
+ return tokenizeIdentifier(next, start, allowDollar);
+ }
+ if ((0x41 <= next && next <= 0x5a) || (0x30 <= next && next <= 0x39) || next == 0x5f || next == 0x24) {
+ return tokenizeIdentifier(next, start, allowDollar);
+ } else if (next < 128) {
+ appendKeywordToken(state.keyword());
+ return next;
+ } else {
+ return tokenizeIdentifier(next, start, allowDollar);
+ }
+ }
+ int tokenizeLessThan(int next) {
+ next = advance();
+ if (0x3d == next) {
+ appendToken(TokenType.LT_EQ);
+ return advance();
+ } else if (0x3c == next) {
+ return select(0x3d, TokenType.LT_LT_EQ, TokenType.LT_LT);
+ } else {
+ appendToken(TokenType.LT);
+ return next;
+ }
+ }
+ int tokenizeMinus(int next) {
+ next = advance();
+ if (next == 0x2d) {
+ appendToken(TokenType.MINUS_MINUS);
+ return advance();
+ } else if (next == 0x3d) {
+ appendToken(TokenType.MINUS_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.MINUS);
+ return next;
+ }
+ }
+ int tokenizeMultiLineComment(int next) {
+ int nesting = 1;
+ next = advance();
+ while (true) {
+ if (-1 == next) {
+ reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
+ appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
+ return next;
+ } else if (0x2a == next) {
+ next = advance();
+ if (0x2f == next) {
+ --nesting;
+ if (0 == nesting) {
+ appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
+ return advance();
+ } else {
+ next = advance();
+ }
+ }
+ } else if (0x2f == next) {
+ next = advance();
+ if (0x2a == next) {
+ next = advance();
+ ++nesting;
+ }
+ } else {
+ next = advance();
+ }
+ }
+ }
+ int tokenizeMultiLineRawString(int quoteChar, int start) {
+ int next = advance();
+ outer: while (next != -1) {
+ while (next != quoteChar) {
+ next = advance();
+ if (next == -1) {
+ break outer;
+ }
+ }
+ next = advance();
+ if (next == quoteChar) {
+ next = advance();
+ if (next == quoteChar) {
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ }
+ }
+ reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ int tokenizeMultiLineString(int quoteChar, int start, bool raw) {
+ if (raw) {
+ return tokenizeMultiLineRawString(quoteChar, start);
+ }
+ int next = advance();
+ while (next != -1) {
+ if (next == 0x24) {
+ appendStringToken(TokenType.STRING, getString(start, -1));
+ beginToken();
+ next = tokenizeStringInterpolation(start);
+ start = offset;
+ continue;
+ }
+ if (next == quoteChar) {
+ next = advance();
+ if (next == quoteChar) {
+ next = advance();
+ if (next == quoteChar) {
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ }
+ continue;
+ }
+ if (next == 0x5c) {
+ next = advance();
+ if (next == -1) {
+ break;
+ }
+ }
+ next = advance();
+ }
+ reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ int tokenizeMultiply(int next) => select(0x3d, TokenType.STAR_EQ, TokenType.STAR);
+ int tokenizeNumber(int next) {
+ int start = offset;
+ while (true) {
+ next = advance();
+ if (0x30 <= next && next <= 0x39) {
+ continue;
+ } else if (next == 0x2e) {
+ return tokenizeFractionPart(advance(), start);
+ } else if (next == 0x64 || next == 0x44) {
+ appendStringToken(TokenType.DOUBLE, getString(start, 0));
+ return advance();
+ } else if (next == 0x65 || next == 0x45) {
+ return tokenizeFractionPart(next, start);
+ } else {
+ appendStringToken(TokenType.INT, getString(start, next < 0 ? 0 : -1));
+ return next;
+ }
+ }
+ }
+ int tokenizeOpenSquareBracket(int next) {
+ next = advance();
+ if (next == 0x5d) {
+ return select(0x3d, TokenType.INDEX_EQ, TokenType.INDEX);
+ } else {
+ appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
+ return next;
+ }
+ }
+ int tokenizePercent(int next) => select(0x3d, TokenType.PERCENT_EQ, TokenType.PERCENT);
+ int tokenizePlus(int next) {
+ next = advance();
+ if (0x2b == next) {
+ appendToken(TokenType.PLUS_PLUS);
+ return advance();
+ } else if (0x3d == next) {
+ appendToken(TokenType.PLUS_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.PLUS);
+ return next;
+ }
+ }
+ int tokenizeSingleLineComment(int next) {
+ while (true) {
+ next = advance();
+ if (0xa == next || 0xd == next || -1 == next) {
+ appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
+ return next;
+ }
+ }
+ }
+ int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
+ next = advance();
+ while (next != -1) {
+ if (next == quoteChar) {
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ } else if (next == 0xd || next == 0xa) {
+ reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ next = advance();
+ }
+ reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ int tokenizeSingleLineString(int next, int quoteChar, int start) {
+ while (next != quoteChar) {
+ if (next == 0x5c) {
+ next = advance();
+ } else if (next == 0x24) {
+ appendStringToken(TokenType.STRING, getString(start, -1));
+ beginToken();
+ next = tokenizeStringInterpolation(start);
+ start = offset;
+ continue;
+ }
+ if (next <= 0xd && (next == 0xa || next == 0xd || next == -1)) {
+ reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ next = advance();
+ }
+ appendStringToken(TokenType.STRING, getString(start, 0));
+ return advance();
+ }
+ int tokenizeSlashOrComment(int next) {
+ next = advance();
+ if (0x2a == next) {
+ return tokenizeMultiLineComment(next);
+ } else if (0x2f == next) {
+ return tokenizeSingleLineComment(next);
+ } else if (0x3d == next) {
+ appendToken(TokenType.SLASH_EQ);
+ return advance();
+ } else {
+ appendToken(TokenType.SLASH);
+ return next;
+ }
+ }
+ int tokenizeString(int next, int start, bool raw) {
+ int quoteChar = next;
+ next = advance();
+ if (quoteChar == next) {
+ next = advance();
+ if (quoteChar == next) {
+ return tokenizeMultiLineString(quoteChar, start, raw);
+ } else {
+ appendStringToken(TokenType.STRING, getString(start, -1));
+ return next;
+ }
+ }
+ if (raw) {
+ return tokenizeSingleLineRawString(next, quoteChar, start);
+ } else {
+ return tokenizeSingleLineString(next, quoteChar, start);
+ }
+ }
+ int tokenizeStringInterpolation(int start) {
+ beginToken();
+ int next = advance();
+ if (next == 0x7b) {
+ return tokenizeInterpolatedExpression(next, start);
+ } else {
+ return tokenizeInterpolatedIdentifier(next, start);
+ }
+ }
+ int tokenizeTag(int next) {
+ if (offset == 0) {
+ if (peek() == 0x21) {
+ do {
+ next = advance();
+ } while (next != 0xa && next != 0xd && next > 0);
+ appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
+ return next;
+ }
+ }
+ appendToken(TokenType.HASH);
+ return advance();
+ }
+ int tokenizeTilde(int next) {
+ next = advance();
+ if (next == 0x2f) {
+ return select(0x3d, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
+ } else {
+ appendToken(TokenType.TILDE);
+ return next;
+ }
+ }
+}
+/**
+ * Instances of the class {@code KeywordTokenWithComment} implement a keyword token that is preceded
+ * by comments.
+ */
+class KeywordTokenWithComment extends KeywordToken {
+ /**
+ * The first comment in the list of comments that precede this token.
+ */
+ Token _precedingComment;
+ /**
+ * Initialize a newly created token to to represent the given keyword and to be preceded by the
+ * comments reachable from the given comment.
+ * @param keyword the keyword being represented by this token
+ * @param offset the offset from the beginning of the file to the first character in the token
+ * @param precedingComment the first comment in the list of comments that precede this token
+ */
+ KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) {
+ this._precedingComment = precedingComment;
+ }
+ Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the abstract class {@code KeywordState} represent a state in a state machine used to
+ * scan keywords.
+ */
+class KeywordState {
+ /**
+ * An empty transition table used by leaf states.
+ */
+ static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>.fixedLength(26);
+ /**
+ * The initial state in the state machine.
+ */
+ static KeywordState KEYWORD_STATE = createKeywordStateTable();
+ /**
+ * Create the next state in the state machine where we have already recognized the subset of
+ * strings in the given array of strings starting at the given offset and having the given length.
+ * All of these strings have a common prefix and the next character is at the given start index.
+ * @param start the index of the character in the strings used to transition to a new state
+ * @param strings an array containing all of the strings that will be recognized by the state
+ * machine
+ * @param offset the offset of the first string in the array that has the prefix that is assumed
+ * to have been recognized by the time we reach the state being built
+ * @param length the number of strings in the array that pass through the state being built
+ * @return the state that was created
+ */
+ static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length) {
+ List<KeywordState> result = new List<KeywordState>.fixedLength(26);
+ assert(length != 0);
+ int chunk = 0x0;
+ int chunkStart = -1;
+ bool isLeaf = false;
+ for (int i = offset; i < offset + length; i++) {
+ if (strings[i].length == start) {
+ isLeaf = true;
+ }
+ if (strings[i].length > start) {
+ int c = strings[i].charCodeAt(start);
+ if (chunk != c) {
+ if (chunkStart != -1) {
+ result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
+ }
+ chunkStart = i;
+ chunk = c;
+ }
+ }
+ }
+ if (chunkStart != -1) {
+ assert(result[chunk - 0x61] == null);
+ result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length - chunkStart);
+ } else {
+ assert(length == 1);
+ return new KeywordState(_EMPTY_TABLE, strings[offset]);
+ }
+ if (isLeaf) {
+ return new KeywordState(result, strings[offset]);
+ } else {
+ return new KeywordState(result, null);
+ }
+ }
+ /**
+ * Create the initial state in the state machine.
+ * @return the state that was created
+ */
+ static KeywordState createKeywordStateTable() {
+ List<Keyword> values2 = Keyword.values;
+ List<String> strings = new List<String>.fixedLength(values2.length);
+ for (int i = 0; i < values2.length; i++) {
+ strings[i] = values2[i].syntax;
+ }
+ strings.sort();
+ return computeKeywordStateTable(0, strings, 0, strings.length);
+ }
+ /**
+ * A table mapping characters to the states to which those characters will transition. (The index
+ * into the array is the offset from the character {@code 'a'} to the transitioning character.)
+ */
+ List<KeywordState> _table;
+ /**
+ * The keyword that is recognized by this state, or {@code null} if this state is not a terminal
+ * state.
+ */
+ Keyword _keyword2;
+ /**
+ * Initialize a newly created state to have the given transitions and to recognize the keyword
+ * with the given syntax.
+ * @param table a table mapping characters to the states to which those characters will transition
+ * @param syntax the syntax of the keyword that is recognized by the state
+ */
+ KeywordState(List<KeywordState> table, String syntax) {
+ this._table = table;
+ this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
+ }
+ /**
+ * Return the keyword that was recognized by this state, or {@code null} if this state does not
+ * recognized a keyword.
+ * @return the keyword that was matched by reaching this state
+ */
+ Keyword keyword() => _keyword2;
+ /**
+ * Return the state that follows this state on a transition of the given character, or{@code null} if there is no valid state reachable from this state with such a transition.
+ * @param c the character used to transition from this state to another state
+ * @return the state that follows this state on a transition of the given character
+ */
+ KeywordState next(int c) => _table[c - 0x61];
+}
« no previous file with comments | « pkg/analyzer-experimental/lib/src/generated/parser.dart ('k') | pkg/analyzer-experimental/lib/src/generated/source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698