Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: pkg/analyzer/lib/src/generated/engine.dart

Issue 806733003: Make futures returned by AnalysisContext cancelable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine; 8 library engine;
9 9
10 import "dart:math" as math; 10 import "dart:math" as math;
11 import 'dart:async'; 11 import 'dart:async';
12 import 'dart:collection'; 12 import 'dart:collection';
13 13
14 import 'package:analyzer/src/cancelable_future.dart';
14 import 'package:analyzer/src/task/task_dart.dart'; 15 import 'package:analyzer/src/task/task_dart.dart';
15 16
16 import '../../instrumentation/instrumentation.dart'; 17 import '../../instrumentation/instrumentation.dart';
17 import 'ast.dart'; 18 import 'ast.dart';
18 import 'constant.dart'; 19 import 'constant.dart';
19 import 'element.dart'; 20 import 'element.dart';
20 import 'error.dart'; 21 import 'error.dart';
21 import 'error_verifier.dart'; 22 import 'error_verifier.dart';
22 import 'html.dart' as ht; 23 import 'html.dart' as ht;
23 import 'incremental_resolver.dart' show IncrementalResolver, 24 import 'incremental_resolver.dart' show IncrementalResolver,
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 * Return a future which will be completed with the fully resolved AST for a 752 * Return a future which will be completed with the fully resolved AST for a
752 * single compilation unit within the given library, once that AST is up to 753 * single compilation unit within the given library, once that AST is up to
753 * date. 754 * date.
754 * 755 *
755 * If the resolved AST can't be computed for some reason, the future will be 756 * If the resolved AST can't be computed for some reason, the future will be
756 * completed with an error. One possible error is AnalysisNotScheduledError, 757 * completed with an error. One possible error is AnalysisNotScheduledError,
757 * which means that the resolved AST can't be computed because the given 758 * which means that the resolved AST can't be computed because the given
758 * source file is not scheduled to be analyzed within the context of the 759 * source file is not scheduled to be analyzed within the context of the
759 * given library. 760 * given library.
760 */ 761 */
761 Future<CompilationUnit> getResolvedCompilationUnitFuture(Source source, 762 CancelableFuture<CompilationUnit>
762 Source librarySource); 763 getResolvedCompilationUnitFuture(Source source, Source librarySource);
763 764
764 /** 765 /**
765 * Return a fully resolved HTML unit, or `null` if the resolved unit is not al ready 766 * Return a fully resolved HTML unit, or `null` if the resolved unit is not al ready
766 * computed. 767 * computed.
767 * 768 *
768 * @param htmlSource the source of the HTML unit 769 * @param htmlSource the source of the HTML unit
769 * @return a fully resolved HTML unit 770 * @return a fully resolved HTML unit
770 * See [resolveHtmlUnit]. 771 * See [resolveHtmlUnit].
771 */ 772 */
772 ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource); 773 ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource);
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 // to complete. 1320 // to complete.
1320 return WaitForAsyncTask.instance; 1321 return WaitForAsyncTask.instance;
1321 } 1322 }
1322 return null; 1323 return null;
1323 } 1324 }
1324 1325
1325 @override 1326 @override
1326 Stream<SourcesChangedEvent> get onSourcesChanged => 1327 Stream<SourcesChangedEvent> get onSourcesChanged =>
1327 _onSourcesChangedController.stream; 1328 _onSourcesChangedController.stream;
1328 1329
1330 /**
1331 * Make _pendingFutureSources available to unit tests.
1332 */
1333 HashMap<Source, List<PendingFuture>> get pendingFutureSources_forTesting =>
1334 _pendingFutureSources;
1335
1329 @override 1336 @override
1330 List<Source> get prioritySources => _priorityOrder; 1337 List<Source> get prioritySources => _priorityOrder;
1331 1338
1332 @override 1339 @override
1333 List<Source> get refactoringUnsafeSources { 1340 List<Source> get refactoringUnsafeSources {
1334 List<Source> sources = new List<Source>(); 1341 List<Source> sources = new List<Source>();
1335 MapIterator<Source, SourceEntry> iterator = _cache.iterator(); 1342 MapIterator<Source, SourceEntry> iterator = _cache.iterator();
1336 while (iterator.moveNext()) { 1343 while (iterator.moveNext()) {
1337 SourceEntry sourceEntry = iterator.value; 1344 SourceEntry sourceEntry = iterator.value;
1338 if (sourceEntry is DartEntry) { 1345 if (sourceEntry is DartEntry) {
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 SourceEntry sourceEntry = getReadableSourceEntryOrNull(unitSource); 2075 SourceEntry sourceEntry = getReadableSourceEntryOrNull(unitSource);
2069 if (sourceEntry is DartEntry) { 2076 if (sourceEntry is DartEntry) {
2070 return sourceEntry.getValueInLibrary( 2077 return sourceEntry.getValueInLibrary(
2071 DartEntry.RESOLVED_UNIT, 2078 DartEntry.RESOLVED_UNIT,
2072 librarySource); 2079 librarySource);
2073 } 2080 }
2074 return null; 2081 return null;
2075 } 2082 }
2076 2083
2077 @override 2084 @override
2078 Future<CompilationUnit> getResolvedCompilationUnitFuture(Source unitSource, 2085 CancelableFuture<CompilationUnit>
2079 Source librarySource) { 2086 getResolvedCompilationUnitFuture(Source unitSource, Source librarySource) {
2080 return _getFuture(unitSource, (SourceEntry sourceEntry) { 2087 return new _AnalysisFutureHelper<CompilationUnit>(
2088 this).getFuture(unitSource, (SourceEntry sourceEntry) {
2081 if (sourceEntry is DartEntry) { 2089 if (sourceEntry is DartEntry) {
2082 if (sourceEntry.getStateInLibrary( 2090 if (sourceEntry.getStateInLibrary(
2083 DartEntry.RESOLVED_UNIT, 2091 DartEntry.RESOLVED_UNIT,
2084 librarySource) == 2092 librarySource) ==
2085 CacheState.ERROR) { 2093 CacheState.ERROR) {
2086 throw sourceEntry.exception; 2094 throw sourceEntry.exception;
2087 } 2095 }
2088 return sourceEntry.getValueInLibrary( 2096 return sourceEntry.getValueInLibrary(
2089 DartEntry.RESOLVED_UNIT, 2097 DartEntry.RESOLVED_UNIT,
2090 librarySource); 2098 librarySource);
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
2875 source, 2883 source,
2876 htmlEntry.modificationTime, 2884 htmlEntry.modificationTime,
2877 htmlEntry.getValue( 2885 htmlEntry.getValue(
2878 HtmlEntry.PARSED_UNIT)).perform(_resultRecorder) as HtmlEntry; 2886 HtmlEntry.PARSED_UNIT)).perform(_resultRecorder) as HtmlEntry;
2879 state = htmlEntry.getState(descriptor); 2887 state = htmlEntry.getState(descriptor);
2880 } 2888 }
2881 return htmlEntry; 2889 return htmlEntry;
2882 } 2890 }
2883 2891
2884 /** 2892 /**
2893 * Remove the given [pendingFuture] from [_pendingFutureSources], since the
2894 * client has indicated its computation is not needed anymore.
2895 */
2896 void _cancelFuture(PendingFuture pendingFuture) {
2897 List<PendingFuture> pendingFutures =
2898 _pendingFutureSources[pendingFuture.source];
2899 if (pendingFutures != null) {
2900 pendingFutures.remove(pendingFuture);
2901 if (pendingFutures.isEmpty) {
2902 _pendingFutureSources.remove(pendingFuture.source);
2903 }
2904 }
2905 }
2906
2907 /**
2885 * Compute the transitive closure of all libraries that depend on the given li brary by adding such 2908 * Compute the transitive closure of all libraries that depend on the given li brary by adding such
2886 * libraries to the given collection. 2909 * libraries to the given collection.
2887 * 2910 *
2888 * @param library the library on which the other libraries depend 2911 * @param library the library on which the other libraries depend
2889 * @param librariesToInvalidate the libraries that depend on the given library 2912 * @param librariesToInvalidate the libraries that depend on the given library
2890 */ 2913 */
2891 void _computeAllLibrariesDependingOn(Source library, 2914 void _computeAllLibrariesDependingOn(Source library,
2892 HashSet<Source> librariesToInvalidate) { 2915 HashSet<Source> librariesToInvalidate) {
2893 if (librariesToInvalidate.add(library)) { 2916 if (librariesToInvalidate.add(library)) {
2894 for (Source dependentLibrary in getLibrariesDependingOn(library)) { 2917 for (Source dependentLibrary in getLibrariesDependingOn(library)) {
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
3620 * resolved 3643 * resolved
3621 */ 3644 */
3622 Object _getDartVerificationData(Source unitSource, Source librarySource, 3645 Object _getDartVerificationData(Source unitSource, Source librarySource,
3623 DartEntry dartEntry, DataDescriptor descriptor) { 3646 DartEntry dartEntry, DataDescriptor descriptor) {
3624 dartEntry = 3647 dartEntry =
3625 _cacheDartVerificationData(unitSource, librarySource, dartEntry, descrip tor); 3648 _cacheDartVerificationData(unitSource, librarySource, dartEntry, descrip tor);
3626 return dartEntry.getValueInLibrary(descriptor, librarySource); 3649 return dartEntry.getValueInLibrary(descriptor, librarySource);
3627 } 3650 }
3628 3651
3629 /** 3652 /**
3630 * Return a future that will be completed with the result of calling
3631 * [computeValue]. If [computeValue] returns non-null, the future will be
3632 * completed immediately with the resulting value. If it returns null, then
3633 * it will be re-executed in the future, after the next time the cached
3634 * information for [source] has changed. If [computeValue] throws an
3635 * exception, the future will fail with that exception.
3636 *
3637 * If the [computeValue] still returns null after there is no further
3638 * analysis to be done for [source], then the future will be completed with
3639 * the error AnalysisNotScheduledError.
3640 *
3641 * Since [computeValue] will be called while the state of analysis is being
3642 * updated, it should be free of side effects so that it doesn't cause
3643 * reentrant changes to the analysis state.
3644 */
3645 Future /*<T>*/ _getFuture(Source source, /*T*/
3646 computeValue(SourceEntry sourceEntry)) {
3647 SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
3648 if (sourceEntry == null) {
3649 return new Future.error(new AnalysisNotScheduledError());
3650 }
3651 PendingFuture pendingFuture = new PendingFuture(computeValue);
3652 if (!pendingFuture.evaluate(sourceEntry)) {
3653 _pendingFutureSources.putIfAbsent(
3654 source,
3655 () => <PendingFuture>[]).add(pendingFuture);
3656 }
3657 return pendingFuture.future;
3658 }
3659
3660 /**
3661 * Given a source for an HTML file, return the data represented by the given d escriptor that is 3653 * Given a source for an HTML file, return the data represented by the given d escriptor that is
3662 * associated with that source, or the given default value if the source is no t an HTML file. This 3654 * associated with that source, or the given default value if the source is no t an HTML file. This
3663 * method assumes that the data can be produced by parsing the source if it is not already cached. 3655 * method assumes that the data can be produced by parsing the source if it is not already cached.
3664 * 3656 *
3665 * <b>Note:</b> This method cannot be used in an async environment. 3657 * <b>Note:</b> This method cannot be used in an async environment.
3666 * 3658 *
3667 * @param source the source representing the Dart file 3659 * @param source the source representing the Dart file
3668 * @param descriptor the descriptor representing the data to be returned 3660 * @param descriptor the descriptor representing the data to be returned
3669 * @param defaultValue the value to be returned if the source is not an HTML f ile 3661 * @param defaultValue the value to be returned if the source is not an HTML f ile
3670 * @return the requested data about the given source 3662 * @return the requested data about the given source
(...skipping 5981 matching lines...) Expand 10 before | Expand all | Expand 10 after
9652 /** 9644 /**
9653 * Initialize a newly created descriptor to have the given [name] and 9645 * Initialize a newly created descriptor to have the given [name] and
9654 * [defaultValue]. 9646 * [defaultValue].
9655 */ 9647 */
9656 DataDescriptor(this._name, [this.defaultValue = null]); 9648 DataDescriptor(this._name, [this.defaultValue = null]);
9657 9649
9658 @override 9650 @override
9659 String toString() => _name; 9651 String toString() => _name;
9660 } 9652 }
9661 9653
9662
9663 /** 9654 /**
9664 * Instances of the class `DefaultRetentionPolicy` implement a retention policy that will keep 9655 * Instances of the class `DefaultRetentionPolicy` implement a retention policy that will keep
9665 * AST's in the cache if there is analysis information that needs to be computed for a source, where 9656 * AST's in the cache if there is analysis information that needs to be computed for a source, where
9666 * the computation is dependent on having the AST. 9657 * the computation is dependent on having the AST.
9667 */ 9658 */
9668 class DefaultRetentionPolicy implements CacheRetentionPolicy { 9659 class DefaultRetentionPolicy implements CacheRetentionPolicy {
9669 /** 9660 /**
9670 * An instance of this class that can be shared. 9661 * An instance of this class that can be shared.
9671 */ 9662 */
9672 static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy(); 9663 static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
(...skipping 15 matching lines...) Expand all
9688 if (sourceEntry is DartEntry) { 9679 if (sourceEntry is DartEntry) {
9689 DartEntry dartEntry = sourceEntry; 9680 DartEntry dartEntry = sourceEntry;
9690 if (astIsNeeded(dartEntry)) { 9681 if (astIsNeeded(dartEntry)) {
9691 return RetentionPriority.MEDIUM; 9682 return RetentionPriority.MEDIUM;
9692 } 9683 }
9693 } 9684 }
9694 return RetentionPriority.LOW; 9685 return RetentionPriority.LOW;
9695 } 9686 }
9696 } 9687 }
9697 9688
9689
9698 /** 9690 /**
9699 * Recursively visits [HtmlUnit] and every embedded [Expression]. 9691 * Recursively visits [HtmlUnit] and every embedded [Expression].
9700 */ 9692 */
9701 abstract class ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> { 9693 abstract class ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> {
9702 /** 9694 /**
9703 * Visits the given [Expression]s embedded into tag or attribute. 9695 * Visits the given [Expression]s embedded into tag or attribute.
9704 * 9696 *
9705 * @param expression the [Expression] to visit, not `null` 9697 * @param expression the [Expression] to visit, not `null`
9706 */ 9698 */
9707 void visitExpression(Expression expression); 9699 void visitExpression(Expression expression);
(...skipping 1955 matching lines...) Expand 10 before | Expand all | Expand 10 after
11663 return partition; 11655 return partition;
11664 } 11656 }
11665 } 11657 }
11666 11658
11667 /** 11659 /**
11668 * Representation of a pending computation which is based on the results of 11660 * Representation of a pending computation which is based on the results of
11669 * analysis that may or may not have been completed. 11661 * analysis that may or may not have been completed.
11670 */ 11662 */
11671 class PendingFuture<T> { 11663 class PendingFuture<T> {
11672 /** 11664 /**
11665 * The context in which this computation runs.
11666 */
11667 final AnalysisContextImpl _context;
11668
11669 /**
11670 * The source used by this computation to compute its value.
11671 */
11672 final Source source;
11673
11674 /**
11673 * The function which implements the computation. 11675 * The function which implements the computation.
11674 */ 11676 */
11675 final PendingFutureComputer<T> _computeValue; 11677 final PendingFutureComputer<T> _computeValue;
11676 11678
11677 /** 11679 /**
11678 * The completer that should be completed once the computation has succeeded. 11680 * The completer that should be completed once the computation has succeeded.
11679 */ 11681 */
11680 final Completer<T> _completer = new Completer<T>(); 11682 CancelableCompleter<T> _completer;
11681 11683
11682 PendingFuture(this._computeValue); 11684 PendingFuture(this._context, this.source, this._computeValue) {
11685 _completer = new CancelableCompleter<T>(_onCancel);
11686 }
11683 11687
11684 /** 11688 /**
11685 * Retrieve the future which will be completed when this object is 11689 * Retrieve the future which will be completed when this object is
11686 * successfully evaluated. 11690 * successfully evaluated.
11687 */ 11691 */
11688 Future<T> get future => _completer.future; 11692 CancelableFuture<T> get future => _completer.future;
11689 11693
11690 /** 11694 /**
11691 * Execute [_computeValue], passing it the given [sourceEntry], and complete 11695 * Execute [_computeValue], passing it the given [sourceEntry], and complete
11692 * the pending future if it's appropriate to do so. If the pending future is 11696 * the pending future if it's appropriate to do so. If the pending future is
11693 * completed by this call, true is returned; otherwise false is returned. 11697 * completed by this call, true is returned; otherwise false is returned.
11694 * 11698 *
11695 * Once this function has returned true, it should not be called again. 11699 * Once this function has returned true, it should not be called again.
11696 * 11700 *
11697 * Other than completing the future, this method is free of side effects. 11701 * Other than completing the future, this method is free of side effects.
11698 * Note that any code the client has attached to the future will be executed 11702 * Note that any code the client has attached to the future will be executed
(...skipping 21 matching lines...) Expand all
11720 * complete it with an AnalysisNotScheduledError in order to avoid 11724 * complete it with an AnalysisNotScheduledError in order to avoid
11721 * deadlocking the client. 11725 * deadlocking the client.
11722 */ 11726 */
11723 void forciblyComplete() { 11727 void forciblyComplete() {
11724 try { 11728 try {
11725 throw new AnalysisNotScheduledError(); 11729 throw new AnalysisNotScheduledError();
11726 } catch (exception, stackTrace) { 11730 } catch (exception, stackTrace) {
11727 _completer.completeError(exception, stackTrace); 11731 _completer.completeError(exception, stackTrace);
11728 } 11732 }
11729 } 11733 }
11734
11735 void _onCancel() {
11736 _context._cancelFuture(this);
11737 }
11730 } 11738 }
11731 11739
11732 /** 11740 /**
11733 * Container with global [AnalysisContext] performance statistics. 11741 * Container with global [AnalysisContext] performance statistics.
11734 */ 11742 */
11735 class PerformanceStatistics { 11743 class PerformanceStatistics {
11736 /** 11744 /**
11737 * The [TimeCounter] for time spent in reading files. 11745 * The [TimeCounter] for time spent in reading files.
11738 */ 11746 */
11739 static TimeCounter io = new TimeCounter(); 11747 static TimeCounter io = new TimeCounter();
(...skipping 2572 matching lines...) Expand 10 before | Expand all | Expand 10 after
14312 _index = 0; 14320 _index = 0;
14313 _queueIndex++; 14321 _queueIndex++;
14314 while (_queueIndex < _manager._workQueues.length && 14322 while (_queueIndex < _manager._workQueues.length &&
14315 _manager._workQueues[_queueIndex].isEmpty) { 14323 _manager._workQueues[_queueIndex].isEmpty) {
14316 _queueIndex++; 14324 _queueIndex++;
14317 } 14325 }
14318 } 14326 }
14319 } 14327 }
14320 } 14328 }
14321 14329
14330 /**
14331 * Helper class used to create futures for AnalysisContextImpl. Using a helper
14332 * class allows us to preserve the generic parameter T.
14333 */
14334 class _AnalysisFutureHelper<T> {
14335 final AnalysisContextImpl _context;
14336
14337 _AnalysisFutureHelper(this._context);
14338
14339 /**
14340 * Return a future that will be completed with the result of calling
14341 * [computeValue]. If [computeValue] returns non-null, the future will be
14342 * completed immediately with the resulting value. If it returns null, then
14343 * it will be re-executed in the future, after the next time the cached
14344 * information for [source] has changed. If [computeValue] throws an
14345 * exception, the future will fail with that exception.
14346 *
14347 * If the [computeValue] still returns null after there is no further
14348 * analysis to be done for [source], then the future will be completed with
14349 * the error AnalysisNotScheduledError.
14350 *
14351 * Since [computeValue] will be called while the state of analysis is being
14352 * updated, it should be free of side effects so that it doesn't cause
14353 * reentrant changes to the analysis state.
14354 */
14355 CancelableFuture<T> getFuture(Source source, T
14356 computeValue(SourceEntry sourceEntry)) {
14357 SourceEntry sourceEntry = _context.getReadableSourceEntryOrNull(source);
14358 if (sourceEntry == null) {
14359 return new CancelableFuture.error(new AnalysisNotScheduledError());
14360 }
14361 PendingFuture pendingFuture =
14362 new PendingFuture<T>(_context, source, computeValue);
14363 if (!pendingFuture.evaluate(sourceEntry)) {
14364 _context._pendingFutureSources.putIfAbsent(
14365 source,
14366 () => <PendingFuture>[]).add(pendingFuture);
14367 }
14368 return pendingFuture.future;
14369 }
14370 }
14371
14322 class _AngularHtmlUnitResolver_visitModelDirectives extends 14372 class _AngularHtmlUnitResolver_visitModelDirectives extends
14323 ht.RecursiveXmlVisitor<Object> { 14373 ht.RecursiveXmlVisitor<Object> {
14324 final AngularHtmlUnitResolver resolver; 14374 final AngularHtmlUnitResolver resolver;
14325 14375
14326 _AngularHtmlUnitResolver_visitModelDirectives(this.resolver) 14376 _AngularHtmlUnitResolver_visitModelDirectives(this.resolver)
14327 : super(); 14377 : super();
14328 14378
14329 @override 14379 @override
14330 Object visitXmlTagNode(ht.XmlTagNode node) { 14380 Object visitXmlTagNode(ht.XmlTagNode node) {
14331 NgModelProcessor directive = NgModelProcessor.INSTANCE; 14381 NgModelProcessor directive = NgModelProcessor.INSTANCE;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
14364 14414
14365 @override 14415 @override
14366 Object visitPolymerTagDartElement(PolymerTagDartElement element) { 14416 Object visitPolymerTagDartElement(PolymerTagDartElement element) {
14367 if (element.name == PolymerHtmlUnitBuilder_this._elementName) { 14417 if (element.name == PolymerHtmlUnitBuilder_this._elementName) {
14368 throw new PolymerHtmlUnitBuilder_FoundTagDartElementError( 14418 throw new PolymerHtmlUnitBuilder_FoundTagDartElementError(
14369 element as PolymerTagDartElementImpl); 14419 element as PolymerTagDartElementImpl);
14370 } 14420 }
14371 return null; 14421 return null;
14372 } 14422 }
14373 } 14423 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698