| Index: pkg/analyzer_experimental/lib/src/generated/scanner.dart
|
| diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
|
| index 81652aaf92930cf65f04a8cea21e147bfa88ebe9..2ed0c401484af0cdbdd57d0647a4fb9d48ff4610 100644
|
| --- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
|
| +++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
|
| @@ -188,6 +188,31 @@ class ScannerErrorCode extends Enum<ScannerErrorCode> implements ErrorCode {
|
| ErrorType get type => ErrorType.SYNTACTIC_ERROR;
|
| }
|
| /**
|
| + * Instances of the class `SubSequenceReader` implement a [CharacterReader] that reads
|
| + * characters from a character sequence, but adds a delta when reporting the current character
|
| + * offset so that the character sequence can be a subsequence from a larger sequence.
|
| + */
|
| +class SubSequenceReader extends CharSequenceReader {
|
| +
|
| + /**
|
| + * The offset from the beginning of the file to the beginning of the source being scanned.
|
| + */
|
| + int _offsetDelta = 0;
|
| +
|
| + /**
|
| + * Initialize a newly created reader to read the characters in the given sequence.
|
| + *
|
| + * @param sequence the sequence from which characters will be read
|
| + * @param offsetDelta the offset from the beginning of the file to the beginning of the source
|
| + * being scanned
|
| + */
|
| + SubSequenceReader(CharSequence sequence, int offsetDelta) : super(sequence) {
|
| + this._offsetDelta = offsetDelta;
|
| + }
|
| + int get offset => _offsetDelta + super.offset;
|
| + String getString(int start, int endDelta) => super.getString(start - _offsetDelta, endDelta);
|
| +}
|
| +/**
|
| * Instances of the class `TokenWithComment` represent a string token that is preceded by
|
| * comments.
|
| *
|
| @@ -367,8 +392,53 @@ class Keyword extends Enum<Keyword> {
|
| }
|
| }
|
| /**
|
| - * The abstract class `AbstractScanner` implements a scanner for Dart code. Subclasses are
|
| - * required to implement the interface used to access the characters being scanned.
|
| + * Instances of the class `CharSequenceReader` implement a [CharacterReader] that reads
|
| + * characters from a character sequence.
|
| + */
|
| +class CharSequenceReader implements CharacterReader {
|
| +
|
| + /**
|
| + * The sequence from which characters will be read.
|
| + */
|
| + CharSequence _sequence;
|
| +
|
| + /**
|
| + * 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 reader to read the characters in the given sequence.
|
| + *
|
| + * @param sequence the sequence from which characters will be read
|
| + */
|
| + CharSequenceReader(CharSequence sequence) {
|
| + this._sequence = sequence;
|
| + this._stringLength = sequence.length();
|
| + this._charOffset = -1;
|
| + }
|
| + int advance() {
|
| + if (_charOffset + 1 >= _stringLength) {
|
| + return -1;
|
| + }
|
| + return _sequence.charAt(++_charOffset);
|
| + }
|
| + int get offset => _charOffset;
|
| + String getString(int start, int endDelta) => _sequence.subSequence(start, _charOffset + 1 + endDelta).toString();
|
| + int peek() {
|
| + if (_charOffset + 1 >= _sequence.length()) {
|
| + return -1;
|
| + }
|
| + return _sequence.charAt(_charOffset + 1);
|
| + }
|
| +}
|
| +/**
|
| + * The class `Scanner` implements a scanner for Dart code.
|
| *
|
| * 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 "<<"
|
| @@ -378,7 +448,7 @@ class Keyword extends Enum<Keyword> {
|
| *
|
| * @coverage dart.engine.parser
|
| */
|
| -abstract class AbstractScanner {
|
| +class Scanner {
|
|
|
| /**
|
| * The source being scanned.
|
| @@ -386,6 +456,11 @@ abstract class AbstractScanner {
|
| Source source;
|
|
|
| /**
|
| + * The reader used to access the characters in the source.
|
| + */
|
| + CharacterReader _reader;
|
| +
|
| + /**
|
| * The error listener that will be informed of any errors that are found during the scan.
|
| */
|
| AnalysisErrorListener _errorListener;
|
| @@ -440,10 +515,12 @@ abstract class AbstractScanner {
|
| * Initialize a newly created scanner.
|
| *
|
| * @param source the source being scanned
|
| + * @param reader the character reader used to read the characters in the source
|
| * @param errorListener the error listener that will be informed of any errors that are found
|
| */
|
| - AbstractScanner(Source source, AnalysisErrorListener errorListener) {
|
| + Scanner(Source source, CharacterReader reader, AnalysisErrorListener errorListener) {
|
| this.source = source;
|
| + this._reader = reader;
|
| this._errorListener = errorListener;
|
| _tokens = new Token(TokenType.EOF, -1);
|
| _tokens.setNext(_tokens);
|
| @@ -460,20 +537,33 @@ abstract class AbstractScanner {
|
| 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 `true` if any unmatched groups were found during the parse.
|
| *
|
| - * @return the current offset of the scanner in the source
|
| + * @return `true` if any unmatched groups were found during the parse
|
| */
|
| - int get offset;
|
| + bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
|
|
|
| /**
|
| - * Return `true` if any unmatched groups were found during the parse.
|
| + * Record that the source begins on the given line and column at the current offset as given by
|
| + * the reader. The line starts for lines before the given line will not be correct.
|
| *
|
| - * @return `true` if any unmatched groups were found during the parse
|
| + * 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
|
| */
|
| - bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
|
| + void setSourceStart(int line, int column) {
|
| + int offset = _reader.offset;
|
| + if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
|
| + return;
|
| + }
|
| + for (int i = 2; i < line; i++) {
|
| + _lineStarts.add(1);
|
| + }
|
| + _lineStarts.add(offset - column + 1);
|
| + }
|
|
|
| /**
|
| * Scan the source code to produce a list of tokens representing the source.
|
| @@ -484,7 +574,7 @@ abstract class AbstractScanner {
|
| InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.AbstractScanner.tokenize");
|
| int tokenCounter = 0;
|
| try {
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| while (next != -1) {
|
| tokenCounter++;
|
| next = bigSwitch(next);
|
| @@ -498,36 +588,10 @@ abstract class AbstractScanner {
|
| }
|
|
|
| /**
|
| - * 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);
|
| + _lineStarts.add(_reader.offset);
|
| }
|
| void appendBeginToken(TokenType type) {
|
| BeginToken token;
|
| @@ -571,9 +635,9 @@ abstract class AbstractScanner {
|
| void appendEofToken() {
|
| Token eofToken;
|
| if (_firstComment == null) {
|
| - eofToken = new Token(TokenType.EOF, offset + 1);
|
| + eofToken = new Token(TokenType.EOF, _reader.offset + 1);
|
| } else {
|
| - eofToken = new TokenWithComment(TokenType.EOF, offset + 1, _firstComment);
|
| + eofToken = new TokenWithComment(TokenType.EOF, _reader.offset + 1, _firstComment);
|
| _firstComment = null;
|
| _lastComment = null;
|
| }
|
| @@ -629,36 +693,36 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| void beginToken() {
|
| - _tokenStart = offset;
|
| + _tokenStart = _reader.offset;
|
| }
|
| int bigSwitch(int next) {
|
| beginToken();
|
| if (next == 0xD) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| recordStartOfLine();
|
| return next;
|
| } else if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| recordStartOfLine();
|
| return next;
|
| } else if (next == 0x9 || next == 0x20) {
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x72) {
|
| - int peek = this.peek();
|
| + int peek = _reader.peek();
|
| if (peek == 0x22 || peek == 0x27) {
|
| - int start = offset;
|
| - return tokenizeString(advance(), start, true);
|
| + int start = _reader.offset;
|
| + return tokenizeString(_reader.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);
|
| + return tokenizeIdentifier(next, _reader.offset, true);
|
| }
|
| if (next == 0x3C) {
|
| return tokenizeLessThan(next);
|
| @@ -701,60 +765,60 @@ abstract class AbstractScanner {
|
| }
|
| if (next == 0x5C) {
|
| appendToken(TokenType.BACKSLASH);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x23) {
|
| return tokenizeTag(next);
|
| }
|
| if (next == 0x28) {
|
| appendBeginToken(TokenType.OPEN_PAREN);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x29) {
|
| appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x2C) {
|
| appendToken(TokenType.COMMA);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x3A) {
|
| appendToken(TokenType.COLON);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x3B) {
|
| appendToken(TokenType.SEMICOLON);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x3F) {
|
| appendToken(TokenType.QUESTION);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x5D) {
|
| appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x60) {
|
| appendToken(TokenType.BACKPING);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x7B) {
|
| appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x7D) {
|
| appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x2F) {
|
| return tokenizeSlashOrComment(next);
|
| }
|
| if (next == 0x40) {
|
| appendToken(TokenType.AT);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| if (next == 0x22 || next == 0x27) {
|
| - return tokenizeString(next, offset, false);
|
| + return tokenizeString(next, _reader.offset, false);
|
| }
|
| if (next == 0x2E) {
|
| return tokenizeDotOrNumber(next);
|
| @@ -769,7 +833,7 @@ abstract class AbstractScanner {
|
| return -1;
|
| }
|
| reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
|
|
| /**
|
| @@ -799,49 +863,49 @@ abstract class AbstractScanner {
|
| * @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));
|
| + _errorListener.onError(new AnalysisError.con2(source, _reader.offset, 1, errorCode, arguments));
|
| }
|
| int select(int choice, TokenType yesType, TokenType noType) {
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| if (next == choice) {
|
| appendToken(yesType);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(noType);
|
| return next;
|
| }
|
| }
|
| int select2(int choice, TokenType yesType, TokenType noType, int offset) {
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| if (next == choice) {
|
| appendToken2(yesType, offset);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken2(noType, offset);
|
| return next;
|
| }
|
| }
|
| int tokenizeAmpersand(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x26) {
|
| appendToken(TokenType.AMPERSAND_AMPERSAND);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (next == 0x3D) {
|
| appendToken(TokenType.AMPERSAND_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.AMPERSAND);
|
| return next;
|
| }
|
| }
|
| int tokenizeBar(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x7C) {
|
| appendToken(TokenType.BAR_BAR);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (next == 0x3D) {
|
| appendToken(TokenType.BAR_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.BAR);
|
| return next;
|
| @@ -849,8 +913,8 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeCaret(int next) => select(0x3D, TokenType.CARET_EQ, TokenType.CARET);
|
| int tokenizeDotOrNumber(int next) {
|
| - int start = offset;
|
| - next = advance();
|
| + int start = _reader.offset;
|
| + next = _reader.advance();
|
| if ((0x30 <= next && next <= 0x39)) {
|
| return tokenizeFractionPart(next, start);
|
| } else if (0x2E == next) {
|
| @@ -861,29 +925,29 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| int tokenizeEquals(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x3D) {
|
| appendToken(TokenType.EQ_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (next == 0x3E) {
|
| appendToken(TokenType.FUNCTION);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| appendToken(TokenType.EQ);
|
| return next;
|
| }
|
| int tokenizeExclamation(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x3D) {
|
| appendToken(TokenType.BANG_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| appendToken(TokenType.BANG);
|
| return next;
|
| }
|
| int tokenizeExponent(int next) {
|
| if (next == 0x2B || next == 0x2D) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| bool hasDigits = false;
|
| while (true) {
|
| @@ -895,7 +959,7 @@ abstract class AbstractScanner {
|
| }
|
| return next;
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| }
|
| int tokenizeFractionPart(int next, int start) {
|
| @@ -906,36 +970,36 @@ abstract class AbstractScanner {
|
| hasDigit = true;
|
| } else if (0x65 == next || 0x45 == next) {
|
| hasDigit = true;
|
| - next = tokenizeExponent(advance());
|
| + next = tokenizeExponent(_reader.advance());
|
| done = true;
|
| continue LOOP;
|
| } else {
|
| done = true;
|
| continue LOOP;
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| if (!hasDigit) {
|
| - appendStringToken(TokenType.INT, getString(start, -2));
|
| + appendStringToken(TokenType.INT, _reader.getString(start, -2));
|
| if (0x2E == next) {
|
| - return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
|
| + return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, _reader.offset - 1);
|
| }
|
| - appendToken2(TokenType.PERIOD, offset - 1);
|
| + appendToken2(TokenType.PERIOD, _reader.offset - 1);
|
| return bigSwitch(next);
|
| }
|
| - appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
|
| + appendStringToken(TokenType.DOUBLE, _reader.getString(start, next < 0 ? 0 : -1));
|
| return next;
|
| }
|
| int tokenizeGreaterThan(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x3D == next) {
|
| appendToken(TokenType.GT_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (0x3E == next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x3D == next) {
|
| appendToken(TokenType.GT_GT_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.GT_GT);
|
| return next;
|
| @@ -946,57 +1010,57 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| int tokenizeHex(int next) {
|
| - int start = offset - 1;
|
| + int start = _reader.offset - 1;
|
| bool hasDigits = false;
|
| while (true) {
|
| - next = advance();
|
| + next = _reader.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));
|
| + appendStringToken(TokenType.HEXADECIMAL, _reader.getString(start, next < 0 ? 0 : -1));
|
| return next;
|
| }
|
| }
|
| }
|
| int tokenizeHexOrNumber(int next) {
|
| - int x = peek();
|
| + int x = _reader.peek();
|
| if (x == 0x78 || x == 0x58) {
|
| - advance();
|
| + _reader.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)) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| - appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
|
| + appendStringToken(TokenType.IDENTIFIER, _reader.getString(start, next < 0 ? 0 : -1));
|
| return next;
|
| }
|
| int tokenizeInterpolatedExpression(int next, int start) {
|
| appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
|
| - next = advance();
|
| + next = _reader.advance();
|
| while (next != -1) {
|
| if (next == 0x7D) {
|
| BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
|
| if (begin == null) {
|
| beginToken();
|
| appendToken(TokenType.CLOSE_CURLY_BRACKET);
|
| - next = advance();
|
| + next = _reader.advance();
|
| beginToken();
|
| return next;
|
| } else if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET)) {
|
| beginToken();
|
| appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
|
| - next = advance();
|
| + next = _reader.advance();
|
| beginToken();
|
| } else if (identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
|
| beginToken();
|
| appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
|
| - next = advance();
|
| + next = _reader.advance();
|
| beginToken();
|
| return next;
|
| }
|
| @@ -1007,7 +1071,7 @@ abstract class AbstractScanner {
|
| if (next == -1) {
|
| return next;
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| beginToken();
|
| return next;
|
| }
|
| @@ -1022,10 +1086,10 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
|
| KeywordState state = KeywordState.KEYWORD_STATE;
|
| - int start = offset;
|
| + int start = _reader.offset;
|
| while (state != null && 0x61 <= next && next <= 0x7A) {
|
| state = state.next(next as int);
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| if (state == null || state.keyword() == null) {
|
| return tokenizeIdentifier(next, start, allowDollar);
|
| @@ -1040,10 +1104,10 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| int tokenizeLessThan(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x3D == next) {
|
| appendToken(TokenType.LT_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (0x3C == next) {
|
| return select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
|
| } else {
|
| @@ -1052,13 +1116,13 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| int tokenizeMinus(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x2D) {
|
| appendToken(TokenType.MINUS_MINUS);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (next == 0x3D) {
|
| appendToken(TokenType.MINUS_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.MINUS);
|
| return next;
|
| @@ -1066,157 +1130,157 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeMultiLineComment(int next) {
|
| int nesting = 1;
|
| - next = advance();
|
| + next = _reader.advance();
|
| while (true) {
|
| if (-1 == next) {
|
| reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
|
| - appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
|
| + appendCommentToken(TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
|
| return next;
|
| } else if (0x2A == next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x2F == next) {
|
| --nesting;
|
| if (0 == nesting) {
|
| - appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
|
| - return advance();
|
| + appendCommentToken(TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
|
| + return _reader.advance();
|
| } else {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| }
|
| } else if (0x2F == next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x2A == next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| ++nesting;
|
| }
|
| } else if (next == 0xD) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| recordStartOfLine();
|
| } else if (next == 0xA) {
|
| recordStartOfLine();
|
| - next = advance();
|
| + next = _reader.advance();
|
| } else {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| }
|
| }
|
| int tokenizeMultiLineRawString(int quoteChar, int start) {
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| outer: while (next != -1) {
|
| while (next != quoteChar) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == -1) {
|
| break outer;
|
| } else if (next == 0xD) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| recordStartOfLine();
|
| } else if (next == 0xA) {
|
| recordStartOfLine();
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == quoteChar) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == quoteChar) {
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| }
|
| }
|
| reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| int tokenizeMultiLineString(int quoteChar, int start, bool raw) {
|
| if (raw) {
|
| return tokenizeMultiLineRawString(quoteChar, start);
|
| }
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| while (next != -1) {
|
| if (next == 0x24) {
|
| - appendStringToken(TokenType.STRING, getString(start, -1));
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, -1));
|
| beginToken();
|
| next = tokenizeStringInterpolation(start);
|
| - start = offset;
|
| + start = _reader.offset;
|
| continue;
|
| }
|
| if (next == quoteChar) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == quoteChar) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == quoteChar) {
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| }
|
| continue;
|
| }
|
| if (next == 0x5C) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == -1) {
|
| break;
|
| }
|
| bool missingCharacter = false;
|
| if (next == 0xD) {
|
| missingCharacter = true;
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| recordStartOfLine();
|
| } else if (next == 0xA) {
|
| missingCharacter = true;
|
| recordStartOfLine();
|
| - next = advance();
|
| + next = _reader.advance();
|
| } else {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| if (missingCharacter) {
|
| - _errorListener.onError(new AnalysisError.con2(source, offset - 1, 1, ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, []));
|
| + _errorListener.onError(new AnalysisError.con2(source, _reader.offset - 1, 1, ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, []));
|
| }
|
| } else if (next == 0xD) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0xA) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| recordStartOfLine();
|
| } else if (next == 0xA) {
|
| recordStartOfLine();
|
| - next = advance();
|
| + next = _reader.advance();
|
| } else {
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| }
|
| reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| int tokenizeMultiply(int next) => select(0x3D, TokenType.STAR_EQ, TokenType.STAR);
|
| int tokenizeNumber(int next) {
|
| - int start = offset;
|
| + int start = _reader.offset;
|
| while (true) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x30 <= next && next <= 0x39) {
|
| continue;
|
| } else if (next == 0x2E) {
|
| - return tokenizeFractionPart(advance(), start);
|
| + return tokenizeFractionPart(_reader.advance(), start);
|
| } else if (next == 0x65 || next == 0x45) {
|
| return tokenizeFractionPart(next, start);
|
| } else {
|
| - appendStringToken(TokenType.INT, getString(start, next < 0 ? 0 : -1));
|
| + appendStringToken(TokenType.INT, _reader.getString(start, next < 0 ? 0 : -1));
|
| return next;
|
| }
|
| }
|
| }
|
| int tokenizeOpenSquareBracket(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x5D) {
|
| return select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
|
| } else {
|
| @@ -1226,13 +1290,13 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizePercent(int next) => select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
|
| int tokenizePlus(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x2B == next) {
|
| appendToken(TokenType.PLUS_PLUS);
|
| - return advance();
|
| + return _reader.advance();
|
| } else if (0x3D == next) {
|
| appendToken(TokenType.PLUS_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.PLUS);
|
| return next;
|
| @@ -1240,63 +1304,63 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeSingleLineComment(int next) {
|
| while (true) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (-1 == next) {
|
| - appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
|
| + appendCommentToken(TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, 0));
|
| return next;
|
| } else if (0xA == next || 0xD == next) {
|
| - appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, -1));
|
| + appendCommentToken(TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, -1));
|
| return next;
|
| }
|
| }
|
| }
|
| int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| while (next != -1) {
|
| if (next == quoteChar) {
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| } else if (next == 0xD || next == 0xA) {
|
| reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| int tokenizeSingleLineString(int next, int quoteChar, int start) {
|
| while (next != quoteChar) {
|
| if (next == 0x5C) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| } else if (next == 0x24) {
|
| - appendStringToken(TokenType.STRING, getString(start, -1));
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, -1));
|
| beginToken();
|
| next = tokenizeStringInterpolation(start);
|
| - start = offset;
|
| + start = _reader.offset;
|
| continue;
|
| }
|
| if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
|
| reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| - next = advance();
|
| + next = _reader.advance();
|
| }
|
| - appendStringToken(TokenType.STRING, getString(start, 0));
|
| - return advance();
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, 0));
|
| + return _reader.advance();
|
| }
|
| int tokenizeSlashOrComment(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (0x2A == next) {
|
| return tokenizeMultiLineComment(next);
|
| } else if (0x2F == next) {
|
| return tokenizeSingleLineComment(next);
|
| } else if (0x3D == next) {
|
| appendToken(TokenType.SLASH_EQ);
|
| - return advance();
|
| + return _reader.advance();
|
| } else {
|
| appendToken(TokenType.SLASH);
|
| return next;
|
| @@ -1304,13 +1368,13 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeString(int next, int start, bool raw) {
|
| int quoteChar = next;
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (quoteChar == next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (quoteChar == next) {
|
| return tokenizeMultiLineString(quoteChar, start, raw);
|
| } else {
|
| - appendStringToken(TokenType.STRING, getString(start, -1));
|
| + appendStringToken(TokenType.STRING, _reader.getString(start, -1));
|
| return next;
|
| }
|
| }
|
| @@ -1322,7 +1386,7 @@ abstract class AbstractScanner {
|
| }
|
| int tokenizeStringInterpolation(int start) {
|
| beginToken();
|
| - int next = advance();
|
| + int next = _reader.advance();
|
| if (next == 0x7B) {
|
| return tokenizeInterpolatedExpression(next, start);
|
| } else {
|
| @@ -1330,20 +1394,20 @@ abstract class AbstractScanner {
|
| }
|
| }
|
| int tokenizeTag(int next) {
|
| - if (offset == 0) {
|
| - if (peek() == 0x21) {
|
| + if (_reader.offset == 0) {
|
| + if (_reader.peek() == 0x21) {
|
| do {
|
| - next = advance();
|
| + next = _reader.advance();
|
| } while (next != 0xA && next != 0xD && next > 0);
|
| - appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
|
| + appendStringToken(TokenType.SCRIPT_TAG, _reader.getString(_tokenStart, 0));
|
| return next;
|
| }
|
| }
|
| appendToken(TokenType.HASH);
|
| - return advance();
|
| + return _reader.advance();
|
| }
|
| int tokenizeTilde(int next) {
|
| - next = advance();
|
| + next = _reader.advance();
|
| if (next == 0x2F) {
|
| return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
|
| } else {
|
| @@ -1379,56 +1443,6 @@ class StringToken extends Token {
|
| String value() => _value2;
|
| }
|
| /**
|
| - * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
|
| - * buffer. The scanning logic is in the superclass.
|
| - *
|
| - * @coverage dart.engine.parser
|
| - */
|
| -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 as CharSequence)).subSequence(start, _charOffset + 1 + endDelta).toString();
|
| - int peek() {
|
| - if (_charOffset + 1 >= _buffer.length()) {
|
| - return -1;
|
| - }
|
| - return _buffer.charAt(_charOffset + 1);
|
| - }
|
| -}
|
| -/**
|
| * Instances of the class `TokenWithComment` represent a normal token that is preceded by
|
| * comments.
|
| *
|
| @@ -1583,86 +1597,44 @@ class Token {
|
| Object value() => type.lexeme;
|
| }
|
| /**
|
| - * Instances of the class `StringScanner` implement a scanner that reads from a string. The
|
| - * scanning logic is in the superclass.
|
| - *
|
| - * @coverage dart.engine.parser
|
| + * The interface `CharacterReader`
|
| */
|
| -class StringScanner extends AbstractScanner {
|
| -
|
| - /**
|
| - * The offset from the beginning of the file to the beginning of the source being scanned.
|
| - */
|
| - int _offsetDelta = 0;
|
| +abstract class CharacterReader {
|
|
|
| /**
|
| - * The string from which characters will be read.
|
| - */
|
| - String _string;
|
| -
|
| - /**
|
| - * The number of characters in the string.
|
| + * Advance the current position and return the character at the new current position.
|
| + *
|
| + * @return the character at the new current position
|
| */
|
| - int _stringLength = 0;
|
| + int advance();
|
|
|
| /**
|
| - * The index, relative to the string, of the last character that was read.
|
| + * Return the current offset relative to the beginning of the source. 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 entire source code has been scanned.
|
| + *
|
| + * @return the current offset of the scanner in the source
|
| */
|
| - int _charOffset = 0;
|
| + int get offset;
|
|
|
| /**
|
| - * Initialize a newly created scanner to scan the characters in the given string.
|
| + * 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 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
|
| + * @param start the offset to the beginning of the string, relative to the start of the file
|
| + * @param endDelta the number of characters 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
|
| */
|
| - 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;
|
| + String getString(int start, int endDelta);
|
|
|
| /**
|
| - * 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.
|
| - *
|
| - * 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.
|
| + * Return the character at the current position without changing the current position.
|
| *
|
| - * @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
|
| + * @return the character at the current position
|
| */
|
| - 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.codeUnitAt(++_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.codeUnitAt(_charOffset + 1);
|
| - }
|
| + int peek();
|
| }
|
| /**
|
| * Instances of the class `BeginTokenWithComment` represent a begin token that is preceded by
|
|
|