Chromium Code Reviews| Index: pkg/front_end/lib/src/scanner/errors.dart |
| diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart |
| index bcf0c56585f52f7fcf62353e86605a15427dc998..10853c1f946b76d91b6a0654d8442b082c4438a9 100644 |
| --- a/pkg/front_end/lib/src/scanner/errors.dart |
| +++ b/pkg/front_end/lib/src/scanner/errors.dart |
| @@ -3,6 +3,9 @@ |
| // BSD-style license that can be found in the LICENSE file. |
| import 'package:front_end/src/base/errors.dart'; |
| +import 'package:front_end/src/fasta/scanner/error_token.dart'; |
| +import 'package:front_end/src/fasta/scanner/token.dart'; |
| +import 'package:front_end/src/fasta/scanner/token_constants.dart'; |
| /** |
| * The error codes used for errors detected by the scanner. |
| @@ -57,3 +60,78 @@ class ScannerErrorCode extends ErrorCode { |
| @override |
| ErrorType get type => ErrorType.SYNTACTIC_ERROR; |
| } |
| + |
| +/** |
|
ahe
2017/03/23 11:52:36
Consistency: use either /// or /**
danrubel
2017/03/24 15:44:20
Good point. Changed /// to /** below to match the
|
| + * Used to report a scan error at the given offset. |
| + * The [errorCode] is the error code indicating the nature of the error. |
| + * The [arguments] are any arguments needed to complete the error message |
|
ahe
2017/03/23 11:52:36
Add a period to the end of this sentence.
danrubel
2017/03/24 15:44:20
Done.
|
| + */ |
| +typedef ReportError( |
| + ScannerErrorCode errorCode, int offset, List<Object> arguments); |
| + |
| +/// Translates the given error [token] into an analyzer error and reports it |
| +/// using [reportError]. |
| +void translateErrorToken(ErrorToken token, ReportError reportError) { |
| + int charOffset = token.charOffset; |
| + // TODO(paulberry,ahe): why is endOffset sometimes null? |
| + int endOffset = token.endOffset ?? charOffset; |
| + void _makeError(ScannerErrorCode errorCode, List<Object> arguments) { |
| + if (_isAtEnd(token, charOffset)) { |
| + // Analyzer never generates an error message past the end of the input, |
| + // since such an error would not be visible in an editor. |
| + // TODO(paulberry,ahe): would it make sense to replicate this behavior |
| + // in fasta, or move it elsewhere in analyzer? |
| + charOffset--; |
| + } |
| + reportError(errorCode, charOffset, arguments); |
| + } |
| + |
| + var errorCode = token.errorCode; |
| + switch (errorCode) { |
| + case ErrorKind.UnterminatedString: |
| + // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| + // string; analyzer expects the end of the string. |
| + charOffset = endOffset; |
| + return _makeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, null); |
| + case ErrorKind.UnmatchedToken: |
| + return null; |
| + case ErrorKind.UnterminatedComment: |
| + // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| + // comment; analyzer expects the end of the comment. |
| + charOffset = endOffset; |
| + return _makeError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, null); |
| + case ErrorKind.MissingExponent: |
| + // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| + // number; analyzer expects the end of the number. |
| + charOffset = endOffset; |
| + return _makeError(ScannerErrorCode.MISSING_DIGIT, null); |
| + case ErrorKind.ExpectedHexDigit: |
| + // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| + // number; analyzer expects the end of the number. |
| + charOffset = endOffset; |
| + return _makeError(ScannerErrorCode.MISSING_HEX_DIGIT, null); |
| + case ErrorKind.NonAsciiIdentifier: |
| + case ErrorKind.NonAsciiWhitespace: |
| + return _makeError(ScannerErrorCode.ILLEGAL_CHARACTER, [token.character]); |
| + case ErrorKind.UnexpectedDollarInString: |
| + return null; |
| + default: |
| + throw new UnimplementedError('$errorCode'); |
| + } |
| +} |
| + |
| +/// Determines whether the given [charOffset], which came from the non-EOF token |
| +/// [token], represents the end of the input. |
| +bool _isAtEnd(Token token, int charOffset) { |
| + while (true) { |
| + // Skip to the next token. |
| + token = token.next; |
| + // If we've found an EOF token, its charOffset indicates where the end of |
| + // the input is. |
| + if (token.isEof) return token.charOffset == charOffset; |
| + // If we've found a non-error token, then we know there is additional input |
| + // text after [charOffset]. |
| + if (token.info.kind != BAD_INPUT_TOKEN) return false; |
| + // Otherwise keep looking. |
| + } |
| +} |