Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: pkg/analyzer/lib/src/generated/scanner.dart

Issue 746503002: Move incremental scanner to separate file (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add new files Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information.
7
8 library engine.scanner; 5 library engine.scanner;
9 6
10 import "dart:math" as math;
11 import 'dart:collection'; 7 import 'dart:collection';
12 8
13 import 'error.dart'; 9 import 'error.dart';
14 import 'instrumentation.dart'; 10 import 'instrumentation.dart';
15 import 'java_engine.dart'; 11 import 'java_engine.dart';
16 import 'source.dart'; 12 import 'source.dart';
17 import 'utilities_collection.dart' show TokenMap;
18 13
19 /** 14 /**
20 * A `BeginToken` is the opening half of a grouping pair of tokens. This is used 15 * A `BeginToken` is the opening half of a grouping pair of tokens. This is used
21 * for curly brackets ('{'), parentheses ('('), and square brackets ('['). 16 * for curly brackets ('{'), parentheses ('('), and square brackets ('[').
22 */ 17 */
23 class BeginToken extends Token { 18 class BeginToken extends Token {
24 /** 19 /**
25 * The token that corresponds to this token. 20 * The token that corresponds to this token.
26 */ 21 */
27 Token endToken; 22 Token endToken;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 String getString(int start, int endDelta); 217 String getString(int start, int endDelta);
223 218
224 /** 219 /**
225 * Return the character at the current position without changing the current 220 * Return the character at the current position without changing the current
226 * position. 221 * position.
227 */ 222 */
228 int peek(); 223 int peek();
229 } 224 }
230 225
231 /** 226 /**
232 * Instances of the class `IncrementalScanner` implement a scanner that scans a subset of a
233 * string and inserts the resulting tokens into the middle of an existing token stream.
234 */
235 class IncrementalScanner extends Scanner {
236 /**
237 * The reader used to access the characters in the source.
238 */
239 CharacterReader _reader;
240
241 /**
242 * A map from tokens that were copied to the copies of the tokens.
243 */
244 TokenMap _tokenMap = new TokenMap();
245
246 /**
247 * The token in the new token stream immediately to the left of the range of t okens that were
248 * inserted, or the token immediately to the left of the modified region if th ere were no new
249 * tokens.
250 */
251 Token _leftToken;
252
253 /**
254 * The token in the new token stream immediately to the right of the range of tokens that were
255 * inserted, or the token immediately to the right of the modified region if t here were no new
256 * tokens.
257 */
258 Token _rightToken;
259
260 /**
261 * A flag indicating whether there were any tokens changed as a result of the modification.
262 */
263 bool _hasNonWhitespaceChange = false;
264
265 /**
266 * Initialize a newly created scanner.
267 *
268 * @param source the source being scanned
269 * @param reader the character reader used to read the characters in the sourc e
270 * @param errorListener the error listener that will be informed of any errors that are found
271 */
272 IncrementalScanner(Source source, CharacterReader reader,
273 AnalysisErrorListener errorListener)
274 : super(source, reader, errorListener) {
275 this._reader = reader;
276 }
277
278 /**
279 * Return `true` if there were any tokens either added or removed (or both) as a result of
280 * the modification.
281 *
282 * @return `true` if there were any tokens changed as a result of the modifica tion
283 */
284 bool get hasNonWhitespaceChange => _hasNonWhitespaceChange;
285
286 /**
287 * Return the token in the new token stream immediately to the left of the ran ge of tokens that
288 * were inserted, or the token immediately to the left of the modified region if there were no new
289 * tokens.
290 *
291 * @return the token to the left of the inserted tokens
292 */
293 Token get leftToken => _leftToken;
294
295 /**
296 * Return the token in the new token stream immediately to the right of the ra nge of tokens that
297 * were inserted, or the token immediately to the right of the modified region if there were no
298 * new tokens.
299 *
300 * @return the token to the right of the inserted tokens
301 */
302 Token get rightToken => _rightToken;
303
304 /**
305 * Return a map from tokens that were copied to the copies of the tokens.
306 *
307 * @return a map from tokens that were copied to the copies of the tokens
308 */
309 TokenMap get tokenMap => _tokenMap;
310
311 /**
312 * Given the stream of tokens scanned from the original source, the modified s ource (the result of
313 * replacing one contiguous range of characters with another string of charact ers), and a
314 * specification of the modification that was made, return a stream of tokens scanned from the
315 * modified source. The original stream of tokens will not be modified.
316 *
317 * @param originalStream the stream of tokens scanned from the original source
318 * @param index the index of the first character in both the original and modi fied source that was
319 * affected by the modification
320 * @param removedLength the number of characters removed from the original sou rce
321 * @param insertedLength the number of characters added to the modified source
322 */
323 Token rescan(Token originalStream, int index, int removedLength,
324 int insertedLength) {
325 //
326 // Copy all of the tokens in the originalStream whose end is less than the
327 // replacement start. (If the replacement start is equal to the end of an
328 // existing token, then it means that the existing token might have been
329 // modified, so we need to rescan it.)
330 //
331 while (originalStream.type != TokenType.EOF && originalStream.end < index) {
332 originalStream = _copyAndAdvance(originalStream, 0);
333 }
334 Token oldFirst = originalStream;
335 Token oldLeftToken = originalStream.previous;
336 _leftToken = tail;
337 //
338 // Skip tokens in the original stream until we find a token whose offset is
339 // greater than the end of the removed region. (If the end of the removed
340 // region is equal to the beginning of an existing token, then it means that
341 // the existing token might have been modified, so we need to rescan it.)
342 //
343 int removedEnd = index + (removedLength == 0 ? 0 : removedLength - 1);
344 while (originalStream.type != TokenType.EOF &&
345 originalStream.offset <= removedEnd) {
346 originalStream = originalStream.next;
347 }
348 Token oldLast;
349 Token oldRightToken;
350 if (originalStream.type != TokenType.EOF &&
351 removedEnd + 1 == originalStream.offset) {
352 oldLast = originalStream;
353 originalStream = originalStream.next;
354 oldRightToken = originalStream;
355 } else {
356 oldLast = originalStream.previous;
357 oldRightToken = originalStream;
358 }
359 //
360 // Compute the delta between the character index of characters after the
361 // modified region in the original source and the index of the corresponding
362 // character in the modified source.
363 //
364 int delta = insertedLength - removedLength;
365 //
366 // Compute the range of characters that are known to need to be rescanned.
367 // If the index is within an existing token, then we need to start at the
368 // beginning of the token.
369 //
370 int scanStart = math.min(oldFirst.offset, index);
371 int oldEnd = oldLast.end + delta - 1;
372 int newEnd = index + insertedLength - 1;
373 int scanEnd = math.max(newEnd, oldEnd);
374 //
375 // Starting at the start of the scan region, scan tokens from the
376 // modifiedSource until the end of the just scanned token is greater than or
377 // equal to end of the scan region in the modified source. Include trailing
378 // characters of any token that was split as a result of inserted text,
379 // as in "ab" --> "a.b".
380 //
381 _reader.offset = scanStart - 1;
382 int next = _reader.advance();
383 while (next != -1 && _reader.offset <= scanEnd) {
384 next = bigSwitch(next);
385 }
386 //
387 // Copy the remaining tokens in the original stream, but apply the delta to
388 // the token's offset.
389 //
390 if (originalStream.type == TokenType.EOF) {
391 _copyAndAdvance(originalStream, delta);
392 _rightToken = tail;
393 _rightToken.setNextWithoutSettingPrevious(_rightToken);
394 } else {
395 originalStream = _copyAndAdvance(originalStream, delta);
396 _rightToken = tail;
397 while (originalStream.type != TokenType.EOF) {
398 originalStream = _copyAndAdvance(originalStream, delta);
399 }
400 Token eof = _copyAndAdvance(originalStream, delta);
401 eof.setNextWithoutSettingPrevious(eof);
402 }
403 //
404 // If the index is immediately after an existing token and the inserted
405 // characters did not change that original token, then adjust the leftToken
406 // to be the next token. For example, in "a; c;" --> "a;b c;", the leftToken
407 // was ";", but this code advances it to "b" since "b" is the first new
408 // token.
409 //
410 Token newFirst = _leftToken.next;
411 while (!identical(newFirst, _rightToken) &&
412 !identical(oldFirst, oldRightToken) &&
413 newFirst.type != TokenType.EOF &&
414 _equalTokens(oldFirst, newFirst)) {
415 _tokenMap.put(oldFirst, newFirst);
416 oldLeftToken = oldFirst;
417 oldFirst = oldFirst.next;
418 _leftToken = newFirst;
419 newFirst = newFirst.next;
420 }
421 Token newLast = _rightToken.previous;
422 while (!identical(newLast, _leftToken) &&
423 !identical(oldLast, oldLeftToken) &&
424 newLast.type != TokenType.EOF &&
425 _equalTokens(oldLast, newLast)) {
426 _tokenMap.put(oldLast, newLast);
427 oldRightToken = oldLast;
428 oldLast = oldLast.previous;
429 _rightToken = newLast;
430 newLast = newLast.previous;
431 }
432 _hasNonWhitespaceChange = !identical(_leftToken.next, _rightToken) ||
433 !identical(oldLeftToken.next, oldRightToken);
434 //
435 // TODO(brianwilkerson) Begin tokens are not getting associated with the
436 // corresponding end tokens (because the end tokens have not been copied
437 // when we're copying the begin tokens). This could have implications for
438 // parsing.
439 // TODO(brianwilkerson) Update the lineInfo.
440 //
441 return firstToken;
442 }
443
444 Token _copyAndAdvance(Token originalToken, int delta) {
445 Token copiedToken = originalToken.copy();
446 _tokenMap.put(originalToken, copiedToken);
447 copiedToken.offset += delta;
448 appendToken(copiedToken);
449 Token originalComment = originalToken.precedingComments;
450 Token copiedComment = originalToken.precedingComments;
451 while (originalComment != null) {
452 _tokenMap.put(originalComment, copiedComment);
453 originalComment = originalComment.next;
454 copiedComment = copiedComment.next;
455 }
456 return originalToken.next;
457 }
458
459 /**
460 * Return `true` if the two tokens are equal to each other. For the purposes o f the
461 * incremental scanner, two tokens are equal if they have the same type and le xeme.
462 *
463 * @param oldToken the token from the old stream that is being compared
464 * @param newToken the token from the new stream that is being compared
465 * @return `true` if the two tokens are equal to each other
466 */
467 bool _equalTokens(Token oldToken, Token newToken) =>
468 oldToken.type == newToken.type &&
469 oldToken.length == newToken.length &&
470 oldToken.lexeme == newToken.lexeme;
471 }
472
473 /**
474 * The enumeration `Keyword` defines the keywords in the Dart programming 227 * The enumeration `Keyword` defines the keywords in the Dart programming
475 * language. 228 * language.
476 */ 229 */
477 class Keyword { 230 class Keyword {
478 static const Keyword ASSERT = const Keyword('ASSERT', "assert"); 231 static const Keyword ASSERT = const Keyword('ASSERT', "assert");
479 232
480 static const Keyword BREAK = const Keyword('BREAK', "break"); 233 static const Keyword BREAK = const Keyword('BREAK', "break");
481 234
482 static const Keyword CASE = const Keyword('CASE', "case"); 235 static const Keyword CASE = const Keyword('CASE', "case");
483 236
(...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 */ 2549 */
2797 TokenWithComment(TokenType type, int offset, this._precedingComment) 2550 TokenWithComment(TokenType type, int offset, this._precedingComment)
2798 : super(type, offset); 2551 : super(type, offset);
2799 2552
2800 @override 2553 @override
2801 Token get precedingComments => _precedingComment; 2554 Token get precedingComments => _precedingComment;
2802 2555
2803 @override 2556 @override
2804 Token copy() => new TokenWithComment(type, offset, _precedingComment); 2557 Token copy() => new TokenWithComment(type, offset, _precedingComment);
2805 } 2558 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_scanner.dart ('k') | pkg/analyzer/test/generated/incremental_scanner_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698