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 'token.dart' show | 7 import 'token.dart' show StringToken, Token; |
8 StringToken, | |
9 Token; | |
10 | 8 |
11 import 'error_token.dart' show | 9 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorKind, ErrorToken; |
12 NonAsciiIdentifierToken, | |
13 ErrorKind, | |
14 ErrorToken; | |
15 | 10 |
16 import 'precedence.dart' as Precedence; | 11 import 'precedence.dart' as Precedence; |
17 | 12 |
18 import 'precedence.dart' show | 13 import 'precedence.dart' show PrecedenceInfo; |
19 PrecedenceInfo; | |
20 | 14 |
21 /// Recover from errors in [tokens]. The original sources are provided as | 15 /// Recover from errors in [tokens]. The original sources are provided as |
22 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and | 16 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and |
23 /// must be updated if recovery is performed rewriting the original source | 17 /// must be updated if recovery is performed rewriting the original source |
24 /// code. | 18 /// code. |
25 Token defaultRecoveryStrategy( | 19 Token defaultRecoveryStrategy( |
26 List<int> bytes, Token tokens, List<int> lineStarts) { | 20 List<int> bytes, Token tokens, List<int> lineStarts) { |
27 // See [Parser.reportErrorToken](package:front_end/src/fasta/parser/src/parser
.dart) for how | 21 // See [Parser.reportErrorToken](package:front_end/src/fasta/parser/src/parser
.dart) for how |
28 // it currently handles lexical errors. In addition, notice how the parser | 22 // it currently handles lexical errors. In addition, notice how the parser |
29 // calls [handleInvalidExpression], [handleInvalidFunctionBody], and | 23 // calls [handleInvalidExpression], [handleInvalidFunctionBody], and |
30 // [handleInvalidTypeReference] to allow the listener to recover its internal | 24 // [handleInvalidTypeReference] to allow the listener to recover its internal |
31 // state. See [package:compiler/src/parser/element_listener.dart] for an | 25 // state. See [package:compiler/src/parser/element_listener.dart] for an |
32 // example of how these events are used. | 26 // example of how these events are used. |
33 // | 27 // |
34 // In addition, the scanner will attempt a bit of recovery when braces don't | 28 // In addition, the scanner will attempt a bit of recovery when braces don't |
35 // match up during brace grouping. See | 29 // match up during brace grouping. See |
36 // [ArrayBasedScanner.discardBeginGroupUntil](array_based_scanner.dart). For | 30 // [ArrayBasedScanner.discardBeginGroupUntil](array_based_scanner.dart). For |
37 // more details on brace grouping see | 31 // more details on brace grouping see |
38 // [AbstractScanner.unmatchedBeginGroup](abstract_scanner.dart). | 32 // [AbstractScanner.unmatchedBeginGroup](abstract_scanner.dart). |
39 | 33 |
40 /// Tokens with errors. | 34 /// Tokens with errors. |
41 ErrorToken error; | 35 ErrorToken error; |
| 36 |
42 /// Used for appending to [error]. | 37 /// Used for appending to [error]. |
43 ErrorToken errorTail; | 38 ErrorToken errorTail; |
44 | 39 |
45 /// Tokens without errors. | 40 /// Tokens without errors. |
46 Token good; | 41 Token good; |
| 42 |
47 /// Used for appending to [good]. | 43 /// Used for appending to [good]. |
48 Token goodTail; | 44 Token goodTail; |
49 | 45 |
50 /// The previous token appended to [good]. Since tokens are single linked | 46 /// The previous token appended to [good]. Since tokens are single linked |
51 /// lists, this allows us to rewrite the current token without scanning all | 47 /// lists, this allows us to rewrite the current token without scanning all |
52 /// of [good]. This is supposed to be the token immediately before | 48 /// of [good]. This is supposed to be the token immediately before |
53 /// [goodTail], that is, `beforeGoodTail.next == goodTail`. | 49 /// [goodTail], that is, `beforeGoodTail.next == goodTail`. |
54 Token beforeGoodTail; | 50 Token beforeGoodTail; |
55 | 51 |
56 recoverIdentifier(NonAsciiIdentifierToken first) { | 52 recoverIdentifier(NonAsciiIdentifierToken first) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } else { | 103 } else { |
108 goodTail = beforeGoodTail; | 104 goodTail = beforeGoodTail; |
109 } | 105 } |
110 } | 106 } |
111 if (append) { | 107 if (append) { |
112 codeUnits.addAll(next.value.codeUnits); | 108 codeUnits.addAll(next.value.codeUnits); |
113 next = next.next; | 109 next = next.next; |
114 } | 110 } |
115 String value = new String.fromCharCodes(codeUnits); | 111 String value = new String.fromCharCodes(codeUnits); |
116 return synthesizeToken(charOffset, value, Precedence.IDENTIFIER_INFO) | 112 return synthesizeToken(charOffset, value, Precedence.IDENTIFIER_INFO) |
117 ..next = next; | 113 ..next = next; |
118 } | 114 } |
119 | 115 |
120 recoverExponent() { | 116 recoverExponent() { |
121 return synthesizeToken(errorTail.charOffset, "NaN", Precedence.DOUBLE_INFO) | 117 return synthesizeToken(errorTail.charOffset, "NaN", Precedence.DOUBLE_INFO) |
122 ..next = errorTail.next; | 118 ..next = errorTail.next; |
123 } | 119 } |
124 | 120 |
125 recoverString() { | 121 recoverString() { |
126 // TODO(ahe): Improve this. | 122 // TODO(ahe): Improve this. |
127 return skipToEof(errorTail); | 123 return skipToEof(errorTail); |
128 } | 124 } |
129 | 125 |
130 recoverHexDigit() { | 126 recoverHexDigit() { |
131 return synthesizeToken(errorTail.charOffset, "-1", Precedence.INT_INFO) | 127 return synthesizeToken(errorTail.charOffset, "-1", Precedence.INT_INFO) |
132 ..next = errorTail.next; | 128 ..next = errorTail.next; |
133 } | 129 } |
134 | 130 |
135 recoverStringInterpolation() { | 131 recoverStringInterpolation() { |
136 // TODO(ahe): Improve this. | 132 // TODO(ahe): Improve this. |
137 return skipToEof(errorTail); | 133 return skipToEof(errorTail); |
138 } | 134 } |
139 | 135 |
140 recoverComment() { | 136 recoverComment() { |
141 // TODO(ahe): Improve this. | 137 // TODO(ahe): Improve this. |
142 return skipToEof(errorTail); | 138 return skipToEof(errorTail); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 235 |
240 String closeBraceFor(String openBrace) { | 236 String closeBraceFor(String openBrace) { |
241 return const { | 237 return const { |
242 '(': ')', | 238 '(': ')', |
243 '[': ']', | 239 '[': ']', |
244 '{': '}', | 240 '{': '}', |
245 '<': '>', | 241 '<': '>', |
246 r'${': '}', | 242 r'${': '}', |
247 }[openBrace]; | 243 }[openBrace]; |
248 } | 244 } |
OLD | NEW |