| 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;
|
| + }
|
| }
|
|
|
| /**
|
|
|