OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'package:front_end/src/base/errors.dart'; | 5 import 'package:front_end/src/base/errors.dart'; |
| 6 import 'package:front_end/src/fasta/scanner/error_token.dart'; |
| 7 import 'package:front_end/src/fasta/scanner/token.dart'; |
| 8 import 'package:front_end/src/fasta/scanner/token_constants.dart'; |
6 | 9 |
7 /** | 10 /** |
8 * The error codes used for errors detected by the scanner. | 11 * The error codes used for errors detected by the scanner. |
9 */ | 12 */ |
10 class ScannerErrorCode extends ErrorCode { | 13 class ScannerErrorCode extends ErrorCode { |
11 /** | 14 /** |
12 * Parameters: | 15 * Parameters: |
13 * 0: the illegal character | 16 * 0: the illegal character |
14 */ | 17 */ |
15 static const ScannerErrorCode ILLEGAL_CHARACTER = | 18 static const ScannerErrorCode ILLEGAL_CHARACTER = |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 */ | 53 */ |
51 const ScannerErrorCode(String name, String message, [String correction]) | 54 const ScannerErrorCode(String name, String message, [String correction]) |
52 : super(name, message, correction); | 55 : super(name, message, correction); |
53 | 56 |
54 @override | 57 @override |
55 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; | 58 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; |
56 | 59 |
57 @override | 60 @override |
58 ErrorType get type => ErrorType.SYNTACTIC_ERROR; | 61 ErrorType get type => ErrorType.SYNTACTIC_ERROR; |
59 } | 62 } |
| 63 |
| 64 /** |
| 65 * Used to report a scan error at the given offset. |
| 66 * The [errorCode] is the error code indicating the nature of the error. |
| 67 * The [arguments] are any arguments needed to complete the error message |
| 68 */ |
| 69 typedef ReportError( |
| 70 ScannerErrorCode errorCode, int offset, List<Object> arguments); |
| 71 |
| 72 /// Translates the given error [token] into an analyzer error and reports it |
| 73 /// using [reportError]. |
| 74 void translateErrorToken(ErrorToken token, ReportError reportError) { |
| 75 int charOffset = token.charOffset; |
| 76 // TODO(paulberry,ahe): why is endOffset sometimes null? |
| 77 int endOffset = token.endOffset ?? charOffset; |
| 78 void _makeError(ScannerErrorCode errorCode, List<Object> arguments) { |
| 79 if (_isAtEnd(token, charOffset)) { |
| 80 // Analyzer never generates an error message past the end of the input, |
| 81 // since such an error would not be visible in an editor. |
| 82 // TODO(paulberry,ahe): would it make sense to replicate this behavior |
| 83 // in fasta, or move it elsewhere in analyzer? |
| 84 charOffset--; |
| 85 } |
| 86 reportError(errorCode, charOffset, arguments); |
| 87 } |
| 88 |
| 89 var errorCode = token.errorCode; |
| 90 switch (errorCode) { |
| 91 case ErrorKind.UnterminatedString: |
| 92 // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| 93 // string; analyzer expects the end of the string. |
| 94 charOffset = endOffset; |
| 95 return _makeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, null); |
| 96 case ErrorKind.UnmatchedToken: |
| 97 return null; |
| 98 case ErrorKind.UnterminatedComment: |
| 99 // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| 100 // comment; analyzer expects the end of the comment. |
| 101 charOffset = endOffset; |
| 102 return _makeError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, null); |
| 103 case ErrorKind.MissingExponent: |
| 104 // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| 105 // number; analyzer expects the end of the number. |
| 106 charOffset = endOffset; |
| 107 return _makeError(ScannerErrorCode.MISSING_DIGIT, null); |
| 108 case ErrorKind.ExpectedHexDigit: |
| 109 // TODO(paulberry,ahe): Fasta reports the error location as the entire |
| 110 // number; analyzer expects the end of the number. |
| 111 charOffset = endOffset; |
| 112 return _makeError(ScannerErrorCode.MISSING_HEX_DIGIT, null); |
| 113 case ErrorKind.NonAsciiIdentifier: |
| 114 case ErrorKind.NonAsciiWhitespace: |
| 115 return _makeError(ScannerErrorCode.ILLEGAL_CHARACTER, [token.character]); |
| 116 case ErrorKind.UnexpectedDollarInString: |
| 117 return null; |
| 118 default: |
| 119 throw new UnimplementedError('$errorCode'); |
| 120 } |
| 121 } |
| 122 |
| 123 /// Determines whether the given [charOffset], which came from the non-EOF token |
| 124 /// [token], represents the end of the input. |
| 125 bool _isAtEnd(Token token, int charOffset) { |
| 126 while (true) { |
| 127 // Skip to the next token. |
| 128 token = token.next; |
| 129 // If we've found an EOF token, its charOffset indicates where the end of |
| 130 // the input is. |
| 131 if (token.isEof) return token.charOffset == charOffset; |
| 132 // If we've found a non-error token, then we know there is additional input |
| 133 // text after [charOffset]. |
| 134 if (token.info.kind != BAD_INPUT_TOKEN) return false; |
| 135 // Otherwise keep looking. |
| 136 } |
| 137 } |
OLD | NEW |