OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library analyzer.src.context.cache; | 5 library analyzer.src.context.cache; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 void setErrorState( | 406 void setErrorState( |
407 CaughtException exception, List<ResultDescriptor> descriptors) { | 407 CaughtException exception, List<ResultDescriptor> descriptors) { |
408 if (descriptors == null || descriptors.isEmpty) { | 408 if (descriptors == null || descriptors.isEmpty) { |
409 throw new ArgumentError('at least one descriptor is expected'); | 409 throw new ArgumentError('at least one descriptor is expected'); |
410 } | 410 } |
411 if (exception == null) { | 411 if (exception == null) { |
412 throw new ArgumentError('an exception is expected'); | 412 throw new ArgumentError('an exception is expected'); |
413 } | 413 } |
414 this._exception = exception; | 414 this._exception = exception; |
415 for (ResultDescriptor descriptor in descriptors) { | 415 for (ResultDescriptor descriptor in descriptors) { |
416 ResultData data = _getResultData(descriptor); | 416 _invalidate(descriptor, exception); |
417 TargetedResult thisResult = new TargetedResult(_target, descriptor); | |
418 data.invalidate(_cache, thisResult, CacheState.ERROR); | |
419 } | 417 } |
420 } | 418 } |
421 | 419 |
422 /** | 420 /** |
423 * Set the state of the result represented by the given [descriptor] to the | 421 * Set the state of the result represented by the given [descriptor] to the |
424 * given [state]. | 422 * given [state]. |
425 */ | 423 */ |
426 void setState(ResultDescriptor descriptor, CacheState state) { | 424 void setState(ResultDescriptor descriptor, CacheState state) { |
427 if (state == CacheState.ERROR) { | 425 if (state == CacheState.ERROR) { |
428 throw new ArgumentError('use setErrorState() to set the state to ERROR'); | 426 throw new ArgumentError('use setErrorState() to set the state to ERROR'); |
429 } | 427 } |
430 if (state == CacheState.VALID) { | 428 if (state == CacheState.VALID) { |
431 throw new ArgumentError('use setValue() to set the state to VALID'); | 429 throw new ArgumentError('use setValue() to set the state to VALID'); |
432 } | 430 } |
433 _validateStateChange(descriptor, state); | 431 _validateStateChange(descriptor, state); |
434 if (state == CacheState.INVALID) { | 432 if (state == CacheState.INVALID) { |
435 ResultData data = _resultMap[descriptor]; | 433 _invalidate(descriptor, null); |
436 if (data != null) { | |
437 TargetedResult thisResult = new TargetedResult(_target, descriptor); | |
438 data.invalidate(_cache, thisResult, CacheState.INVALID); | |
439 } | |
440 } else { | 434 } else { |
441 ResultData data = _getResultData(descriptor); | 435 ResultData data = _getResultData(descriptor); |
442 data.state = state; | 436 data.state = state; |
443 if (state != CacheState.IN_PROCESS) { | 437 if (state != CacheState.IN_PROCESS) { |
444 // | 438 // |
445 // If the state is in-process, we can leave the current value in the | 439 // If the state is in-process, we can leave the current value in the |
446 // cache for any 'get' methods to access. | 440 // cache for any 'get' methods to access. |
447 // | 441 // |
448 data.value = descriptor.defaultValue; | 442 data.value = descriptor.defaultValue; |
449 } | 443 } |
450 } | 444 } |
451 } | 445 } |
452 | 446 |
453 /** | 447 /** |
454 * Set the value of the result represented by the given [descriptor] to the | 448 * Set the value of the result represented by the given [descriptor] to the |
455 * given [value]. The optional [memento] may help to recompute [value] more | 449 * given [value]. The optional [memento] may help to recompute [value] more |
456 * efficiently after invalidation. | 450 * efficiently after invalidation. |
457 */ | 451 */ |
458 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ | 452 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ |
459 value, List<TargetedResult> dependedOn, Object memento) { | 453 value, List<TargetedResult> dependedOn, Object memento) { |
460 _validateStateChange(descriptor, CacheState.VALID); | 454 _validateStateChange(descriptor, CacheState.VALID); |
| 455 _invalidate(descriptor, null); |
461 ResultData data = _getResultData(descriptor); | 456 ResultData data = _getResultData(descriptor); |
462 { | 457 { |
463 TargetedResult thisResult = new TargetedResult(_target, descriptor); | 458 TargetedResult thisResult = new TargetedResult(_target, descriptor); |
464 data.invalidate(_cache, thisResult, CacheState.INVALID); | |
465 data.setDependedOnResults(_cache, thisResult, dependedOn); | 459 data.setDependedOnResults(_cache, thisResult, dependedOn); |
466 } | 460 } |
467 data.state = CacheState.VALID; | 461 data.state = CacheState.VALID; |
468 data.value = value == null ? descriptor.defaultValue : value; | 462 data.value = value == null ? descriptor.defaultValue : value; |
469 data.memento = memento; | 463 data.memento = memento; |
470 } | 464 } |
471 | 465 |
472 @override | 466 @override |
473 String toString() { | 467 String toString() { |
474 StringBuffer buffer = new StringBuffer(); | 468 StringBuffer buffer = new StringBuffer(); |
475 _writeOn(buffer); | 469 _writeOn(buffer); |
476 return buffer.toString(); | 470 return buffer.toString(); |
477 } | 471 } |
478 | 472 |
479 /** | 473 /** |
480 * Return the value of the flag with the given [index]. | 474 * Return the value of the flag with the given [index]. |
481 */ | 475 */ |
482 bool _getFlag(int index) => BooleanArray.get(_flags, index); | 476 bool _getFlag(int index) => BooleanArray.get(_flags, index); |
483 | 477 |
484 /** | 478 /** |
485 * Look up the [ResultData] of [descriptor], or add a new one if it isn't | 479 * Look up the [ResultData] of [descriptor], or add a new one if it isn't |
486 * there. | 480 * there. |
487 */ | 481 */ |
488 ResultData _getResultData(ResultDescriptor descriptor) { | 482 ResultData _getResultData(ResultDescriptor descriptor) { |
489 return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); | 483 return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); |
490 } | 484 } |
491 | 485 |
492 /** | 486 /** |
| 487 * Invalidate the result represented by the given [descriptor]. |
| 488 * Propagate invalidation to other results that depend on it. |
| 489 */ |
| 490 void _invalidate(ResultDescriptor descriptor, CaughtException exception) { |
| 491 ResultData data = _getResultData(descriptor); |
| 492 // Invalidate this result. |
| 493 if (exception == null) { |
| 494 data.state = CacheState.INVALID; |
| 495 } else { |
| 496 data.state = CacheState.ERROR; |
| 497 _exception = exception; |
| 498 } |
| 499 data.value = descriptor.defaultValue; |
| 500 // Stop depending on other results. |
| 501 TargetedResult thisResult = new TargetedResult(_target, descriptor); |
| 502 List<TargetedResult> dependedOnResults = data.dependedOnResults; |
| 503 data.dependedOnResults = <TargetedResult>[]; |
| 504 dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| 505 ResultData data = _cache._getDataFor(dependedOnResult); |
| 506 data.removeDependentResult(thisResult); |
| 507 }); |
| 508 // Invalidate results that depend on this result. |
| 509 List<TargetedResult> dependentResults = data.dependentResults; |
| 510 data.dependentResults = <TargetedResult>[]; |
| 511 dependentResults.forEach((TargetedResult dependentResult) { |
| 512 CacheEntry entry = _cache.get(dependentResult.target); |
| 513 entry._invalidate(dependentResult.result, exception); |
| 514 }); |
| 515 } |
| 516 |
| 517 /** |
493 * Set the value of the flag with the given [index] to the given [value]. | 518 * Set the value of the flag with the given [index] to the given [value]. |
494 */ | 519 */ |
495 void _setFlag(int index, bool value) { | 520 void _setFlag(int index, bool value) { |
496 _flags = BooleanArray.set(_flags, index, value); | 521 _flags = BooleanArray.set(_flags, index, value); |
497 } | 522 } |
498 | 523 |
499 /** | 524 /** |
500 * If the state of the value described by the given [descriptor] is changing | 525 * If the state of the value described by the given [descriptor] is changing |
501 * from ERROR to anything else, capture the information. This is an attempt to | 526 * from ERROR to anything else, capture the information. This is an attempt to |
502 * discover the underlying cause of a long-standing bug. | 527 * discover the underlying cause of a long-standing bug. |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 } | 884 } |
860 | 885 |
861 /** | 886 /** |
862 * Add the given [result] to the list of dependent results. | 887 * Add the given [result] to the list of dependent results. |
863 */ | 888 */ |
864 void addDependentResult(TargetedResult result) { | 889 void addDependentResult(TargetedResult result) { |
865 dependentResults.add(result); | 890 dependentResults.add(result); |
866 } | 891 } |
867 | 892 |
868 /** | 893 /** |
869 * Invalidate this [ResultData] that corresponds to [thisResult] and | |
870 * propagate invalidation to the results that depend on this one. | |
871 */ | |
872 void invalidate( | |
873 AnalysisCache cache, TargetedResult thisResult, CacheState newState) { | |
874 // Invalidate this result. | |
875 state = newState; | |
876 value = descriptor.defaultValue; | |
877 // Stop depending on other results. | |
878 List<TargetedResult> dependedOnResults = this.dependedOnResults; | |
879 this.dependedOnResults = <TargetedResult>[]; | |
880 dependedOnResults.forEach((TargetedResult dependedOnResult) { | |
881 ResultData data = cache._getDataFor(dependedOnResult); | |
882 data.removeDependentResult(thisResult); | |
883 }); | |
884 // Invalidate results that depend on this result. | |
885 List<TargetedResult> dependentResults = this.dependentResults; | |
886 this.dependentResults = <TargetedResult>[]; | |
887 dependentResults.forEach((TargetedResult dependentResult) { | |
888 ResultData data = cache._getDataFor(dependentResult); | |
889 data.invalidate(cache, dependentResult, newState); | |
890 }); | |
891 } | |
892 | |
893 /** | |
894 * Remove the given [result] from the list of dependent results. | 894 * Remove the given [result] from the list of dependent results. |
895 */ | 895 */ |
896 void removeDependentResult(TargetedResult result) { | 896 void removeDependentResult(TargetedResult result) { |
897 dependentResults.remove(result); | 897 dependentResults.remove(result); |
898 } | 898 } |
899 | 899 |
900 /** | 900 /** |
901 * Set the [dependedOn] on which this result depends. | 901 * Set the [dependedOn] on which this result depends. |
902 */ | 902 */ |
903 void setDependedOnResults(AnalysisCache cache, TargetedResult thisResult, | 903 void setDependedOnResults(AnalysisCache cache, TargetedResult thisResult, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 * structures in the cache, using the [retentionPolicy] to determine which | 983 * structures in the cache, using the [retentionPolicy] to determine which |
984 * AST structures to flush. | 984 * AST structures to flush. |
985 */ | 985 */ |
986 UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize, | 986 UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize, |
987 CacheRetentionPolicy retentionPolicy) | 987 CacheRetentionPolicy retentionPolicy) |
988 : super(context, maxCacheSize, retentionPolicy); | 988 : super(context, maxCacheSize, retentionPolicy); |
989 | 989 |
990 @override | 990 @override |
991 bool contains(AnalysisTarget target) => true; | 991 bool contains(AnalysisTarget target) => true; |
992 } | 992 } |
OLD | NEW |