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 '../fasta_codes.dart' |
| 8 show |
| 9 FastaCode, |
| 10 codeAsciiControlCharacter, |
| 11 codeEncoding, |
| 12 codeExpectedHexDigit, |
| 13 codeMissingExponent, |
| 14 codeNonAsciiIdentifier, |
| 15 codeNonAsciiWhitespace, |
| 16 codeUnexpectedDollarInString, |
| 17 codeUnmatchedToken, |
| 18 codeUnterminatedComment, |
| 19 codeUnterminatedString; |
| 20 |
7 import 'token.dart' show StringToken, SymbolToken, Token; | 21 import 'token.dart' show StringToken, SymbolToken, Token; |
8 | 22 |
9 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorKind, ErrorToken; | 23 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorToken; |
10 | 24 |
11 import 'precedence.dart' as Precedence; | 25 import 'precedence.dart' as Precedence; |
12 | 26 |
13 import 'precedence.dart' show PrecedenceInfo; | 27 import 'precedence.dart' show PrecedenceInfo; |
14 | 28 |
15 /// Recover from errors in [tokens]. The original sources are provided as | 29 /// Recover from errors in [tokens]. The original sources are provided as |
16 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and | 30 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and |
17 /// must be updated if recovery is performed rewriting the original source | 31 /// must be updated if recovery is performed rewriting the original source |
18 /// code. | 32 /// code. |
19 Token defaultRecoveryStrategy( | 33 Token defaultRecoveryStrategy( |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 if (errorTail == null) { | 168 if (errorTail == null) { |
155 error = next; | 169 error = next; |
156 } else { | 170 } else { |
157 errorTail.next = next; | 171 errorTail.next = next; |
158 next.previousToken = errorTail; | 172 next.previousToken = errorTail; |
159 } | 173 } |
160 errorTail = next; | 174 errorTail = next; |
161 next = next.next; | 175 next = next.next; |
162 } while (next is ErrorToken && first.errorCode == next.errorCode); | 176 } while (next is ErrorToken && first.errorCode == next.errorCode); |
163 | 177 |
164 switch (first.errorCode) { | 178 FastaCode code = first.errorCode; |
165 case ErrorKind.Encoding: | 179 if (code == codeEncoding || |
166 case ErrorKind.NonAsciiWhitespace: | 180 code == codeNonAsciiWhitespace || |
167 case ErrorKind.AsciiControlCharacter: | 181 code == codeAsciiControlCharacter) { |
168 treatAsWhitespace = true; | 182 treatAsWhitespace = true; |
169 break; | 183 } else if (code == codeNonAsciiIdentifier) { |
170 | 184 current = recoverIdentifier(first); |
171 case ErrorKind.NonAsciiIdentifier: | 185 assert(current.next != null); |
172 current = recoverIdentifier(first); | 186 } else if (code == codeMissingExponent) { |
173 assert(current.next != null); | 187 current = recoverExponent(); |
174 break; | 188 assert(current.next != null); |
175 | 189 } else if (code == codeUnterminatedString) { |
176 case ErrorKind.MissingExponent: | 190 current = recoverString(); |
177 current = recoverExponent(); | 191 assert(current.next != null); |
178 assert(current.next != null); | 192 } else if (code == codeExpectedHexDigit) { |
179 break; | 193 current = recoverHexDigit(); |
180 | 194 assert(current.next != null); |
181 case ErrorKind.UnterminatedString: | 195 } else if (code == codeUnexpectedDollarInString) { |
182 current = recoverString(); | 196 current = recoverStringInterpolation(); |
183 assert(current.next != null); | 197 assert(current.next != null); |
184 break; | 198 } else if (code == codeUnterminatedComment) { |
185 | 199 current = recoverComment(); |
186 case ErrorKind.ExpectedHexDigit: | 200 assert(current.next != null); |
187 current = recoverHexDigit(); | 201 } else if (code == codeUnmatchedToken) { |
188 assert(current.next != null); | 202 current = recoverUnmatched(); |
189 break; | 203 assert(current.next != null); |
190 | 204 } else { |
191 case ErrorKind.UnexpectedDollarInString: | 205 treatAsWhitespace = true; |
192 current = recoverStringInterpolation(); | |
193 assert(current.next != null); | |
194 break; | |
195 | |
196 case ErrorKind.UnterminatedComment: | |
197 current = recoverComment(); | |
198 assert(current.next != null); | |
199 break; | |
200 | |
201 case ErrorKind.UnmatchedToken: | |
202 current = recoverUnmatched(); | |
203 assert(current.next != null); | |
204 break; | |
205 | |
206 case ErrorKind.UnterminatedToken: // TODO(ahe): Can this happen? | |
207 default: | |
208 treatAsWhitespace = true; | |
209 break; | |
210 } | 206 } |
211 if (treatAsWhitespace) continue; | 207 if (treatAsWhitespace) continue; |
212 } | 208 } |
213 if (goodTail == null) { | 209 if (goodTail == null) { |
214 good = current; | 210 good = current; |
215 } else { | 211 } else { |
216 goodTail.next = current; | 212 goodTail.next = current; |
217 current.previousToken = goodTail; | 213 current.previousToken = goodTail; |
218 } | 214 } |
219 beforeGoodTail = goodTail; | 215 beforeGoodTail = goodTail; |
(...skipping 27 matching lines...) Expand all Loading... |
247 | 243 |
248 String closeBraceFor(String openBrace) { | 244 String closeBraceFor(String openBrace) { |
249 return const { | 245 return const { |
250 '(': ')', | 246 '(': ')', |
251 '[': ']', | 247 '[': ']', |
252 '{': '}', | 248 '{': '}', |
253 '<': '>', | 249 '<': '>', |
254 r'${': '}', | 250 r'${': '}', |
255 }[openBrace]; | 251 }[openBrace]; |
256 } | 252 } |
OLD | NEW |