| 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.context; | 5 library analyzer.src.context.context; |
| 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/cancelable_future.dart'; | 10 import 'package:analyzer/src/cancelable_future.dart'; |
| 11 import 'package:analyzer/src/context/cache.dart' as cache; | 11 import 'package:analyzer/src/context/cache.dart'; |
| 12 import 'package:analyzer/src/generated/ast.dart'; | 12 import 'package:analyzer/src/generated/ast.dart'; |
| 13 import 'package:analyzer/src/generated/constant.dart'; | 13 import 'package:analyzer/src/generated/constant.dart'; |
| 14 import 'package:analyzer/src/generated/element.dart'; | 14 import 'package:analyzer/src/generated/element.dart'; |
| 15 import 'package:analyzer/src/generated/engine.dart' hide WorkManager; | 15 import 'package:analyzer/src/generated/engine.dart' |
| 16 hide |
| 17 AnalysisCache, |
| 18 CachePartition, |
| 19 SdkCachePartition, |
| 20 UniversalCachePartition, |
| 21 WorkManager; |
| 16 import 'package:analyzer/src/generated/error.dart'; | 22 import 'package:analyzer/src/generated/error.dart'; |
| 17 import 'package:analyzer/src/generated/html.dart' as ht; | 23 import 'package:analyzer/src/generated/html.dart' as ht; |
| 18 import 'package:analyzer/src/generated/java_core.dart'; | 24 import 'package:analyzer/src/generated/java_core.dart'; |
| 19 import 'package:analyzer/src/generated/java_engine.dart'; | 25 import 'package:analyzer/src/generated/java_engine.dart'; |
| 20 import 'package:analyzer/src/generated/resolver.dart'; | 26 import 'package:analyzer/src/generated/resolver.dart'; |
| 21 import 'package:analyzer/src/generated/scanner.dart'; | 27 import 'package:analyzer/src/generated/scanner.dart'; |
| 22 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; | 28 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; |
| 23 import 'package:analyzer/src/generated/source.dart'; | 29 import 'package:analyzer/src/generated/source.dart'; |
| 24 import 'package:analyzer/src/generated/utilities_collection.dart'; | 30 import 'package:analyzer/src/generated/utilities_collection.dart'; |
| 25 import 'package:analyzer/src/task/dart.dart'; | 31 import 'package:analyzer/src/task/dart.dart'; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 36 * the computation can't be performed yet because more analysis is needed, | 42 * the computation can't be performed yet because more analysis is needed, |
| 37 * `null` should be returned. | 43 * `null` should be returned. |
| 38 * | 44 * |
| 39 * The function may also throw an exception, in which case the corresponding | 45 * The function may also throw an exception, in which case the corresponding |
| 40 * future will be completed with failure. | 46 * future will be completed with failure. |
| 41 * | 47 * |
| 42 * Because this function is called while the state of analysis is being updated, | 48 * Because this function is called while the state of analysis is being updated, |
| 43 * it should be free of side effects so that it doesn't cause reentrant changes | 49 * it should be free of side effects so that it doesn't cause reentrant changes |
| 44 * to the analysis state. | 50 * to the analysis state. |
| 45 */ | 51 */ |
| 46 typedef T PendingFutureComputer<T>(cache.CacheEntry entry); | 52 typedef T PendingFutureComputer<T>(CacheEntry entry); |
| 47 | 53 |
| 48 /** | 54 /** |
| 49 * An [AnalysisContext] in which analysis can be performed. | 55 * An [AnalysisContext] in which analysis can be performed. |
| 50 */ | 56 */ |
| 51 class AnalysisContextImpl implements InternalAnalysisContext { | 57 class AnalysisContextImpl implements InternalAnalysisContext { |
| 52 /** | 58 /** |
| 53 * A client-provided name used to identify this context, or `null` if the | 59 * A client-provided name used to identify this context, or `null` if the |
| 54 * client has not provided a name. | 60 * client has not provided a name. |
| 55 */ | 61 */ |
| 56 String name; | 62 String name; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 78 | 84 |
| 79 /** | 85 /** |
| 80 * The set of declared variables used when computing constant values. | 86 * The set of declared variables used when computing constant values. |
| 81 */ | 87 */ |
| 82 DeclaredVariables _declaredVariables = new DeclaredVariables(); | 88 DeclaredVariables _declaredVariables = new DeclaredVariables(); |
| 83 | 89 |
| 84 /** | 90 /** |
| 85 * The partition that contains analysis results that are not shared with other | 91 * The partition that contains analysis results that are not shared with other |
| 86 * contexts. | 92 * contexts. |
| 87 */ | 93 */ |
| 88 cache.CachePartition _privatePartition; | 94 CachePartition _privatePartition; |
| 89 | 95 |
| 90 /** | 96 /** |
| 91 * The cache in which information about the results associated with targets | 97 * The cache in which information about the results associated with targets |
| 92 * are stored. | 98 * are stored. |
| 93 */ | 99 */ |
| 94 cache.AnalysisCache _cache; | 100 AnalysisCache _cache; |
| 95 | 101 |
| 96 /** | 102 /** |
| 97 * The task manager used to manage the tasks used to analyze code. | 103 * The task manager used to manage the tasks used to analyze code. |
| 98 */ | 104 */ |
| 99 TaskManager _taskManager; | 105 TaskManager _taskManager; |
| 100 | 106 |
| 101 /** | 107 /** |
| 102 * The [DartWorkManager] instance that performs Dart specific scheduling. | 108 * The [DartWorkManager] instance that performs Dart specific scheduling. |
| 103 */ | 109 */ |
| 104 DartWorkManager dartWorkManager; | 110 DartWorkManager dartWorkManager; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 | 186 |
| 181 /** | 187 /** |
| 182 * A factory to override how [LibraryResolver] is created. | 188 * A factory to override how [LibraryResolver] is created. |
| 183 */ | 189 */ |
| 184 LibraryResolverFactory libraryResolverFactory; | 190 LibraryResolverFactory libraryResolverFactory; |
| 185 | 191 |
| 186 /** | 192 /** |
| 187 * Initialize a newly created analysis context. | 193 * Initialize a newly created analysis context. |
| 188 */ | 194 */ |
| 189 AnalysisContextImpl() { | 195 AnalysisContextImpl() { |
| 190 _privatePartition = new cache.UniversalCachePartition(this); | 196 _privatePartition = new UniversalCachePartition(this); |
| 191 _cache = createCacheFromSourceFactory(null); | 197 _cache = createCacheFromSourceFactory(null); |
| 192 _taskManager = AnalysisEngine.instance.taskManager; | 198 _taskManager = AnalysisEngine.instance.taskManager; |
| 193 // TODO(scheglov) Get WorkManager(Factory)(s) from plugins. | 199 // TODO(scheglov) Get WorkManager(Factory)(s) from plugins. |
| 194 dartWorkManager = new DartWorkManager(this); | 200 dartWorkManager = new DartWorkManager(this); |
| 195 driver = | 201 driver = |
| 196 new AnalysisDriver(_taskManager, <WorkManager>[dartWorkManager], this); | 202 new AnalysisDriver(_taskManager, <WorkManager>[dartWorkManager], this); |
| 197 _onSourcesChangedController = | 203 _onSourcesChangedController = |
| 198 new StreamController<SourcesChangedEvent>.broadcast(); | 204 new StreamController<SourcesChangedEvent>.broadcast(); |
| 199 } | 205 } |
| 200 | 206 |
| 201 @override | 207 @override |
| 202 cache.AnalysisCache get analysisCache => _cache; | 208 AnalysisCache get analysisCache => _cache; |
| 203 | 209 |
| 204 @override | 210 @override |
| 205 AnalysisOptions get analysisOptions => _options; | 211 AnalysisOptions get analysisOptions => _options; |
| 206 | 212 |
| 207 @override | 213 @override |
| 208 void set analysisOptions(AnalysisOptions options) { | 214 void set analysisOptions(AnalysisOptions options) { |
| 209 bool needsRecompute = this._options.analyzeFunctionBodiesPredicate != | 215 bool needsRecompute = this._options.analyzeFunctionBodiesPredicate != |
| 210 options.analyzeFunctionBodiesPredicate || | 216 options.analyzeFunctionBodiesPredicate || |
| 211 this._options.generateImplicitErrors != | 217 this._options.generateImplicitErrors != |
| 212 options.generateImplicitErrors || | 218 options.generateImplicitErrors || |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 set contentCache(ContentCache value) { | 266 set contentCache(ContentCache value) { |
| 261 _contentCache = value; | 267 _contentCache = value; |
| 262 } | 268 } |
| 263 | 269 |
| 264 @override | 270 @override |
| 265 DeclaredVariables get declaredVariables => _declaredVariables; | 271 DeclaredVariables get declaredVariables => _declaredVariables; |
| 266 | 272 |
| 267 @override | 273 @override |
| 268 List<AnalysisTarget> get explicitTargets { | 274 List<AnalysisTarget> get explicitTargets { |
| 269 List<AnalysisTarget> targets = <AnalysisTarget>[]; | 275 List<AnalysisTarget> targets = <AnalysisTarget>[]; |
| 270 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 276 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 271 while (iterator.moveNext()) { | 277 while (iterator.moveNext()) { |
| 272 if (iterator.value.explicitlyAdded) { | 278 if (iterator.value.explicitlyAdded) { |
| 273 targets.add(iterator.key); | 279 targets.add(iterator.key); |
| 274 } | 280 } |
| 275 } | 281 } |
| 276 return targets; | 282 return targets; |
| 277 } | 283 } |
| 278 | 284 |
| 279 @override | 285 @override |
| 280 List<Source> get htmlSources => _getSources(SourceKind.HTML); | 286 List<Source> get htmlSources => _getSources(SourceKind.HTML); |
| 281 | 287 |
| 282 @override | 288 @override |
| 283 bool get isDisposed => _disposed; | 289 bool get isDisposed => _disposed; |
| 284 | 290 |
| 285 @override | 291 @override |
| 286 List<Source> get launchableClientLibrarySources { | 292 List<Source> get launchableClientLibrarySources { |
| 287 List<Source> sources = new List<Source>(); | 293 List<Source> sources = new List<Source>(); |
| 288 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 294 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 289 while (iterator.moveNext()) { | 295 while (iterator.moveNext()) { |
| 290 AnalysisTarget target = iterator.key; | 296 AnalysisTarget target = iterator.key; |
| 291 cache.CacheEntry entry = iterator.value; | 297 CacheEntry entry = iterator.value; |
| 292 if (target is Source && | 298 if (target is Source && |
| 293 entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY && | 299 entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY && |
| 294 !target.isInSystemLibrary && | 300 !target.isInSystemLibrary && |
| 295 isClientLibrary(target)) { | 301 isClientLibrary(target)) { |
| 296 sources.add(target); | 302 sources.add(target); |
| 297 } | 303 } |
| 298 } | 304 } |
| 299 return sources; | 305 return sources; |
| 300 } | 306 } |
| 301 | 307 |
| 302 @override | 308 @override |
| 303 List<Source> get launchableServerLibrarySources { | 309 List<Source> get launchableServerLibrarySources { |
| 304 List<Source> sources = new List<Source>(); | 310 List<Source> sources = new List<Source>(); |
| 305 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 311 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 306 while (iterator.moveNext()) { | 312 while (iterator.moveNext()) { |
| 307 AnalysisTarget target = iterator.key; | 313 AnalysisTarget target = iterator.key; |
| 308 cache.CacheEntry entry = iterator.value; | 314 CacheEntry entry = iterator.value; |
| 309 if (target is Source && | 315 if (target is Source && |
| 310 entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY && | 316 entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY && |
| 311 !target.isInSystemLibrary && | 317 !target.isInSystemLibrary && |
| 312 isServerLibrary(target)) { | 318 isServerLibrary(target)) { |
| 313 sources.add(target); | 319 sources.add(target); |
| 314 } | 320 } |
| 315 } | 321 } |
| 316 return sources; | 322 return sources; |
| 317 } | 323 } |
| 318 | 324 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 } | 357 } |
| 352 factory.context = this; | 358 factory.context = this; |
| 353 _sourceFactory = factory; | 359 _sourceFactory = factory; |
| 354 _cache = createCacheFromSourceFactory(factory); | 360 _cache = createCacheFromSourceFactory(factory); |
| 355 _invalidateAllLocalResolutionInformation(true); | 361 _invalidateAllLocalResolutionInformation(true); |
| 356 } | 362 } |
| 357 | 363 |
| 358 @override | 364 @override |
| 359 List<Source> get sources { | 365 List<Source> get sources { |
| 360 List<Source> sources = new List<Source>(); | 366 List<Source> sources = new List<Source>(); |
| 361 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 367 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 362 while (iterator.moveNext()) { | 368 while (iterator.moveNext()) { |
| 363 AnalysisTarget target = iterator.key; | 369 AnalysisTarget target = iterator.key; |
| 364 if (target is Source) { | 370 if (target is Source) { |
| 365 sources.add(target); | 371 sources.add(target); |
| 366 } | 372 } |
| 367 } | 373 } |
| 368 return sources; | 374 return sources; |
| 369 } | 375 } |
| 370 | 376 |
| 371 /** | 377 /** |
| 372 * Return a list of the sources that would be processed by | 378 * Return a list of the sources that would be processed by |
| 373 * [performAnalysisTask]. This method duplicates, and must therefore be kept | 379 * [performAnalysisTask]. This method duplicates, and must therefore be kept |
| 374 * in sync with, [getNextAnalysisTask]. This method is intended to be used for | 380 * in sync with, [getNextAnalysisTask]. This method is intended to be used for |
| 375 * testing purposes only. | 381 * testing purposes only. |
| 376 */ | 382 */ |
| 377 List<Source> get sourcesNeedingProcessing { | 383 List<Source> get sourcesNeedingProcessing { |
| 378 HashSet<Source> sources = new HashSet<Source>(); | 384 HashSet<Source> sources = new HashSet<Source>(); |
| 379 bool hintsEnabled = _options.hint; | 385 bool hintsEnabled = _options.hint; |
| 380 bool lintsEnabled = _options.lint; | 386 bool lintsEnabled = _options.lint; |
| 381 | 387 |
| 382 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = | 388 MapIterator<AnalysisTarget, CacheEntry> iterator = |
| 383 _privatePartition.iterator(); | 389 _privatePartition.iterator(); |
| 384 while (iterator.moveNext()) { | 390 while (iterator.moveNext()) { |
| 385 AnalysisTarget target = iterator.key; | 391 AnalysisTarget target = iterator.key; |
| 386 if (target is Source) { | 392 if (target is Source) { |
| 387 _getSourcesNeedingProcessing( | 393 _getSourcesNeedingProcessing( |
| 388 target, iterator.value, false, hintsEnabled, lintsEnabled, sources); | 394 target, iterator.value, false, hintsEnabled, lintsEnabled, sources); |
| 389 } | 395 } |
| 390 } | 396 } |
| 391 return new List<Source>.from(sources); | 397 return new List<Source>.from(sources); |
| 392 } | 398 } |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 595 } |
| 590 | 596 |
| 591 @override | 597 @override |
| 592 CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync( | 598 CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync( |
| 593 Source unitSource, Source librarySource) { | 599 Source unitSource, Source librarySource) { |
| 594 if (!AnalysisEngine.isDartFileName(unitSource.shortName) || | 600 if (!AnalysisEngine.isDartFileName(unitSource.shortName) || |
| 595 !AnalysisEngine.isDartFileName(librarySource.shortName)) { | 601 !AnalysisEngine.isDartFileName(librarySource.shortName)) { |
| 596 return new CancelableFuture.error(new AnalysisNotScheduledError()); | 602 return new CancelableFuture.error(new AnalysisNotScheduledError()); |
| 597 } | 603 } |
| 598 return new _AnalysisFutureHelper<CompilationUnit>(this).computeAsync( | 604 return new _AnalysisFutureHelper<CompilationUnit>(this).computeAsync( |
| 599 new LibrarySpecificUnit(librarySource, unitSource), | 605 new LibrarySpecificUnit(librarySource, unitSource), (CacheEntry entry) { |
| 600 (cache.CacheEntry entry) { | |
| 601 CacheState state = entry.getState(RESOLVED_UNIT); | 606 CacheState state = entry.getState(RESOLVED_UNIT); |
| 602 if (state == CacheState.ERROR) { | 607 if (state == CacheState.ERROR) { |
| 603 throw entry.exception; | 608 throw entry.exception; |
| 604 } else if (state == CacheState.INVALID) { | 609 } else if (state == CacheState.INVALID) { |
| 605 return null; | 610 return null; |
| 606 } | 611 } |
| 607 return entry.getValue(RESOLVED_UNIT); | 612 return entry.getValue(RESOLVED_UNIT); |
| 608 }); | 613 }); |
| 609 } | 614 } |
| 610 | 615 |
| 611 /** | 616 /** |
| 612 * Create an analysis cache based on the given source [factory]. | 617 * Create an analysis cache based on the given source [factory]. |
| 613 */ | 618 */ |
| 614 cache.AnalysisCache createCacheFromSourceFactory(SourceFactory factory) { | 619 AnalysisCache createCacheFromSourceFactory(SourceFactory factory) { |
| 615 if (factory == null) { | 620 if (factory == null) { |
| 616 return new cache.AnalysisCache(<cache.CachePartition>[_privatePartition]); | 621 return new AnalysisCache(<CachePartition>[_privatePartition]); |
| 617 } | 622 } |
| 618 DartSdk sdk = factory.dartSdk; | 623 DartSdk sdk = factory.dartSdk; |
| 619 if (sdk == null) { | 624 if (sdk == null) { |
| 620 return new cache.AnalysisCache(<cache.CachePartition>[_privatePartition]); | 625 return new AnalysisCache(<CachePartition>[_privatePartition]); |
| 621 } | 626 } |
| 622 return new cache.AnalysisCache(<cache.CachePartition>[ | 627 return new AnalysisCache(<CachePartition>[ |
| 623 AnalysisEngine.instance.partitionManager_new.forSdk(sdk), | 628 AnalysisEngine.instance.partitionManager_new.forSdk(sdk), |
| 624 _privatePartition | 629 _privatePartition |
| 625 ]); | 630 ]); |
| 626 } | 631 } |
| 627 | 632 |
| 628 @override | 633 @override |
| 629 void dispose() { | 634 void dispose() { |
| 630 _disposed = true; | 635 _disposed = true; |
| 631 for (List<PendingFuture> pendingFutures in _pendingFutureTargets.values) { | 636 for (List<PendingFuture> pendingFutures in _pendingFutureTargets.values) { |
| 632 for (PendingFuture pendingFuture in pendingFutures) { | 637 for (PendingFuture pendingFuture in pendingFutures) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 if (source == null) { | 676 if (source == null) { |
| 672 return false; | 677 return false; |
| 673 } | 678 } |
| 674 if (_contentCache.getContents(source) != null) { | 679 if (_contentCache.getContents(source) != null) { |
| 675 return true; | 680 return true; |
| 676 } | 681 } |
| 677 return source.exists(); | 682 return source.exists(); |
| 678 } | 683 } |
| 679 | 684 |
| 680 @override | 685 @override |
| 681 cache.CacheEntry getCacheEntry(AnalysisTarget target) { | 686 CacheEntry getCacheEntry(AnalysisTarget target) { |
| 682 cache.CacheEntry entry = _cache.get(target); | 687 CacheEntry entry = _cache.get(target); |
| 683 if (entry == null) { | 688 if (entry == null) { |
| 684 entry = new cache.CacheEntry(target); | 689 entry = new CacheEntry(target); |
| 685 _cache.put(entry); | 690 _cache.put(entry); |
| 686 } | 691 } |
| 687 return entry; | 692 return entry; |
| 688 } | 693 } |
| 689 | 694 |
| 690 @override | 695 @override |
| 691 CompilationUnitElement getCompilationUnitElement( | 696 CompilationUnitElement getCompilationUnitElement( |
| 692 Source unitSource, Source librarySource) { | 697 Source unitSource, Source librarySource) { |
| 693 AnalysisTarget target = new LibrarySpecificUnit(librarySource, unitSource); | 698 AnalysisTarget target = new LibrarySpecificUnit(librarySource, unitSource); |
| 694 return _cache.getValue(target, COMPILATION_UNIT_ELEMENT); | 699 return _cache.getValue(target, COMPILATION_UNIT_ELEMENT); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 @override | 781 @override |
| 777 List<Source> getHtmlFilesReferencing(Source source) { | 782 List<Source> getHtmlFilesReferencing(Source source) { |
| 778 SourceKind sourceKind = getKindOf(source); | 783 SourceKind sourceKind = getKindOf(source); |
| 779 if (sourceKind == null) { | 784 if (sourceKind == null) { |
| 780 return Source.EMPTY_LIST; | 785 return Source.EMPTY_LIST; |
| 781 } | 786 } |
| 782 List<Source> htmlSources = new List<Source>(); | 787 List<Source> htmlSources = new List<Source>(); |
| 783 while (true) { | 788 while (true) { |
| 784 if (sourceKind == SourceKind.PART) { | 789 if (sourceKind == SourceKind.PART) { |
| 785 List<Source> librarySources = getLibrariesContaining(source); | 790 List<Source> librarySources = getLibrariesContaining(source); |
| 786 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = | 791 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 787 _cache.iterator(); | |
| 788 while (iterator.moveNext()) { | 792 while (iterator.moveNext()) { |
| 789 cache.CacheEntry entry = iterator.value; | 793 CacheEntry entry = iterator.value; |
| 790 if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) { | 794 if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) { |
| 791 List<Source> referencedLibraries = | 795 List<Source> referencedLibraries = |
| 792 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES); | 796 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES); |
| 793 if (_containsAny(referencedLibraries, librarySources)) { | 797 if (_containsAny(referencedLibraries, librarySources)) { |
| 794 htmlSources.add(iterator.key); | 798 htmlSources.add(iterator.key); |
| 795 } | 799 } |
| 796 } | 800 } |
| 797 } | 801 } |
| 798 } else { | 802 } else { |
| 799 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = | 803 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 800 _cache.iterator(); | |
| 801 while (iterator.moveNext()) { | 804 while (iterator.moveNext()) { |
| 802 cache.CacheEntry entry = iterator.value; | 805 CacheEntry entry = iterator.value; |
| 803 if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) { | 806 if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) { |
| 804 List<Source> referencedLibraries = | 807 List<Source> referencedLibraries = |
| 805 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES); | 808 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES); |
| 806 if (_contains(referencedLibraries, source)) { | 809 if (_contains(referencedLibraries, source)) { |
| 807 htmlSources.add(iterator.key); | 810 htmlSources.add(iterator.key); |
| 808 } | 811 } |
| 809 } | 812 } |
| 810 } | 813 } |
| 811 } | 814 } |
| 812 break; | 815 break; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 828 return SourceKind.UNKNOWN; | 831 return SourceKind.UNKNOWN; |
| 829 } | 832 } |
| 830 | 833 |
| 831 @override | 834 @override |
| 832 List<Source> getLibrariesContaining(Source source) { | 835 List<Source> getLibrariesContaining(Source source) { |
| 833 SourceKind kind = getKindOf(source); | 836 SourceKind kind = getKindOf(source); |
| 834 if (kind == SourceKind.LIBRARY) { | 837 if (kind == SourceKind.LIBRARY) { |
| 835 return <Source>[source]; | 838 return <Source>[source]; |
| 836 } else if (kind == SourceKind.PART) { | 839 } else if (kind == SourceKind.PART) { |
| 837 List<Source> libraries = <Source>[]; | 840 List<Source> libraries = <Source>[]; |
| 838 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = | 841 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 839 _cache.iterator(); | |
| 840 while (iterator.moveNext()) { | 842 while (iterator.moveNext()) { |
| 841 AnalysisTarget target = iterator.key; | 843 AnalysisTarget target = iterator.key; |
| 842 if (target is Source && getKindOf(target) == SourceKind.LIBRARY) { | 844 if (target is Source && getKindOf(target) == SourceKind.LIBRARY) { |
| 843 List<Source> parts = _cache.getValue(target, INCLUDED_PARTS); | 845 List<Source> parts = _cache.getValue(target, INCLUDED_PARTS); |
| 844 if (parts.contains(source)) { | 846 if (parts.contains(source)) { |
| 845 libraries.add(target); | 847 libraries.add(target); |
| 846 } | 848 } |
| 847 } | 849 } |
| 848 } | 850 } |
| 849 if (libraries.isNotEmpty) { | 851 if (libraries.isNotEmpty) { |
| 850 return libraries; | 852 return libraries; |
| 851 } | 853 } |
| 852 } | 854 } |
| 853 return Source.EMPTY_ARRAY; | 855 return Source.EMPTY_ARRAY; |
| 854 } | 856 } |
| 855 | 857 |
| 856 @override | 858 @override |
| 857 List<Source> getLibrariesDependingOn(Source librarySource) { | 859 List<Source> getLibrariesDependingOn(Source librarySource) { |
| 858 List<Source> dependentLibraries = new List<Source>(); | 860 List<Source> dependentLibraries = new List<Source>(); |
| 859 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 861 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 860 while (iterator.moveNext()) { | 862 while (iterator.moveNext()) { |
| 861 cache.CacheEntry entry = iterator.value; | 863 CacheEntry entry = iterator.value; |
| 862 if (entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY) { | 864 if (entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY) { |
| 863 if (_contains(entry.getValue(EXPORTED_LIBRARIES), librarySource)) { | 865 if (_contains(entry.getValue(EXPORTED_LIBRARIES), librarySource)) { |
| 864 dependentLibraries.add(iterator.key); | 866 dependentLibraries.add(iterator.key); |
| 865 } | 867 } |
| 866 if (_contains(entry.getValue(IMPORTED_LIBRARIES), librarySource)) { | 868 if (_contains(entry.getValue(IMPORTED_LIBRARIES), librarySource)) { |
| 867 dependentLibraries.add(iterator.key); | 869 dependentLibraries.add(iterator.key); |
| 868 } | 870 } |
| 869 } | 871 } |
| 870 } | 872 } |
| 871 if (dependentLibraries.isEmpty) { | 873 if (dependentLibraries.isEmpty) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 // and it is not used with tasks - instead we compute export namespace once | 913 // and it is not used with tasks - instead we compute export namespace once |
| 912 // using BuildExportNamespaceTask and reuse in scopes. | 914 // using BuildExportNamespaceTask and reuse in scopes. |
| 913 NamespaceBuilder builder = new NamespaceBuilder(); | 915 NamespaceBuilder builder = new NamespaceBuilder(); |
| 914 return builder.createPublicNamespaceForLibrary(library); | 916 return builder.createPublicNamespaceForLibrary(library); |
| 915 } | 917 } |
| 916 | 918 |
| 917 /** | 919 /** |
| 918 * Return the cache entry associated with the given [target], or `null` if | 920 * Return the cache entry associated with the given [target], or `null` if |
| 919 * there is no entry associated with the target. | 921 * there is no entry associated with the target. |
| 920 */ | 922 */ |
| 921 cache.CacheEntry getReadableSourceEntryOrNull(AnalysisTarget target) => | 923 CacheEntry getReadableSourceEntryOrNull(AnalysisTarget target) => |
| 922 _cache.get(target); | 924 _cache.get(target); |
| 923 | 925 |
| 924 @override | 926 @override |
| 925 CompilationUnit getResolvedCompilationUnit( | 927 CompilationUnit getResolvedCompilationUnit( |
| 926 Source unitSource, LibraryElement library) { | 928 Source unitSource, LibraryElement library) { |
| 927 if (library == null || | 929 if (library == null || |
| 928 !AnalysisEngine.isDartFileName(unitSource.shortName)) { | 930 !AnalysisEngine.isDartFileName(unitSource.shortName)) { |
| 929 return null; | 931 return null; |
| 930 } | 932 } |
| 931 return getResolvedCompilationUnit2(unitSource, library.source); | 933 return getResolvedCompilationUnit2(unitSource, library.source); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 949 // if (sourceEntry is HtmlEntry) { | 951 // if (sourceEntry is HtmlEntry) { |
| 950 // HtmlEntry htmlEntry = sourceEntry; | 952 // HtmlEntry htmlEntry = sourceEntry; |
| 951 // return htmlEntry.getValue(HtmlEntry.RESOLVED_UNIT); | 953 // return htmlEntry.getValue(HtmlEntry.RESOLVED_UNIT); |
| 952 // } | 954 // } |
| 953 return null; | 955 return null; |
| 954 } | 956 } |
| 955 | 957 |
| 956 @override | 958 @override |
| 957 List<Source> getSourcesWithFullName(String path) { | 959 List<Source> getSourcesWithFullName(String path) { |
| 958 List<Source> sources = <Source>[]; | 960 List<Source> sources = <Source>[]; |
| 959 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 961 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 960 while (iterator.moveNext()) { | 962 while (iterator.moveNext()) { |
| 961 AnalysisTarget target = iterator.key; | 963 AnalysisTarget target = iterator.key; |
| 962 if (target is Source && target.fullName == path) { | 964 if (target is Source && target.fullName == path) { |
| 963 sources.add(target); | 965 sources.add(target); |
| 964 } | 966 } |
| 965 } | 967 } |
| 966 return sources; | 968 return sources; |
| 967 } | 969 } |
| 968 | 970 |
| 969 @override | 971 @override |
| 970 bool handleContentsChanged( | 972 bool handleContentsChanged( |
| 971 Source source, String originalContents, String newContents, bool notify) { | 973 Source source, String originalContents, String newContents, bool notify) { |
| 972 cache.CacheEntry entry = _cache.get(source); | 974 CacheEntry entry = _cache.get(source); |
| 973 if (entry == null) { | 975 if (entry == null) { |
| 974 return false; | 976 return false; |
| 975 } | 977 } |
| 976 bool changed = newContents != originalContents; | 978 bool changed = newContents != originalContents; |
| 977 if (newContents != null) { | 979 if (newContents != null) { |
| 978 if (newContents != originalContents) { | 980 if (newContents != originalContents) { |
| 979 _incrementalAnalysisCache = | 981 _incrementalAnalysisCache = |
| 980 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); | 982 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); |
| 981 if (!analysisOptions.incremental || | 983 if (!analysisOptions.incremental || |
| 982 !_tryPoorMansIncrementalResolution(source, newContents)) { | 984 !_tryPoorMansIncrementalResolution(source, newContents)) { |
| 983 _sourceChanged(source); | 985 _sourceChanged(source); |
| 984 } | 986 } |
| 985 entry.modificationTime = _contentCache.getModificationStamp(source); | 987 entry.modificationTime = _contentCache.getModificationStamp(source); |
| 986 entry.setValue(CONTENT, newContents, cache.TargetedResult.EMPTY_LIST); | 988 entry.setValue(CONTENT, newContents, TargetedResult.EMPTY_LIST); |
| 987 } else { | 989 } else { |
| 988 entry.modificationTime = _contentCache.getModificationStamp(source); | 990 entry.modificationTime = _contentCache.getModificationStamp(source); |
| 989 } | 991 } |
| 990 } else if (originalContents != null) { | 992 } else if (originalContents != null) { |
| 991 _incrementalAnalysisCache = | 993 _incrementalAnalysisCache = |
| 992 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); | 994 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); |
| 993 changed = newContents != originalContents; | 995 changed = newContents != originalContents; |
| 994 // We are removing the overlay for the file, check if the file's | 996 // We are removing the overlay for the file, check if the file's |
| 995 // contents is the same as it was in the overlay. | 997 // contents is the same as it was in the overlay. |
| 996 try { | 998 try { |
| 997 TimestampedData<String> fileContents = getContents(source); | 999 TimestampedData<String> fileContents = getContents(source); |
| 998 String fileContentsData = fileContents.data; | 1000 String fileContentsData = fileContents.data; |
| 999 if (fileContentsData == originalContents) { | 1001 if (fileContentsData == originalContents) { |
| 1000 entry.setValue( | 1002 entry.setValue(CONTENT, fileContentsData, TargetedResult.EMPTY_LIST); |
| 1001 CONTENT, fileContentsData, cache.TargetedResult.EMPTY_LIST); | |
| 1002 entry.modificationTime = fileContents.modificationTime; | 1003 entry.modificationTime = fileContents.modificationTime; |
| 1003 changed = false; | 1004 changed = false; |
| 1004 } | 1005 } |
| 1005 } catch (e) {} | 1006 } catch (e) {} |
| 1006 // If not the same content (e.g. the file is being closed without save), | 1007 // If not the same content (e.g. the file is being closed without save), |
| 1007 // then force analysis. | 1008 // then force analysis. |
| 1008 if (changed) { | 1009 if (changed) { |
| 1009 _sourceChanged(source); | 1010 _sourceChanged(source); |
| 1010 } | 1011 } |
| 1011 } | 1012 } |
| 1012 if (notify && changed) { | 1013 if (notify && changed) { |
| 1013 _onSourcesChangedController | 1014 _onSourcesChangedController |
| 1014 .add(new SourcesChangedEvent.changedContent(source, newContents)); | 1015 .add(new SourcesChangedEvent.changedContent(source, newContents)); |
| 1015 } | 1016 } |
| 1016 return changed; | 1017 return changed; |
| 1017 } | 1018 } |
| 1018 | 1019 |
| 1019 @override | 1020 @override |
| 1020 bool isClientLibrary(Source librarySource) { | 1021 bool isClientLibrary(Source librarySource) { |
| 1021 cache.CacheEntry entry = _cache.get(librarySource); | 1022 CacheEntry entry = _cache.get(librarySource); |
| 1022 return entry.getValue(IS_CLIENT) && entry.getValue(IS_LAUNCHABLE); | 1023 return entry.getValue(IS_CLIENT) && entry.getValue(IS_LAUNCHABLE); |
| 1023 } | 1024 } |
| 1024 | 1025 |
| 1025 @override | 1026 @override |
| 1026 bool isServerLibrary(Source librarySource) { | 1027 bool isServerLibrary(Source librarySource) { |
| 1027 cache.CacheEntry entry = _cache.get(librarySource); | 1028 CacheEntry entry = _cache.get(librarySource); |
| 1028 return !entry.getValue(IS_CLIENT) && entry.getValue(IS_LAUNCHABLE); | 1029 return !entry.getValue(IS_CLIENT) && entry.getValue(IS_LAUNCHABLE); |
| 1029 } | 1030 } |
| 1030 | 1031 |
| 1031 @override | 1032 @override |
| 1032 CompilationUnit parseCompilationUnit(Source source) { | 1033 CompilationUnit parseCompilationUnit(Source source) { |
| 1033 if (!AnalysisEngine.isDartFileName(source.shortName)) { | 1034 if (!AnalysisEngine.isDartFileName(source.shortName)) { |
| 1034 return null; | 1035 return null; |
| 1035 } | 1036 } |
| 1036 return _computeResult(source, PARSED_UNIT); | 1037 return _computeResult(source, PARSED_UNIT); |
| 1037 } | 1038 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1063 return new AnalysisResult(notices, -1, '', -1); | 1064 return new AnalysisResult(notices, -1, '', -1); |
| 1064 }); | 1065 }); |
| 1065 } | 1066 } |
| 1066 | 1067 |
| 1067 @override | 1068 @override |
| 1068 void recordLibraryElements(Map<Source, LibraryElement> elementMap) { | 1069 void recordLibraryElements(Map<Source, LibraryElement> elementMap) { |
| 1069 elementMap.forEach((Source librarySource, LibraryElement library) { | 1070 elementMap.forEach((Source librarySource, LibraryElement library) { |
| 1070 // | 1071 // |
| 1071 // Cache the element in the library's info. | 1072 // Cache the element in the library's info. |
| 1072 // | 1073 // |
| 1073 cache.CacheEntry entry = getCacheEntry(librarySource); | 1074 CacheEntry entry = getCacheEntry(librarySource); |
| 1074 setValue(ResultDescriptor result, value) { | 1075 setValue(ResultDescriptor result, value) { |
| 1075 entry.setValue(result, value, cache.TargetedResult.EMPTY_LIST); | 1076 entry.setValue(result, value, TargetedResult.EMPTY_LIST); |
| 1076 } | 1077 } |
| 1077 setValue(BUILD_DIRECTIVES_ERRORS, AnalysisError.NO_ERRORS); | 1078 setValue(BUILD_DIRECTIVES_ERRORS, AnalysisError.NO_ERRORS); |
| 1078 setValue(BUILD_FUNCTION_TYPE_ALIASES_ERRORS, AnalysisError.NO_ERRORS); | 1079 setValue(BUILD_FUNCTION_TYPE_ALIASES_ERRORS, AnalysisError.NO_ERRORS); |
| 1079 setValue(BUILD_LIBRARY_ERRORS, AnalysisError.NO_ERRORS); | 1080 setValue(BUILD_LIBRARY_ERRORS, AnalysisError.NO_ERRORS); |
| 1080 // CLASS_ELEMENTS | 1081 // CLASS_ELEMENTS |
| 1081 setValue(COMPILATION_UNIT_ELEMENT, library.definingCompilationUnit); | 1082 setValue(COMPILATION_UNIT_ELEMENT, library.definingCompilationUnit); |
| 1082 // CONSTRUCTORS | 1083 // CONSTRUCTORS |
| 1083 // CONSTRUCTORS_ERRORS | 1084 // CONSTRUCTORS_ERRORS |
| 1084 entry.setState(CONTENT, CacheState.FLUSHED); | 1085 entry.setState(CONTENT, CacheState.FLUSHED); |
| 1085 setValue(EXPORTED_LIBRARIES, Source.EMPTY_LIST); | 1086 setValue(EXPORTED_LIBRARIES, Source.EMPTY_LIST); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1114 entry.setState(RESOLVED_UNIT1, CacheState.FLUSHED); | 1115 entry.setState(RESOLVED_UNIT1, CacheState.FLUSHED); |
| 1115 entry.setState(RESOLVED_UNIT2, CacheState.FLUSHED); | 1116 entry.setState(RESOLVED_UNIT2, CacheState.FLUSHED); |
| 1116 entry.setState(RESOLVED_UNIT3, CacheState.FLUSHED); | 1117 entry.setState(RESOLVED_UNIT3, CacheState.FLUSHED); |
| 1117 entry.setState(RESOLVED_UNIT4, CacheState.FLUSHED); | 1118 entry.setState(RESOLVED_UNIT4, CacheState.FLUSHED); |
| 1118 entry.setState(RESOLVED_UNIT5, CacheState.FLUSHED); | 1119 entry.setState(RESOLVED_UNIT5, CacheState.FLUSHED); |
| 1119 // USED_IMPORTED_ELEMENTS | 1120 // USED_IMPORTED_ELEMENTS |
| 1120 // USED_LOCAL_ELEMENTS | 1121 // USED_LOCAL_ELEMENTS |
| 1121 setValue(VERIFY_ERRORS, AnalysisError.NO_ERRORS); | 1122 setValue(VERIFY_ERRORS, AnalysisError.NO_ERRORS); |
| 1122 }); | 1123 }); |
| 1123 | 1124 |
| 1124 cache.CacheEntry entry = getCacheEntry(AnalysisContextTarget.request); | 1125 CacheEntry entry = getCacheEntry(AnalysisContextTarget.request); |
| 1125 entry.setValue( | 1126 entry.setValue(TYPE_PROVIDER, typeProvider, TargetedResult.EMPTY_LIST); |
| 1126 TYPE_PROVIDER, typeProvider, cache.TargetedResult.EMPTY_LIST); | |
| 1127 } | 1127 } |
| 1128 | 1128 |
| 1129 @override | 1129 @override |
| 1130 void removeListener(AnalysisListener listener) { | 1130 void removeListener(AnalysisListener listener) { |
| 1131 _listeners.remove(listener); | 1131 _listeners.remove(listener); |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 @override | 1134 @override |
| 1135 CompilationUnit resolveCompilationUnit( | 1135 CompilationUnit resolveCompilationUnit( |
| 1136 Source unitSource, LibraryElement library) { | 1136 Source unitSource, LibraryElement library) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 */ | 1243 */ |
| 1244 void visitContentCache(ContentCacheVisitor visitor) { | 1244 void visitContentCache(ContentCacheVisitor visitor) { |
| 1245 _contentCache.accept(visitor); | 1245 _contentCache.accept(visitor); |
| 1246 } | 1246 } |
| 1247 | 1247 |
| 1248 /** | 1248 /** |
| 1249 * Add all of the sources contained in the given source [container] to the | 1249 * Add all of the sources contained in the given source [container] to the |
| 1250 * given list of [sources]. | 1250 * given list of [sources]. |
| 1251 */ | 1251 */ |
| 1252 void _addSourcesInContainer(List<Source> sources, SourceContainer container) { | 1252 void _addSourcesInContainer(List<Source> sources, SourceContainer container) { |
| 1253 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 1253 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 1254 while (iterator.moveNext()) { | 1254 while (iterator.moveNext()) { |
| 1255 Source source = iterator.key; | 1255 Source source = iterator.key; |
| 1256 if (container.contains(source)) { | 1256 if (container.contains(source)) { |
| 1257 sources.add(source); | 1257 sources.add(source); |
| 1258 } | 1258 } |
| 1259 } | 1259 } |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 /** | 1262 /** |
| 1263 * Remove the given [pendingFuture] from [_pendingFutureTargets], since the | 1263 * Remove the given [pendingFuture] from [_pendingFutureTargets], since the |
| 1264 * client has indicated its computation is not needed anymore. | 1264 * client has indicated its computation is not needed anymore. |
| 1265 */ | 1265 */ |
| 1266 void _cancelFuture(PendingFuture pendingFuture) { | 1266 void _cancelFuture(PendingFuture pendingFuture) { |
| 1267 List<PendingFuture> pendingFutures = | 1267 List<PendingFuture> pendingFutures = |
| 1268 _pendingFutureTargets[pendingFuture.target]; | 1268 _pendingFutureTargets[pendingFuture.target]; |
| 1269 if (pendingFutures != null) { | 1269 if (pendingFutures != null) { |
| 1270 pendingFutures.remove(pendingFuture); | 1270 pendingFutures.remove(pendingFuture); |
| 1271 if (pendingFutures.isEmpty) { | 1271 if (pendingFutures.isEmpty) { |
| 1272 _pendingFutureTargets.remove(pendingFuture.target); | 1272 _pendingFutureTargets.remove(pendingFuture.target); |
| 1273 } | 1273 } |
| 1274 } | 1274 } |
| 1275 } | 1275 } |
| 1276 | 1276 |
| 1277 Object /*V*/ _computeResult( | 1277 Object /*V*/ _computeResult( |
| 1278 AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) { | 1278 AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) { |
| 1279 cache.CacheEntry entry = getCacheEntry(target); | 1279 CacheEntry entry = getCacheEntry(target); |
| 1280 CacheState state = entry.getState(descriptor); | 1280 CacheState state = entry.getState(descriptor); |
| 1281 if (state == CacheState.FLUSHED || state == CacheState.INVALID) { | 1281 if (state == CacheState.FLUSHED || state == CacheState.INVALID) { |
| 1282 driver.computeResult(target, descriptor); | 1282 driver.computeResult(target, descriptor); |
| 1283 } | 1283 } |
| 1284 state = entry.getState(descriptor); | 1284 state = entry.getState(descriptor); |
| 1285 if (state == CacheState.ERROR) { | 1285 if (state == CacheState.ERROR) { |
| 1286 throw new AnalysisException( | 1286 throw new AnalysisException( |
| 1287 'Cannot compute $descriptor for $target', entry.exception); | 1287 'Cannot compute $descriptor for $target', entry.exception); |
| 1288 } | 1288 } |
| 1289 return entry.getValue(descriptor); | 1289 return entry.getValue(descriptor); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 if (contents != null) { | 1336 if (contents != null) { |
| 1337 if (contents != originalContents) { | 1337 if (contents != originalContents) { |
| 1338 // TODO(brianwilkerson) Find a better way to do incremental analysis. | 1338 // TODO(brianwilkerson) Find a better way to do incremental analysis. |
| 1339 // if (_options.incremental) { | 1339 // if (_options.incremental) { |
| 1340 // _incrementalAnalysisCache = IncrementalAnalysisCache.update( | 1340 // _incrementalAnalysisCache = IncrementalAnalysisCache.update( |
| 1341 // _incrementalAnalysisCache, source, originalContents, contents, | 1341 // _incrementalAnalysisCache, source, originalContents, contents, |
| 1342 // offset, oldLength, newLength, _cache.get(source)); | 1342 // offset, oldLength, newLength, _cache.get(source)); |
| 1343 // } | 1343 // } |
| 1344 _sourceChanged(source); | 1344 _sourceChanged(source); |
| 1345 changed = true; | 1345 changed = true; |
| 1346 cache.CacheEntry entry = _cache.get(source); | 1346 CacheEntry entry = _cache.get(source); |
| 1347 if (entry != null) { | 1347 if (entry != null) { |
| 1348 entry.modificationTime = _contentCache.getModificationStamp(source); | 1348 entry.modificationTime = _contentCache.getModificationStamp(source); |
| 1349 entry.setValue(CONTENT, contents, cache.TargetedResult.EMPTY_LIST); | 1349 entry.setValue(CONTENT, contents, TargetedResult.EMPTY_LIST); |
| 1350 } | 1350 } |
| 1351 } | 1351 } |
| 1352 } else if (originalContents != null) { | 1352 } else if (originalContents != null) { |
| 1353 _incrementalAnalysisCache = | 1353 _incrementalAnalysisCache = |
| 1354 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); | 1354 IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); |
| 1355 _sourceChanged(source); | 1355 _sourceChanged(source); |
| 1356 changed = true; | 1356 changed = true; |
| 1357 } | 1357 } |
| 1358 return changed; | 1358 return changed; |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 /** | 1361 /** |
| 1362 * Set the contents of the given [source] to the given [contents] and mark the | 1362 * Set the contents of the given [source] to the given [contents] and mark the |
| 1363 * source as having changed. This has the effect of overriding the default | 1363 * source as having changed. This has the effect of overriding the default |
| 1364 * contents of the source. If the contents are `null` the override is removed | 1364 * contents of the source. If the contents are `null` the override is removed |
| 1365 * so that the default contents will be returned. If [notify] is true, a | 1365 * so that the default contents will be returned. If [notify] is true, a |
| 1366 * source changed event is triggered. | 1366 * source changed event is triggered. |
| 1367 */ | 1367 */ |
| 1368 void _contentsChanged(Source source, String contents, bool notify) { | 1368 void _contentsChanged(Source source, String contents, bool notify) { |
| 1369 String originalContents = _contentCache.setContents(source, contents); | 1369 String originalContents = _contentCache.setContents(source, contents); |
| 1370 handleContentsChanged(source, originalContents, contents, notify); | 1370 handleContentsChanged(source, originalContents, contents, notify); |
| 1371 } | 1371 } |
| 1372 | 1372 |
| 1373 /** | 1373 /** |
| 1374 * Create a cache entry for the given [source]. The source was explicitly | 1374 * Create a cache entry for the given [source]. The source was explicitly |
| 1375 * added to this context if [explicitlyAdded] is `true`. Return the cache | 1375 * added to this context if [explicitlyAdded] is `true`. Return the cache |
| 1376 * entry that was created. | 1376 * entry that was created. |
| 1377 */ | 1377 */ |
| 1378 cache.CacheEntry _createCacheEntry(Source source, bool explicitlyAdded) { | 1378 CacheEntry _createCacheEntry(Source source, bool explicitlyAdded) { |
| 1379 cache.CacheEntry entry = new cache.CacheEntry(source); | 1379 CacheEntry entry = new CacheEntry(source); |
| 1380 entry.modificationTime = getModificationStamp(source); | 1380 entry.modificationTime = getModificationStamp(source); |
| 1381 entry.explicitlyAdded = explicitlyAdded; | 1381 entry.explicitlyAdded = explicitlyAdded; |
| 1382 _cache.put(entry); | 1382 _cache.put(entry); |
| 1383 return entry; | 1383 return entry; |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 /** | 1386 /** |
| 1387 * Return a list containing all of the cache entries for targets associated | 1387 * Return a list containing all of the cache entries for targets associated |
| 1388 * with the given [source]. | 1388 * with the given [source]. |
| 1389 */ | 1389 */ |
| 1390 List<cache.CacheEntry> _entriesFor(Source source) { | 1390 List<CacheEntry> _entriesFor(Source source) { |
| 1391 List<cache.CacheEntry> entries = <cache.CacheEntry>[]; | 1391 List<CacheEntry> entries = <CacheEntry>[]; |
| 1392 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 1392 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 1393 while (iterator.moveNext()) { | 1393 while (iterator.moveNext()) { |
| 1394 if (iterator.key.source == source) { | 1394 if (iterator.key.source == source) { |
| 1395 entries.add(iterator.value); | 1395 entries.add(iterator.value); |
| 1396 } | 1396 } |
| 1397 } | 1397 } |
| 1398 return entries; | 1398 return entries; |
| 1399 } | 1399 } |
| 1400 | 1400 |
| 1401 /** | 1401 /** |
| 1402 * Return a list containing all of the change notices that are waiting to be | 1402 * Return a list containing all of the change notices that are waiting to be |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1428 } | 1428 } |
| 1429 return notice; | 1429 return notice; |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 /** | 1432 /** |
| 1433 * Return a list containing all of the sources known to this context that have | 1433 * Return a list containing all of the sources known to this context that have |
| 1434 * the given [kind]. | 1434 * the given [kind]. |
| 1435 */ | 1435 */ |
| 1436 List<Source> _getSources(SourceKind kind) { | 1436 List<Source> _getSources(SourceKind kind) { |
| 1437 List<Source> sources = new List<Source>(); | 1437 List<Source> sources = new List<Source>(); |
| 1438 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 1438 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 1439 while (iterator.moveNext()) { | 1439 while (iterator.moveNext()) { |
| 1440 if (iterator.value.getValue(SOURCE_KIND) == kind && | 1440 if (iterator.value.getValue(SOURCE_KIND) == kind && |
| 1441 iterator.key is Source) { | 1441 iterator.key is Source) { |
| 1442 sources.add(iterator.key); | 1442 sources.add(iterator.key); |
| 1443 } | 1443 } |
| 1444 } | 1444 } |
| 1445 return sources; | 1445 return sources; |
| 1446 } | 1446 } |
| 1447 | 1447 |
| 1448 /** | 1448 /** |
| 1449 * Look at the given [source] to see whether a task needs to be performed | 1449 * Look at the given [source] to see whether a task needs to be performed |
| 1450 * related to it. If so, add the source to the set of sources that need to be | 1450 * related to it. If so, add the source to the set of sources that need to be |
| 1451 * processed. This method is intended to be used for testing purposes only. | 1451 * processed. This method is intended to be used for testing purposes only. |
| 1452 */ | 1452 */ |
| 1453 void _getSourcesNeedingProcessing(Source source, cache.CacheEntry entry, | 1453 void _getSourcesNeedingProcessing(Source source, CacheEntry entry, |
| 1454 bool isPriority, bool hintsEnabled, bool lintsEnabled, | 1454 bool isPriority, bool hintsEnabled, bool lintsEnabled, |
| 1455 HashSet<Source> sources) { | 1455 HashSet<Source> sources) { |
| 1456 CacheState state = entry.getState(CONTENT); | 1456 CacheState state = entry.getState(CONTENT); |
| 1457 if (state == CacheState.INVALID || | 1457 if (state == CacheState.INVALID || |
| 1458 (isPriority && state == CacheState.FLUSHED)) { | 1458 (isPriority && state == CacheState.FLUSHED)) { |
| 1459 sources.add(source); | 1459 sources.add(source); |
| 1460 return; | 1460 return; |
| 1461 } else if (state == CacheState.ERROR) { | 1461 } else if (state == CacheState.ERROR) { |
| 1462 return; | 1462 return; |
| 1463 } | 1463 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1487 } else if (state == CacheState.ERROR) { | 1487 } else if (state == CacheState.ERROR) { |
| 1488 return; | 1488 return; |
| 1489 } | 1489 } |
| 1490 // if (isPriority) { | 1490 // if (isPriority) { |
| 1491 // if (!entry.hasResolvableCompilationUnit) { | 1491 // if (!entry.hasResolvableCompilationUnit) { |
| 1492 // sources.add(source); | 1492 // sources.add(source); |
| 1493 // return; | 1493 // return; |
| 1494 // } | 1494 // } |
| 1495 // } | 1495 // } |
| 1496 for (Source librarySource in getLibrariesContaining(source)) { | 1496 for (Source librarySource in getLibrariesContaining(source)) { |
| 1497 cache.CacheEntry libraryEntry = _cache.get(librarySource); | 1497 CacheEntry libraryEntry = _cache.get(librarySource); |
| 1498 state = libraryEntry.getState(LIBRARY_ELEMENT); | 1498 state = libraryEntry.getState(LIBRARY_ELEMENT); |
| 1499 if (state == CacheState.INVALID || | 1499 if (state == CacheState.INVALID || |
| 1500 (isPriority && state == CacheState.FLUSHED)) { | 1500 (isPriority && state == CacheState.FLUSHED)) { |
| 1501 sources.add(source); | 1501 sources.add(source); |
| 1502 return; | 1502 return; |
| 1503 } else if (state == CacheState.ERROR) { | 1503 } else if (state == CacheState.ERROR) { |
| 1504 return; | 1504 return; |
| 1505 } | 1505 } |
| 1506 cache.CacheEntry unitEntry = | 1506 CacheEntry unitEntry = |
| 1507 _cache.get(new LibrarySpecificUnit(librarySource, source)); | 1507 _cache.get(new LibrarySpecificUnit(librarySource, source)); |
| 1508 state = unitEntry.getState(RESOLVED_UNIT); | 1508 state = unitEntry.getState(RESOLVED_UNIT); |
| 1509 if (state == CacheState.INVALID || | 1509 if (state == CacheState.INVALID || |
| 1510 (isPriority && state == CacheState.FLUSHED)) { | 1510 (isPriority && state == CacheState.FLUSHED)) { |
| 1511 sources.add(source); | 1511 sources.add(source); |
| 1512 return; | 1512 return; |
| 1513 } else if (state == CacheState.ERROR) { | 1513 } else if (state == CacheState.ERROR) { |
| 1514 return; | 1514 return; |
| 1515 } | 1515 } |
| 1516 if (_shouldErrorsBeAnalyzed(source, unitEntry)) { | 1516 if (_shouldErrorsBeAnalyzed(source, unitEntry)) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1646 } | 1646 } |
| 1647 if (newOrder.length < count) { | 1647 if (newOrder.length < count) { |
| 1648 analysisPriorityOrder = newOrder; | 1648 analysisPriorityOrder = newOrder; |
| 1649 } | 1649 } |
| 1650 } | 1650 } |
| 1651 | 1651 |
| 1652 /** | 1652 /** |
| 1653 * Return `true` if errors should be produced for the given [source]. The | 1653 * Return `true` if errors should be produced for the given [source]. The |
| 1654 * [entry] associated with the source is passed in for efficiency. | 1654 * [entry] associated with the source is passed in for efficiency. |
| 1655 */ | 1655 */ |
| 1656 bool _shouldErrorsBeAnalyzed(Source source, cache.CacheEntry entry) { | 1656 bool _shouldErrorsBeAnalyzed(Source source, CacheEntry entry) { |
| 1657 if (source.isInSystemLibrary) { | 1657 if (source.isInSystemLibrary) { |
| 1658 return _options.generateSdkErrors; | 1658 return _options.generateSdkErrors; |
| 1659 } else if (!entry.explicitlyAdded) { | 1659 } else if (!entry.explicitlyAdded) { |
| 1660 return _options.generateImplicitErrors; | 1660 return _options.generateImplicitErrors; |
| 1661 } else { | 1661 } else { |
| 1662 return true; | 1662 return true; |
| 1663 } | 1663 } |
| 1664 } | 1664 } |
| 1665 | 1665 |
| 1666 /** | 1666 /** |
| 1667 * Create an entry for the newly added [source] and invalidate any sources | 1667 * Create an entry for the newly added [source] and invalidate any sources |
| 1668 * that referenced the source before it existed. | 1668 * that referenced the source before it existed. |
| 1669 */ | 1669 */ |
| 1670 void _sourceAvailable(Source source) { | 1670 void _sourceAvailable(Source source) { |
| 1671 cache.CacheEntry entry = _cache.get(source); | 1671 CacheEntry entry = _cache.get(source); |
| 1672 if (entry == null) { | 1672 if (entry == null) { |
| 1673 _createCacheEntry(source, true); | 1673 _createCacheEntry(source, true); |
| 1674 } else { | 1674 } else { |
| 1675 // TODO(brianwilkerson) Implement this. | 1675 // TODO(brianwilkerson) Implement this. |
| 1676 // _propagateInvalidation(source, entry); | 1676 // _propagateInvalidation(source, entry); |
| 1677 } | 1677 } |
| 1678 } | 1678 } |
| 1679 | 1679 |
| 1680 /** | 1680 /** |
| 1681 * Invalidate the [source] that was changed and any sources that referenced | 1681 * Invalidate the [source] that was changed and any sources that referenced |
| 1682 * the source before it existed. | 1682 * the source before it existed. |
| 1683 */ | 1683 */ |
| 1684 void _sourceChanged(Source source) { | 1684 void _sourceChanged(Source source) { |
| 1685 cache.CacheEntry entry = _cache.get(source); | 1685 CacheEntry entry = _cache.get(source); |
| 1686 // If the source is removed, we don't care about it. | 1686 // If the source is removed, we don't care about it. |
| 1687 if (entry == null) { | 1687 if (entry == null) { |
| 1688 return; | 1688 return; |
| 1689 } | 1689 } |
| 1690 // Check whether the content of the source is the same as it was the last | 1690 // Check whether the content of the source is the same as it was the last |
| 1691 // time. | 1691 // time. |
| 1692 String sourceContent = entry.getValue(CONTENT); | 1692 String sourceContent = entry.getValue(CONTENT); |
| 1693 if (sourceContent != null) { | 1693 if (sourceContent != null) { |
| 1694 entry.setState(CONTENT, CacheState.FLUSHED); | 1694 entry.setState(CONTENT, CacheState.FLUSHED); |
| 1695 try { | 1695 try { |
| 1696 TimestampedData<String> fileContents = getContents(source); | 1696 TimestampedData<String> fileContents = getContents(source); |
| 1697 if (fileContents.data == sourceContent) { | 1697 if (fileContents.data == sourceContent) { |
| 1698 int time = fileContents.modificationTime; | 1698 int time = fileContents.modificationTime; |
| 1699 for (cache.CacheEntry entry in _entriesFor(source)) { | 1699 for (CacheEntry entry in _entriesFor(source)) { |
| 1700 entry.modificationTime = time; | 1700 entry.modificationTime = time; |
| 1701 } | 1701 } |
| 1702 return; | 1702 return; |
| 1703 } | 1703 } |
| 1704 } catch (e) {} | 1704 } catch (e) {} |
| 1705 } | 1705 } |
| 1706 // We need to invalidate the cache. | 1706 // We need to invalidate the cache. |
| 1707 // TODO(brianwilkerson) Implement this. | 1707 // TODO(brianwilkerson) Implement this. |
| 1708 // _propagateInvalidation(source, entry); | 1708 // _propagateInvalidation(source, entry); |
| 1709 } | 1709 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 /** | 1814 /** |
| 1815 * Check the cache for any invalid entries (entries whose modification time | 1815 * Check the cache for any invalid entries (entries whose modification time |
| 1816 * does not match the modification time of the source associated with the | 1816 * does not match the modification time of the source associated with the |
| 1817 * entry). Invalid entries will be marked as invalid so that the source will | 1817 * entry). Invalid entries will be marked as invalid so that the source will |
| 1818 * be re-analyzed. Return `true` if at least one entry was invalid. | 1818 * be re-analyzed. Return `true` if at least one entry was invalid. |
| 1819 */ | 1819 */ |
| 1820 bool _validateCacheConsistency() { | 1820 bool _validateCacheConsistency() { |
| 1821 int consistencyCheckStart = JavaSystem.nanoTime(); | 1821 int consistencyCheckStart = JavaSystem.nanoTime(); |
| 1822 HashSet<Source> changedSources = new HashSet<Source>(); | 1822 HashSet<Source> changedSources = new HashSet<Source>(); |
| 1823 HashSet<Source> missingSources = new HashSet<Source>(); | 1823 HashSet<Source> missingSources = new HashSet<Source>(); |
| 1824 MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator(); | 1824 MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator(); |
| 1825 while (iterator.moveNext()) { | 1825 while (iterator.moveNext()) { |
| 1826 Source source = iterator.key.source; | 1826 Source source = iterator.key.source; |
| 1827 if (source != null) { | 1827 if (source != null) { |
| 1828 cache.CacheEntry entry = iterator.value; | 1828 CacheEntry entry = iterator.value; |
| 1829 int sourceTime = getModificationStamp(source); | 1829 int sourceTime = getModificationStamp(source); |
| 1830 if (sourceTime != entry.modificationTime) { | 1830 if (sourceTime != entry.modificationTime) { |
| 1831 changedSources.add(source); | 1831 changedSources.add(source); |
| 1832 } | 1832 } |
| 1833 if (entry.exception != null) { | 1833 if (entry.exception != null) { |
| 1834 if (!exists(source)) { | 1834 if (!exists(source)) { |
| 1835 missingSources.add(source); | 1835 missingSources.add(source); |
| 1836 } | 1836 } |
| 1837 } | 1837 } |
| 1838 } | 1838 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 } | 1873 } |
| 1874 | 1874 |
| 1875 /** | 1875 /** |
| 1876 * An object that manages the partitions that can be shared between analysis | 1876 * An object that manages the partitions that can be shared between analysis |
| 1877 * contexts. | 1877 * contexts. |
| 1878 */ | 1878 */ |
| 1879 class PartitionManager { | 1879 class PartitionManager { |
| 1880 /** | 1880 /** |
| 1881 * A table mapping SDK's to the partitions used for those SDK's. | 1881 * A table mapping SDK's to the partitions used for those SDK's. |
| 1882 */ | 1882 */ |
| 1883 HashMap<DartSdk, cache.SdkCachePartition> _sdkPartitions = | 1883 HashMap<DartSdk, SdkCachePartition> _sdkPartitions = |
| 1884 new HashMap<DartSdk, cache.SdkCachePartition>(); | 1884 new HashMap<DartSdk, SdkCachePartition>(); |
| 1885 | 1885 |
| 1886 /** | 1886 /** |
| 1887 * Clear any cached data being maintained by this manager. | 1887 * Clear any cached data being maintained by this manager. |
| 1888 */ | 1888 */ |
| 1889 void clearCache() { | 1889 void clearCache() { |
| 1890 _sdkPartitions.clear(); | 1890 _sdkPartitions.clear(); |
| 1891 } | 1891 } |
| 1892 | 1892 |
| 1893 /** | 1893 /** |
| 1894 * Return the partition being used for the given [sdk], creating the partition | 1894 * Return the partition being used for the given [sdk], creating the partition |
| 1895 * if necessary. | 1895 * if necessary. |
| 1896 */ | 1896 */ |
| 1897 cache.SdkCachePartition forSdk(DartSdk sdk) { | 1897 SdkCachePartition forSdk(DartSdk sdk) { |
| 1898 // Call sdk.context now, because when it creates a new | 1898 // Call sdk.context now, because when it creates a new |
| 1899 // InternalAnalysisContext instance, it calls forSdk() again, so creates an | 1899 // InternalAnalysisContext instance, it calls forSdk() again, so creates an |
| 1900 // SdkCachePartition instance. | 1900 // SdkCachePartition instance. |
| 1901 // So, if we initialize context after "partition == null", we end up | 1901 // So, if we initialize context after "partition == null", we end up |
| 1902 // with two SdkCachePartition instances. | 1902 // with two SdkCachePartition instances. |
| 1903 InternalAnalysisContext sdkContext = sdk.context; | 1903 InternalAnalysisContext sdkContext = sdk.context; |
| 1904 // Check cache for an existing partition. | 1904 // Check cache for an existing partition. |
| 1905 cache.SdkCachePartition partition = _sdkPartitions[sdk]; | 1905 SdkCachePartition partition = _sdkPartitions[sdk]; |
| 1906 if (partition == null) { | 1906 if (partition == null) { |
| 1907 partition = new cache.SdkCachePartition(sdkContext); | 1907 partition = new SdkCachePartition(sdkContext); |
| 1908 _sdkPartitions[sdk] = partition; | 1908 _sdkPartitions[sdk] = partition; |
| 1909 } | 1909 } |
| 1910 return partition; | 1910 return partition; |
| 1911 } | 1911 } |
| 1912 } | 1912 } |
| 1913 | 1913 |
| 1914 /** | 1914 /** |
| 1915 * Representation of a pending computation which is based on the results of | 1915 * Representation of a pending computation which is based on the results of |
| 1916 * analysis that may or may not have been completed. | 1916 * analysis that may or may not have been completed. |
| 1917 */ | 1917 */ |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 * the pending future if it's appropriate to do so. If the pending future is | 1951 * the pending future if it's appropriate to do so. If the pending future is |
| 1952 * completed by this call, true is returned; otherwise false is returned. | 1952 * completed by this call, true is returned; otherwise false is returned. |
| 1953 * | 1953 * |
| 1954 * Once this function has returned true, it should not be called again. | 1954 * Once this function has returned true, it should not be called again. |
| 1955 * | 1955 * |
| 1956 * Other than completing the future, this method is free of side effects. | 1956 * Other than completing the future, this method is free of side effects. |
| 1957 * Note that any code the client has attached to the future will be executed | 1957 * Note that any code the client has attached to the future will be executed |
| 1958 * in a microtask, so there is no danger of side effects occurring due to | 1958 * in a microtask, so there is no danger of side effects occurring due to |
| 1959 * client callbacks. | 1959 * client callbacks. |
| 1960 */ | 1960 */ |
| 1961 bool evaluate(cache.CacheEntry entry) { | 1961 bool evaluate(CacheEntry entry) { |
| 1962 assert(!_completer.isCompleted); | 1962 assert(!_completer.isCompleted); |
| 1963 try { | 1963 try { |
| 1964 T result = _computeValue(entry); | 1964 T result = _computeValue(entry); |
| 1965 if (result == null) { | 1965 if (result == null) { |
| 1966 return false; | 1966 return false; |
| 1967 } else { | 1967 } else { |
| 1968 _completer.complete(result); | 1968 _completer.complete(result); |
| 1969 return true; | 1969 return true; |
| 1970 } | 1970 } |
| 1971 } catch (exception, stackTrace) { | 1971 } catch (exception, stackTrace) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 * | 2011 * |
| 2012 * If the [computeValue] still returns `null` after there is no further | 2012 * If the [computeValue] still returns `null` after there is no further |
| 2013 * analysis to be done for [target], then the future will be completed with | 2013 * analysis to be done for [target], then the future will be completed with |
| 2014 * the error AnalysisNotScheduledError. | 2014 * the error AnalysisNotScheduledError. |
| 2015 * | 2015 * |
| 2016 * Since [computeValue] will be called while the state of analysis is being | 2016 * Since [computeValue] will be called while the state of analysis is being |
| 2017 * updated, it should be free of side effects so that it doesn't cause | 2017 * updated, it should be free of side effects so that it doesn't cause |
| 2018 * reentrant changes to the analysis state. | 2018 * reentrant changes to the analysis state. |
| 2019 */ | 2019 */ |
| 2020 CancelableFuture<T> computeAsync( | 2020 CancelableFuture<T> computeAsync( |
| 2021 AnalysisTarget target, T computeValue(cache.CacheEntry entry)) { | 2021 AnalysisTarget target, T computeValue(CacheEntry entry)) { |
| 2022 if (_context.isDisposed) { | 2022 if (_context.isDisposed) { |
| 2023 // No further analysis is expected, so return a future that completes | 2023 // No further analysis is expected, so return a future that completes |
| 2024 // immediately with AnalysisNotScheduledError. | 2024 // immediately with AnalysisNotScheduledError. |
| 2025 return new CancelableFuture.error(new AnalysisNotScheduledError()); | 2025 return new CancelableFuture.error(new AnalysisNotScheduledError()); |
| 2026 } | 2026 } |
| 2027 cache.CacheEntry entry = _context.getReadableSourceEntryOrNull(target); | 2027 CacheEntry entry = _context.getReadableSourceEntryOrNull(target); |
| 2028 if (entry == null) { | 2028 if (entry == null) { |
| 2029 return new CancelableFuture.error(new AnalysisNotScheduledError()); | 2029 return new CancelableFuture.error(new AnalysisNotScheduledError()); |
| 2030 } | 2030 } |
| 2031 PendingFuture pendingFuture = | 2031 PendingFuture pendingFuture = |
| 2032 new PendingFuture<T>(_context, target, computeValue); | 2032 new PendingFuture<T>(_context, target, computeValue); |
| 2033 if (!pendingFuture.evaluate(entry)) { | 2033 if (!pendingFuture.evaluate(entry)) { |
| 2034 _context._pendingFutureTargets | 2034 _context._pendingFutureTargets |
| 2035 .putIfAbsent(target, () => <PendingFuture>[]) | 2035 .putIfAbsent(target, () => <PendingFuture>[]) |
| 2036 .add(pendingFuture); | 2036 .add(pendingFuture); |
| 2037 } | 2037 } |
| 2038 return pendingFuture.future; | 2038 return pendingFuture.future; |
| 2039 } | 2039 } |
| 2040 } | 2040 } |
| OLD | NEW |