| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 licenset hat can be found in the LICENSE file. | 3 // BSD-style licenset hat can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.scanner.recover; | 5 library fasta.scanner.recover; |
| 6 | 6 |
| 7 import '../../scanner/token.dart' show TokenType; | 7 import '../../scanner/token.dart' show TokenType; |
| 8 | 8 |
| 9 import '../fasta_codes.dart' | 9 import '../fasta_codes.dart' |
| 10 show | 10 show |
| 11 FastaCode, | 11 FastaCode, |
| 12 codeAsciiControlCharacter, | 12 codeAsciiControlCharacter, |
| 13 codeEncoding, | 13 codeEncoding, |
| 14 codeExpectedHexDigit, | 14 codeExpectedHexDigit, |
| 15 codeMissingExponent, | 15 codeMissingExponent, |
| 16 codeNonAsciiIdentifier, | 16 codeNonAsciiIdentifier, |
| 17 codeNonAsciiWhitespace, | 17 codeNonAsciiWhitespace, |
| 18 codeUnexpectedDollarInString, | 18 codeUnexpectedDollarInString, |
| 19 codeUnmatchedToken, | 19 codeUnmatchedToken, |
| 20 codeUnterminatedComment, | 20 codeUnterminatedComment, |
| 21 codeUnterminatedString; | 21 codeUnterminatedString; |
| 22 | 22 |
| 23 import 'token.dart' show StringToken, SymbolToken, Token; | 23 import 'token.dart' show StringToken, SymbolToken, Token; |
| 24 | 24 |
| 25 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorToken; | 25 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorToken; |
| 26 | 26 |
| 27 import 'precedence.dart' as Precedence; | |
| 28 | |
| 29 /// Recover from errors in [tokens]. The original sources are provided as | 27 /// Recover from errors in [tokens]. The original sources are provided as |
| 30 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and | 28 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and |
| 31 /// must be updated if recovery is performed rewriting the original source | 29 /// must be updated if recovery is performed rewriting the original source |
| 32 /// code. | 30 /// code. |
| 33 Token defaultRecoveryStrategy( | 31 Token defaultRecoveryStrategy( |
| 34 List<int> bytes, Token tokens, List<int> lineStarts) { | 32 List<int> bytes, Token tokens, List<int> lineStarts) { |
| 35 // See [Parser.reportErrorToken](../parser/src/parser.dart) for how | 33 // See [Parser.reportErrorToken](../parser/src/parser.dart) for how |
| 36 // it currently handles lexical errors. In addition, notice how the parser | 34 // it currently handles lexical errors. In addition, notice how the parser |
| 37 // calls [handleInvalidExpression], [handleInvalidFunctionBody], and | 35 // calls [handleInvalidExpression], [handleInvalidFunctionBody], and |
| 38 // [handleInvalidTypeReference] to allow the listener to recover its internal | 36 // [handleInvalidTypeReference] to allow the listener to recover its internal |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 // NonAsciiIdentifierToken("ø"), | 77 // NonAsciiIdentifierToken("ø"), |
| 80 // StringToken("d"), | 78 // StringToken("d"), |
| 81 // EOF, | 79 // EOF, |
| 82 // ] | 80 // ] |
| 83 bool prepend = false; | 81 bool prepend = false; |
| 84 | 82 |
| 85 // True if following token is also an identifier that starts right where | 83 // True if following token is also an identifier that starts right where |
| 86 // [errorTail] ends. This is the case for "b" above. | 84 // [errorTail] ends. This is the case for "b" above. |
| 87 bool append = false; | 85 bool append = false; |
| 88 if (goodTail != null) { | 86 if (goodTail != null) { |
| 89 if (goodTail.info == Precedence.IDENTIFIER_INFO && | 87 if (goodTail.info == TokenType.IDENTIFIER && |
| 90 goodTail.charEnd == first.charOffset) { | 88 goodTail.charEnd == first.charOffset) { |
| 91 prepend = true; | 89 prepend = true; |
| 92 } | 90 } |
| 93 } | 91 } |
| 94 Token next = errorTail.next; | 92 Token next = errorTail.next; |
| 95 if (next.info == Precedence.IDENTIFIER_INFO && | 93 if (next.info == TokenType.IDENTIFIER && |
| 96 errorTail.charOffset + 1 == next.charOffset) { | 94 errorTail.charOffset + 1 == next.charOffset) { |
| 97 append = true; | 95 append = true; |
| 98 } | 96 } |
| 99 if (prepend) { | 97 if (prepend) { |
| 100 codeUnits.addAll(goodTail.lexeme.codeUnits); | 98 codeUnits.addAll(goodTail.lexeme.codeUnits); |
| 101 } | 99 } |
| 102 NonAsciiIdentifierToken current = first; | 100 NonAsciiIdentifierToken current = first; |
| 103 while (current != errorTail) { | 101 while (current != errorTail) { |
| 104 codeUnits.add(current.character); | 102 codeUnits.add(current.character); |
| 105 current = current.next; | 103 current = current.next; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 116 beforeGoodTail = null; | 114 beforeGoodTail = null; |
| 117 } else { | 115 } else { |
| 118 goodTail = beforeGoodTail; | 116 goodTail = beforeGoodTail; |
| 119 } | 117 } |
| 120 } | 118 } |
| 121 if (append) { | 119 if (append) { |
| 122 codeUnits.addAll(next.lexeme.codeUnits); | 120 codeUnits.addAll(next.lexeme.codeUnits); |
| 123 next = next.next; | 121 next = next.next; |
| 124 } | 122 } |
| 125 String value = new String.fromCharCodes(codeUnits); | 123 String value = new String.fromCharCodes(codeUnits); |
| 126 return synthesizeToken(charOffset, value, Precedence.IDENTIFIER_INFO) | 124 return synthesizeToken(charOffset, value, TokenType.IDENTIFIER) |
| 127 ..next = next; | 125 ..next = next; |
| 128 } | 126 } |
| 129 | 127 |
| 130 recoverExponent() { | 128 recoverExponent() { |
| 131 return synthesizeToken(errorTail.charOffset, "NaN", Precedence.DOUBLE_INFO) | 129 return synthesizeToken(errorTail.charOffset, "NaN", TokenType.DOUBLE) |
| 132 ..next = errorTail.next; | 130 ..next = errorTail.next; |
| 133 } | 131 } |
| 134 | 132 |
| 135 recoverString() { | 133 recoverString() { |
| 136 // TODO(ahe): Improve this. | 134 // TODO(ahe): Improve this. |
| 137 return skipToEof(errorTail); | 135 return skipToEof(errorTail); |
| 138 } | 136 } |
| 139 | 137 |
| 140 recoverHexDigit() { | 138 recoverHexDigit() { |
| 141 return synthesizeToken(errorTail.charOffset, "-1", Precedence.INT_INFO) | 139 return synthesizeToken(errorTail.charOffset, "-1", TokenType.INT) |
| 142 ..next = errorTail.next; | 140 ..next = errorTail.next; |
| 143 } | 141 } |
| 144 | 142 |
| 145 recoverStringInterpolation() { | 143 recoverStringInterpolation() { |
| 146 // TODO(ahe): Improve this. | 144 // TODO(ahe): Improve this. |
| 147 return skipToEof(errorTail); | 145 return skipToEof(errorTail); |
| 148 } | 146 } |
| 149 | 147 |
| 150 recoverComment() { | 148 recoverComment() { |
| 151 // TODO(ahe): Improve this. | 149 // TODO(ahe): Improve this. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 241 |
| 244 String closeBraceFor(String openBrace) { | 242 String closeBraceFor(String openBrace) { |
| 245 return const { | 243 return const { |
| 246 '(': ')', | 244 '(': ')', |
| 247 '[': ']', | 245 '[': ']', |
| 248 '{': '}', | 246 '{': '}', |
| 249 '<': '>', | 247 '<': '>', |
| 250 r'${': '}', | 248 r'${': '}', |
| 251 }[openBrace]; | 249 }[openBrace]; |
| 252 } | 250 } |
| OLD | NEW |