Chromium Code Reviews| 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 /** | 228 /** |
| 229 * The most recent time at which the state of the target matched the state | 229 * The most recent time at which the state of the target matched the state |
| 230 * represented by this entry. | 230 * represented by this entry. |
| 231 */ | 231 */ |
| 232 int modificationTime = 0; | 232 int modificationTime = 0; |
| 233 | 233 |
| 234 /** | 234 /** |
| 235 * The exception that caused one or more values to have a state of | 235 * The exception that caused one or more values to have a state of |
| 236 * [CacheState.ERROR]. | 236 * [CacheState.ERROR]. |
| 237 */ | 237 */ |
| 238 CaughtException exception; | 238 CaughtException _exception; |
| 239 | 239 |
| 240 /** | 240 /** |
| 241 * A bit-encoding of boolean flags associated with this entry's target. | 241 * A bit-encoding of boolean flags associated with this entry's target. |
| 242 */ | 242 */ |
| 243 int _flags = 0; | 243 int _flags = 0; |
| 244 | 244 |
| 245 /** | 245 /** |
| 246 * A table mapping result descriptors to the cached values of those results. | 246 * A table mapping result descriptors to the cached values of those results. |
| 247 */ | 247 */ |
| 248 Map<ResultDescriptor, ResultData> _resultMap = | 248 Map<ResultDescriptor, ResultData> _resultMap = |
| 249 new HashMap<ResultDescriptor, ResultData>(); | 249 new HashMap<ResultDescriptor, ResultData>(); |
| 250 | 250 |
| 251 /** | 251 /** |
| 252 * The exception that caused one or more values to have a state of | |
| 253 * [CacheState.ERROR]. | |
| 254 */ | |
| 255 CaughtException get exception => _exception; | |
| 256 | |
| 257 /** | |
| 252 * Return `true` if the source was explicitly added to the context or `false` | 258 * Return `true` if the source was explicitly added to the context or `false` |
| 253 * if the source was implicitly added because it was referenced by another | 259 * if the source was implicitly added because it was referenced by another |
| 254 * source. | 260 * source. |
| 255 */ | 261 */ |
| 256 bool get explicitlyAdded => _getFlag(_EXPLICITLY_ADDED_FLAG); | 262 bool get explicitlyAdded => _getFlag(_EXPLICITLY_ADDED_FLAG); |
| 257 | 263 |
| 258 /** | 264 /** |
| 259 * Set whether the source was explicitly added to the context to match the | 265 * Set whether the source was explicitly added to the context to match the |
| 260 * [explicitlyAdded] flag. | 266 * [explicitlyAdded] flag. |
| 261 */ | 267 */ |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 273 return true; | 279 return true; |
| 274 } | 280 } |
| 275 } | 281 } |
| 276 return false; | 282 return false; |
| 277 } | 283 } |
| 278 | 284 |
| 279 /** | 285 /** |
| 280 * Fix the state of the [exception] to match the current state of the entry. | 286 * Fix the state of the [exception] to match the current state of the entry. |
| 281 */ | 287 */ |
| 282 void fixExceptionState() { | 288 void fixExceptionState() { |
| 283 if (hasErrorState()) { | 289 if (!hasErrorState()) { |
| 284 if (exception == null) { | 290 _exception = null; |
| 285 // | |
| 286 // This code should never be reached, but is a fail-safe in case an | |
| 287 // exception is not recorded when it should be. | |
| 288 // | |
| 289 // TODO(brianwilkerson) Log this? | |
| 290 String message = 'State set to ERROR without setting an exception'; | |
| 291 exception = new CaughtException(new AnalysisException(message), null); | |
| 292 } | |
| 293 } else { | |
| 294 exception = null; | |
| 295 } | 291 } |
| 296 } | 292 } |
| 297 | 293 |
| 298 /** | 294 /** |
| 299 * Mark any AST structures associated with this cache entry as being flushed. | 295 * Mark any AST structures associated with this cache entry as being flushed. |
| 300 */ | 296 */ |
| 301 void flushAstStructures() { | 297 void flushAstStructures() { |
| 302 _resultMap.forEach((ResultDescriptor descriptor, ResultData data) { | 298 _resultMap.forEach((ResultDescriptor descriptor, ResultData data) { |
| 303 if (data.value is AstNode || data.value is XmlNode) { | 299 if (data.value is AstNode || data.value is XmlNode) { |
| 304 _validateStateChange(descriptor, CacheState.FLUSHED); | 300 _validateStateChange(descriptor, CacheState.FLUSHED); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 } | 337 } |
| 342 } | 338 } |
| 343 return false; | 339 return false; |
| 344 } | 340 } |
| 345 | 341 |
| 346 /** | 342 /** |
| 347 * Invalidate all of the information associated with this entry's target. | 343 * Invalidate all of the information associated with this entry's target. |
| 348 */ | 344 */ |
| 349 void invalidateAllInformation() { | 345 void invalidateAllInformation() { |
| 350 _resultMap.clear(); | 346 _resultMap.clear(); |
| 351 exception = null; | 347 _exception = null; |
| 352 } | 348 } |
| 353 | 349 |
| 354 /** | 350 /** |
| 351 * Set the [CacheState.ERROR] state for given [descriptors], their values to | |
| 352 * the corresponding default values, and remember the [exception] that caused | |
| 353 * this state. | |
| 354 */ | |
| 355 void setErrorState( | |
| 356 List<ResultDescriptor> descriptors, CaughtException exception) { | |
|
Brian Wilkerson
2015/03/07 15:43:32
I would prefer having the exception be the first a
scheglov
2015/03/07 17:01:04
Done.
| |
| 357 if (descriptors.isEmpty) { | |
| 358 throw new ArgumentError('at least one descriptor is expected'); | |
| 359 } | |
| 360 if (exception == null) { | |
| 361 throw new ArgumentError('an exception is expected'); | |
| 362 } | |
| 363 this._exception = exception; | |
| 364 for (ResultDescriptor descriptor in descriptors) { | |
| 365 ResultData data = _getResultData(descriptor); | |
| 366 data.state = CacheState.ERROR; | |
| 367 data.value = descriptor.defaultValue; | |
| 368 } | |
| 369 } | |
| 370 | |
| 371 /** | |
| 355 * Set the state of the result represented by the given [descriptor] to the | 372 * Set the state of the result represented by the given [descriptor] to the |
| 356 * given [state]. | 373 * given [state]. |
| 357 */ | 374 */ |
| 358 void setState(ResultDescriptor descriptor, CacheState state) { | 375 void setState(ResultDescriptor descriptor, CacheState state) { |
| 359 // TODO(brianwilkerson) Consider introducing a different method used to set | 376 if (state == CacheState.ERROR) { |
| 360 // the state of a list of descriptors to ERROR that could validate that an | 377 throw new ArgumentError('use setErrorState() to set the state to ERROR'); |
| 361 // exception was also provided. (It would then be an error to use this | 378 } |
| 362 // method to set the state to ERROR.) | |
| 363 if (state == CacheState.VALID) { | 379 if (state == CacheState.VALID) { |
| 364 throw new ArgumentError('use setValue() to set the state to VALID'); | 380 throw new ArgumentError('use setValue() to set the state to VALID'); |
| 365 } | 381 } |
| 366 _validateStateChange(descriptor, state); | 382 _validateStateChange(descriptor, state); |
| 367 if (state == CacheState.INVALID) { | 383 if (state == CacheState.INVALID) { |
| 368 _resultMap.remove(descriptor); | 384 _resultMap.remove(descriptor); |
| 369 } else { | 385 } else { |
| 370 ResultData data = | 386 ResultData data = _getResultData(descriptor); |
| 371 _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); | |
| 372 data.state = state; | 387 data.state = state; |
| 373 if (state != CacheState.IN_PROCESS) { | 388 if (state != CacheState.IN_PROCESS) { |
| 374 // | 389 // |
| 375 // If the state is in-process, we can leave the current value in the | 390 // If the state is in-process, we can leave the current value in the |
| 376 // cache for any 'get' methods to access. | 391 // cache for any 'get' methods to access. |
| 377 // | 392 // |
| 378 data.value = descriptor.defaultValue; | 393 data.value = descriptor.defaultValue; |
| 379 } | 394 } |
| 380 } | 395 } |
| 381 } | 396 } |
| 382 | 397 |
| 383 /** | 398 /** |
| 384 * Set the value of the result represented by the given [descriptor] to the | 399 * Set the value of the result represented by the given [descriptor] to the |
| 385 * given [value]. | 400 * given [value]. |
| 386 */ | 401 */ |
| 387 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ | 402 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ |
| 388 value) { | 403 value) { |
| 389 _validateStateChange(descriptor, CacheState.VALID); | 404 _validateStateChange(descriptor, CacheState.VALID); |
| 390 ResultData data = | 405 ResultData data = _getResultData(descriptor); |
| 391 _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); | |
| 392 data.state = CacheState.VALID; | 406 data.state = CacheState.VALID; |
| 393 data.value = value == null ? descriptor.defaultValue : value; | 407 data.value = value == null ? descriptor.defaultValue : value; |
| 394 } | 408 } |
| 395 | 409 |
| 396 @override | 410 @override |
| 397 String toString() { | 411 String toString() { |
| 398 StringBuffer buffer = new StringBuffer(); | 412 StringBuffer buffer = new StringBuffer(); |
| 399 _writeOn(buffer); | 413 _writeOn(buffer); |
| 400 return buffer.toString(); | 414 return buffer.toString(); |
| 401 } | 415 } |
| 402 | 416 |
| 403 /** | 417 /** |
| 404 * Return the value of the flag with the given [index]. | 418 * Return the value of the flag with the given [index]. |
| 405 */ | 419 */ |
| 406 bool _getFlag(int index) => BooleanArray.get(_flags, index); | 420 bool _getFlag(int index) => BooleanArray.get(_flags, index); |
| 407 | 421 |
| 408 /** | 422 /** |
| 423 * Look up the [ResultData] of [descriptor], or add a new one if it isn't | |
| 424 * there. | |
| 425 */ | |
| 426 ResultData _getResultData(ResultDescriptor descriptor) { | |
| 427 return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); | |
| 428 } | |
| 429 | |
| 430 /** | |
| 409 * Set the value of the flag with the given [index] to the given [value]. | 431 * Set the value of the flag with the given [index] to the given [value]. |
| 410 */ | 432 */ |
| 411 void _setFlag(int index, bool value) { | 433 void _setFlag(int index, bool value) { |
| 412 _flags = BooleanArray.set(_flags, index, value); | 434 _flags = BooleanArray.set(_flags, index, value); |
| 413 } | 435 } |
| 414 | 436 |
| 415 /** | 437 /** |
| 416 * If the state of the value described by the given [descriptor] is changing | 438 * If the state of the value described by the given [descriptor] is changing |
| 417 * from ERROR to anything else, capture the information. This is an attempt to | 439 * from ERROR to anything else, capture the information. This is an attempt to |
| 418 * discover the underlying cause of a long-standing bug. | 440 * discover the underlying cause of a long-standing bug. |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 * structures in the cache, using the [retentionPolicy] to determine which | 802 * structures in the cache, using the [retentionPolicy] to determine which |
| 781 * AST structures to flush. | 803 * AST structures to flush. |
| 782 */ | 804 */ |
| 783 UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize, | 805 UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize, |
| 784 CacheRetentionPolicy retentionPolicy) | 806 CacheRetentionPolicy retentionPolicy) |
| 785 : super(context, maxCacheSize, retentionPolicy); | 807 : super(context, maxCacheSize, retentionPolicy); |
| 786 | 808 |
| 787 @override | 809 @override |
| 788 bool contains(AnalysisTarget target) => true; | 810 bool contains(AnalysisTarget target) => true; |
| 789 } | 811 } |
| OLD | NEW |