Index: pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart |
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart |
index 602503e789842eda3251958ee1ae8fc44ce2fbc3..5cfdacef0120bf9de9db13431207ad612a3c9b19 100644 |
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart |
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart |
@@ -25,10 +25,12 @@ import 'package:analyzer/src/context/context.dart' |
show AnalysisFutureHelper, AnalysisContextImpl; |
import 'package:analyzer/src/generated/ast.dart'; |
import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl; |
+import 'package:analyzer/src/generated/java_engine.dart'; |
import 'package:analyzer/src/generated/scanner.dart'; |
import 'package:analyzer/src/generated/source.dart'; |
import 'package:analyzer/src/task/dart.dart'; |
import 'package:analyzer/task/dart.dart'; |
+import 'package:analyzer/task/model.dart'; |
/** |
* [DartCompletionManager] determines if a completion request is Dart specific |
@@ -44,17 +46,15 @@ class DartCompletionManager implements CompletionContributor { |
@override |
Future<List<CompletionSuggestion>> computeSuggestions( |
CompletionRequest request) async { |
+ request.checkAborted(); |
if (!AnalysisEngine.isDartFileName(request.source.shortName)) { |
return EMPTY_LIST; |
} |
CompletionPerformance performance = |
(request as CompletionRequestImpl).performance; |
- const BUILD_REQUEST_TAG = 'build DartCompletionRequestImpl'; |
- performance.logStartTime(BUILD_REQUEST_TAG); |
DartCompletionRequestImpl dartRequest = |
await DartCompletionRequestImpl.from(request); |
- performance.logElapseTime(BUILD_REQUEST_TAG); |
// Don't suggest in comments. |
if (dartRequest.target.isCommentText) { |
@@ -78,6 +78,7 @@ class DartCompletionManager implements CompletionContributor { |
List<CompletionSuggestion> contributorSuggestions = |
await contributor.computeSuggestions(dartRequest); |
performance.logElapseTime(contributorTag); |
+ request.checkAborted(); |
for (CompletionSuggestion newSuggestion in contributorSuggestions) { |
var oldSuggestion = suggestionMap.putIfAbsent( |
@@ -95,6 +96,7 @@ class DartCompletionManager implements CompletionContributor { |
performance.logStartTime(SORT_TAG); |
await contributionSorter.sort(dartRequest, suggestions); |
performance.logElapseTime(SORT_TAG); |
+ request.checkAborted(); |
return suggestions; |
} |
} |
@@ -139,6 +141,8 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
OpType _opType; |
+ final CompletionRequest _originalRequest; |
+ |
final CompletionPerformance performance; |
DartCompletionRequestImpl._( |
@@ -149,6 +153,7 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
this.source, |
this.offset, |
CompilationUnit unit, |
+ this._originalRequest, |
this.performance) { |
_updateTargets(unit); |
} |
@@ -200,26 +205,35 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
return _opType; |
} |
+ /** |
+ * Throw [AbortCompletion] if the completion request has been aborted. |
+ */ |
+ void checkAborted() { |
+ _originalRequest.checkAborted(); |
+ } |
+ |
// For internal use only |
@override |
Future<List<Directive>> resolveDirectives() async { |
+ checkAborted(); |
+ |
CompilationUnit libUnit; |
if (librarySource != null) { |
// TODO(danrubel) only resolve the directives |
- const RESOLVE_DIRECTIVES_TAG = 'resolve directives'; |
- performance.logStartTime(RESOLVE_DIRECTIVES_TAG); |
- libUnit = await new AnalysisFutureHelper<CompilationUnit>( |
- context, |
- new LibrarySpecificUnit(librarySource, librarySource), |
- RESOLVED_UNIT3) |
- .computeAsync(); |
- performance.logElapseTime(RESOLVE_DIRECTIVES_TAG); |
+ libUnit = await _computeAsync( |
+ this, |
+ new LibrarySpecificUnit(librarySource, librarySource), |
+ RESOLVED_UNIT3, |
+ performance, |
+ 'resolve directives'); |
} |
return libUnit?.directives; |
} |
@override |
Future resolveExpression(Expression expression) async { |
+ checkAborted(); |
+ |
// Return immediately if the expression has already been resolved |
if (expression.propagatedType != null) { |
return; |
@@ -233,13 +247,12 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
// Resolve declarations in the target unit |
// TODO(danrubel) resolve the expression or containing method |
// rather than the entire complilation unit |
- const RESOLVE_EXPRESSION_TAG = 'resolve expression'; |
- performance.logStartTime(RESOLVE_EXPRESSION_TAG); |
- CompilationUnit resolvedUnit = |
- await new AnalysisFutureHelper<CompilationUnit>(context, |
- new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT) |
- .computeAsync(); |
- performance.logElapseTime(RESOLVE_EXPRESSION_TAG); |
+ CompilationUnit resolvedUnit = await _computeAsync( |
+ this, |
+ new LibrarySpecificUnit(librarySource, source), |
+ RESOLVED_UNIT, |
+ performance, |
+ 'resolve expression'); |
// TODO(danrubel) determine if the underlying source has been modified |
// in a way that invalidates the completion request |
@@ -285,9 +298,11 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
/** |
* Return a [Future] that completes with a newly created completion request |
- * based on the given [request]. |
+ * based on the given [request]. This method will throw [AbortCompletion] |
+ * if the completion request has been aborted. |
*/ |
static Future<DartCompletionRequest> from(CompletionRequest request) async { |
+ request.checkAborted(); |
CompletionPerformance performance = |
(request as CompletionRequestImpl).performance; |
const BUILD_REQUEST_TAG = 'build DartCompletionRequest'; |
@@ -313,12 +328,12 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
// Most (all?) contributors need declarations in scope to be resolved |
if (libSource != null) { |
- const RESOLVE_DECLARATIONS_TAG = 'resolve declarations'; |
- performance.logStartTime(RESOLVE_DECLARATIONS_TAG); |
- unit = await new AnalysisFutureHelper<CompilationUnit>(context, |
- new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3) |
- .computeAsync(); |
- performance.logElapseTime(RESOLVE_DECLARATIONS_TAG); |
+ unit = await _computeAsync( |
+ request, |
+ new LibrarySpecificUnit(libSource, source), |
+ RESOLVED_UNIT3, |
+ performance, |
+ 'resolve declarations'); |
} |
DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._( |
@@ -329,6 +344,7 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
request.source, |
request.offset, |
unit, |
+ request, |
performance); |
// Resolve the expression in which the completion occurs |
@@ -341,12 +357,33 @@ class DartCompletionRequestImpl implements DartCompletionRequest { |
performance.logStartTime(FUNCTIONAL_ARG_TAG); |
await dartRequest.resolveExpression(node); |
performance.logElapseTime(FUNCTIONAL_ARG_TAG); |
+ dartRequest.checkAborted(); |
} |
} |
performance.logElapseTime(BUILD_REQUEST_TAG); |
return dartRequest; |
} |
+ |
+ static Future _computeAsync(CompletionRequest request, AnalysisTarget target, |
+ ResultDescriptor descriptor, CompletionPerformance performance, String perfTag) async { |
+ request.checkAborted(); |
+ performance.logStartTime(perfTag); |
+ var result; |
+ try { |
+ result = |
+ await new AnalysisFutureHelper(request.context, target, descriptor) |
+ .computeAsync(); |
+ } catch (e, s) { |
+ if (e is AnalysisNotScheduledError) { |
+ request.checkAborted(); |
+ } |
+ throw new AnalysisException( |
+ 'failed to $perfTag', new CaughtException(e, s)); |
+ } |
+ request.checkAborted(); |
+ return result; |
+ } |
} |
/** |