| 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 |