| 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:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 this._exception = exception; | 405 this._exception = exception; |
| 406 for (ResultDescriptor descriptor in descriptors) { | 406 for (ResultDescriptor descriptor in descriptors) { |
| 407 _setErrorState(descriptor, exception); | 407 _setErrorState(descriptor, exception); |
| 408 } | 408 } |
| 409 } | 409 } |
| 410 | 410 |
| 411 /** | 411 /** |
| 412 * Set the state of the result represented by the given [descriptor] to the | 412 * Set the state of the result represented by the given [descriptor] to the |
| 413 * given [state]. | 413 * given [state]. |
| 414 */ | 414 */ |
| 415 void setState(ResultDescriptor descriptor, CacheState state) { | 415 void setState(ResultDescriptor descriptor, CacheState state, {Delta delta}) { |
| 416 if (state == CacheState.ERROR) { | 416 if (state == CacheState.ERROR) { |
| 417 throw new ArgumentError('use setErrorState() to set the state to ERROR'); | 417 throw new ArgumentError('use setErrorState() to set the state to ERROR'); |
| 418 } | 418 } |
| 419 if (state == CacheState.VALID) { | 419 if (state == CacheState.VALID) { |
| 420 throw new ArgumentError('use setValue() to set the state to VALID'); | 420 throw new ArgumentError('use setValue() to set the state to VALID'); |
| 421 } | 421 } |
| 422 _validateStateChange(descriptor, state); | 422 _validateStateChange(descriptor, state); |
| 423 if (state == CacheState.INVALID) { | 423 if (state == CacheState.INVALID) { |
| 424 ResultData data = _resultMap[descriptor]; | 424 ResultData data = _resultMap[descriptor]; |
| 425 if (data != null) { | 425 if (data != null) { |
| 426 _invalidate(descriptor); | 426 _invalidate(descriptor, delta); |
| 427 } | 427 } |
| 428 } else { | 428 } else { |
| 429 ResultData data = getResultData(descriptor); | 429 ResultData data = getResultData(descriptor); |
| 430 data.state = state; | 430 data.state = state; |
| 431 if (state != CacheState.IN_PROCESS) { | 431 if (state != CacheState.IN_PROCESS) { |
| 432 // | 432 // |
| 433 // If the state is in-process, we can leave the current value in the | 433 // If the state is in-process, we can leave the current value in the |
| 434 // cache for any 'get' methods to access. | 434 // cache for any 'get' methods to access. |
| 435 // | 435 // |
| 436 data.value = descriptor.defaultValue; | 436 data.value = descriptor.defaultValue; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 464 data.value = value == null ? descriptor.defaultValue : value; | 464 data.value = value == null ? descriptor.defaultValue : value; |
| 465 } | 465 } |
| 466 | 466 |
| 467 /** | 467 /** |
| 468 * Set the value of the result represented by the given [descriptor] to the | 468 * Set the value of the result represented by the given [descriptor] to the |
| 469 * given [value], keep its dependency, invalidate all the dependent result. | 469 * given [value], keep its dependency, invalidate all the dependent result. |
| 470 */ | 470 */ |
| 471 void setValueIncremental(ResultDescriptor descriptor, dynamic value) { | 471 void setValueIncremental(ResultDescriptor descriptor, dynamic value) { |
| 472 ResultData data = getResultData(descriptor); | 472 ResultData data = getResultData(descriptor); |
| 473 List<TargetedResult> dependedOn = data.dependedOnResults; | 473 List<TargetedResult> dependedOn = data.dependedOnResults; |
| 474 _invalidate(descriptor); | 474 _invalidate(descriptor, null); |
| 475 setValue(descriptor, value, dependedOn); | 475 setValue(descriptor, value, dependedOn); |
| 476 } | 476 } |
| 477 | 477 |
| 478 @override | 478 @override |
| 479 String toString() { | 479 String toString() { |
| 480 StringBuffer buffer = new StringBuffer(); | 480 StringBuffer buffer = new StringBuffer(); |
| 481 _writeOn(buffer); | 481 _writeOn(buffer); |
| 482 return buffer.toString(); | 482 return buffer.toString(); |
| 483 } | 483 } |
| 484 | 484 |
| 485 /** | 485 /** |
| 486 * Return the value of the flag with the given [index]. | 486 * Return the value of the flag with the given [index]. |
| 487 */ | 487 */ |
| 488 bool _getFlag(int index) => BooleanArray.get(_flags, index); | 488 bool _getFlag(int index) => BooleanArray.get(_flags, index); |
| 489 | 489 |
| 490 /** | 490 /** |
| 491 * Invalidate the result represented by the given [descriptor] and propagate | 491 * Invalidate the result represented by the given [descriptor] and propagate |
| 492 * invalidation to other results that depend on it. | 492 * invalidation to other results that depend on it. |
| 493 */ | 493 */ |
| 494 void _invalidate(ResultDescriptor descriptor) { | 494 void _invalidate(ResultDescriptor descriptor, Delta delta) { |
| 495 if (delta != null && |
| 496 !delta.affects(_partition.context, target, descriptor)) { |
| 497 // print('not-invalidate $descriptor for $target'); |
| 498 return; |
| 499 } |
| 495 // print('invalidate $descriptor for $target'); | 500 // print('invalidate $descriptor for $target'); |
| 496 ResultData thisData = _resultMap.remove(descriptor); | 501 ResultData thisData = _resultMap.remove(descriptor); |
| 497 if (thisData == null) { | 502 if (thisData == null) { |
| 498 return; | 503 return; |
| 499 } | 504 } |
| 500 // Stop depending on other results. | 505 // Stop depending on other results. |
| 501 TargetedResult thisResult = new TargetedResult(target, descriptor); | 506 TargetedResult thisResult = new TargetedResult(target, descriptor); |
| 502 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { | 507 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| 503 ResultData data = _partition._getDataFor(dependedOnResult, orNull: true); | 508 ResultData data = _partition._getDataFor(dependedOnResult, orNull: true); |
| 504 if (data != null) { | 509 if (data != null) { |
| 505 data.dependentResults.remove(thisResult); | 510 data.dependentResults.remove(thisResult); |
| 506 } | 511 } |
| 507 }); | 512 }); |
| 508 // Invalidate results that depend on this result. | 513 // Invalidate results that depend on this result. |
| 509 Set<TargetedResult> dependentResults = thisData.dependentResults; | 514 Set<TargetedResult> dependentResults = thisData.dependentResults; |
| 510 thisData.dependentResults = new Set<TargetedResult>(); | 515 thisData.dependentResults = new Set<TargetedResult>(); |
| 511 dependentResults.forEach((TargetedResult dependentResult) { | 516 dependentResults.forEach((TargetedResult dependentResult) { |
| 512 CacheEntry entry = _partition.get(dependentResult.target); | 517 CacheEntry entry = _partition.get(dependentResult.target); |
| 513 if (entry != null) { | 518 if (entry != null) { |
| 514 entry._invalidate(dependentResult.result); | 519 entry._invalidate(dependentResult.result, delta); |
| 515 } | 520 } |
| 516 }); | 521 }); |
| 517 // If empty, remove the entry altogether. | 522 // If empty, remove the entry altogether. |
| 518 if (_resultMap.isEmpty) { | 523 if (_resultMap.isEmpty) { |
| 519 _partition._targetMap.remove(target); | 524 _partition._targetMap.remove(target); |
| 520 _partition._removeIfSource(target); | 525 _partition._removeIfSource(target); |
| 521 } | 526 } |
| 522 // Notify controller. | 527 // Notify controller. |
| 523 _partition._onResultInvalidated | 528 _partition._onResultInvalidated |
| 524 .add(new InvalidatedResult(this, descriptor)); | 529 .add(new InvalidatedResult(this, descriptor)); |
| 525 } | 530 } |
| 526 | 531 |
| 527 /** | 532 /** |
| 528 * Invalidates all the results of this entry, with propagation. | 533 * Invalidates all the results of this entry, with propagation. |
| 529 */ | 534 */ |
| 530 void _invalidateAll() { | 535 void _invalidateAll() { |
| 531 List<ResultDescriptor> results = _resultMap.keys.toList(); | 536 List<ResultDescriptor> results = _resultMap.keys.toList(); |
| 532 for (ResultDescriptor result in results) { | 537 for (ResultDescriptor result in results) { |
| 533 _invalidate(result); | 538 _invalidate(result, null); |
| 534 } | 539 } |
| 535 } | 540 } |
| 536 | 541 |
| 537 /** | 542 /** |
| 538 * Set the [dependedOn] on which this result depends. | 543 * Set the [dependedOn] on which this result depends. |
| 539 */ | 544 */ |
| 540 void _setDependedOnResults(ResultData thisData, TargetedResult thisResult, | 545 void _setDependedOnResults(ResultData thisData, TargetedResult thisResult, |
| 541 List<TargetedResult> dependedOn) { | 546 List<TargetedResult> dependedOn) { |
| 542 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { | 547 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| 543 ResultData data = _partition._getDataFor(dependedOnResult, orNull: true); | 548 ResultData data = _partition._getDataFor(dependedOnResult, orNull: true); |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 if (sources.isEmpty) { | 958 if (sources.isEmpty) { |
| 954 _pathToSources.remove(fullName); | 959 _pathToSources.remove(fullName); |
| 955 } | 960 } |
| 956 } | 961 } |
| 957 } | 962 } |
| 958 } | 963 } |
| 959 } | 964 } |
| 960 } | 965 } |
| 961 | 966 |
| 962 /** | 967 /** |
| 968 * The description for a change. |
| 969 */ |
| 970 class Delta { |
| 971 final Source source; |
| 972 |
| 973 Delta(this.source); |
| 974 |
| 975 /** |
| 976 * Check whether this delta affects the result described by the given |
| 977 * [descriptor] and [target]. |
| 978 */ |
| 979 bool affects(InternalAnalysisContext context, AnalysisTarget target, |
| 980 ResultDescriptor descriptor) { |
| 981 return true; |
| 982 } |
| 983 } |
| 984 |
| 985 /** |
| 963 * [InvalidatedResult] describes an invalidated result. | 986 * [InvalidatedResult] describes an invalidated result. |
| 964 */ | 987 */ |
| 965 class InvalidatedResult { | 988 class InvalidatedResult { |
| 966 /** | 989 /** |
| 967 * The target in which the result was invalidated. | 990 * The target in which the result was invalidated. |
| 968 */ | 991 */ |
| 969 final CacheEntry entry; | 992 final CacheEntry entry; |
| 970 | 993 |
| 971 /** | 994 /** |
| 972 * The descriptor of the result which was invalidated. | 995 * The descriptor of the result which was invalidated. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 void resultAccessed(TargetedResult result) {} | 1138 void resultAccessed(TargetedResult result) {} |
| 1116 | 1139 |
| 1117 @override | 1140 @override |
| 1118 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { | 1141 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { |
| 1119 return TargetedResult.EMPTY_LIST; | 1142 return TargetedResult.EMPTY_LIST; |
| 1120 } | 1143 } |
| 1121 | 1144 |
| 1122 @override | 1145 @override |
| 1123 void targetRemoved(AnalysisTarget target) {} | 1146 void targetRemoved(AnalysisTarget target) {} |
| 1124 } | 1147 } |
| OLD | NEW |