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 StringToken, Token; | 7 import 'token.dart' show StringToken, SymbolToken, Token; |
8 | 8 |
9 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorKind, ErrorToken; | 9 import 'error_token.dart' show NonAsciiIdentifierToken, ErrorKind, ErrorToken; |
10 | 10 |
11 import 'precedence.dart' as Precedence; | 11 import 'precedence.dart' as Precedence; |
12 | 12 |
13 import 'precedence.dart' show PrecedenceInfo; | 13 import 'precedence.dart' show PrecedenceInfo; |
14 | 14 |
15 /// Recover from errors in [tokens]. The original sources are provided as | 15 /// Recover from errors in [tokens]. The original sources are provided as |
16 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and | 16 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and |
17 /// must be updated if recovery is performed rewriting the original source | 17 /// must be updated if recovery is performed rewriting the original source |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 if (current is ErrorToken) { | 148 if (current is ErrorToken) { |
149 ErrorToken first = current; | 149 ErrorToken first = current; |
150 Token next = current; | 150 Token next = current; |
151 bool treatAsWhitespace = false; | 151 bool treatAsWhitespace = false; |
152 do { | 152 do { |
153 current = next; | 153 current = next; |
154 if (errorTail == null) { | 154 if (errorTail == null) { |
155 error = next; | 155 error = next; |
156 } else { | 156 } else { |
157 errorTail.next = next; | 157 errorTail.next = next; |
| 158 next.previousToken = errorTail; |
158 } | 159 } |
159 errorTail = next; | 160 errorTail = next; |
160 next = next.next; | 161 next = next.next; |
161 } while (next is ErrorToken && first.errorCode == next.errorCode); | 162 } while (next is ErrorToken && first.errorCode == next.errorCode); |
162 | 163 |
163 switch (first.errorCode) { | 164 switch (first.errorCode) { |
164 case ErrorKind.Encoding: | 165 case ErrorKind.Encoding: |
165 case ErrorKind.NonAsciiWhitespace: | 166 case ErrorKind.NonAsciiWhitespace: |
166 case ErrorKind.AsciiControlCharacter: | 167 case ErrorKind.AsciiControlCharacter: |
167 treatAsWhitespace = true; | 168 treatAsWhitespace = true; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 default: | 207 default: |
207 treatAsWhitespace = true; | 208 treatAsWhitespace = true; |
208 break; | 209 break; |
209 } | 210 } |
210 if (treatAsWhitespace) continue; | 211 if (treatAsWhitespace) continue; |
211 } | 212 } |
212 if (goodTail == null) { | 213 if (goodTail == null) { |
213 good = current; | 214 good = current; |
214 } else { | 215 } else { |
215 goodTail.next = current; | 216 goodTail.next = current; |
| 217 current.previousToken = goodTail; |
216 } | 218 } |
217 beforeGoodTail = goodTail; | 219 beforeGoodTail = goodTail; |
218 goodTail = current; | 220 goodTail = current; |
219 } | 221 } |
220 | 222 |
221 errorTail.next = good; | 223 error.previousToken = new SymbolToken.eof(-1)..next = error; |
| 224 Token tail; |
| 225 if (good != null) { |
| 226 errorTail.next = good; |
| 227 good.previousToken = errorTail; |
| 228 tail = goodTail; |
| 229 } else { |
| 230 tail = errorTail; |
| 231 } |
| 232 if (!tail.isEof) |
| 233 tail.next = new SymbolToken.eof(tail.end)..previousToken = tail; |
222 return error; | 234 return error; |
223 } | 235 } |
224 | 236 |
225 Token synthesizeToken(int charOffset, String value, PrecedenceInfo info) { | 237 Token synthesizeToken(int charOffset, String value, PrecedenceInfo info) { |
226 return new StringToken.fromString(info, value, charOffset); | 238 return new StringToken.fromString(info, value, charOffset); |
227 } | 239 } |
228 | 240 |
229 Token skipToEof(Token token) { | 241 Token skipToEof(Token token) { |
230 while (!token.isEof) { | 242 while (!token.isEof) { |
231 token = token.next; | 243 token = token.next; |
232 } | 244 } |
233 return token; | 245 return token; |
234 } | 246 } |
235 | 247 |
236 String closeBraceFor(String openBrace) { | 248 String closeBraceFor(String openBrace) { |
237 return const { | 249 return const { |
238 '(': ')', | 250 '(': ')', |
239 '[': ']', | 251 '[': ']', |
240 '{': '}', | 252 '{': '}', |
241 '<': '>', | 253 '<': '>', |
242 r'${': '}', | 254 r'${': '}', |
243 }[openBrace]; | 255 }[openBrace]; |
244 } | 256 } |
OLD | NEW |