Index: pkg/analysis_server/lib/src/domain_completion.dart |
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart |
index 8810ff6ae8b3f7e8047a5638e0302bbadb9d48fb..f9ea745ddb21eb2c44f30ba53c7a6ac928690b86 100644 |
--- a/pkg/analysis_server/lib/src/domain_completion.dart |
+++ b/pkg/analysis_server/lib/src/domain_completion.dart |
@@ -53,12 +53,17 @@ class CompletionDomainHandler implements RequestHandler { |
CompletionPerformance computeCachePerformance; |
/** |
+ * The current request being processed or `null` if none. |
+ */ |
+ CompletionRequestImpl _currentRequest; |
+ |
+ /** |
* Initialize a new request handler for the given [server]. |
*/ |
CompletionDomainHandler(this.server); |
/** |
- * Compute completion results for the given reqeust and append them to the stream. |
+ * Compute completion results for the given request and append them to the stream. |
* Clients should not call this method directly as it is automatically called |
* when a client listens to the stream returned by [results]. |
* Subclasses should override this method, append at least one result |
@@ -76,7 +81,12 @@ class CompletionDomainHandler implements RequestHandler { |
for (CompletionContributor contributor in newContributors) { |
String contributorTag = 'computeSuggestions - ${contributor.runtimeType}'; |
performance.logStartTime(contributorTag); |
- suggestions.addAll(await contributor.computeSuggestions(request)); |
+ try { |
+ suggestions.addAll(await contributor.computeSuggestions(request)); |
+ } on AbortCompletion { |
+ suggestions.clear(); |
+ break; |
+ } |
performance.logElapseTime(contributorTag); |
} |
@@ -139,7 +149,7 @@ class CompletionDomainHandler implements RequestHandler { |
recordRequest(performance, context, source, params.offset); |
- CompletionRequest completionRequest = new CompletionRequestImpl( |
+ CompletionRequestImpl completionRequest = new CompletionRequestImpl( |
context, |
server.resourceProvider, |
server.searchEngine, |
@@ -148,6 +158,9 @@ class CompletionDomainHandler implements RequestHandler { |
performance); |
String completionId = (_nextCompletionId++).toString(); |
+ _abortCurrentRequest(); |
+ _currentRequest = completionRequest; |
+ |
// Compute suggestions in the background |
computeSuggestions(completionRequest).then((CompletionResult result) { |
const SEND_NOTIFICATION_TAG = 'send notification'; |
@@ -161,6 +174,10 @@ class CompletionDomainHandler implements RequestHandler { |
performance.suggestionCountFirst = result.suggestions.length; |
performance.suggestionCountLast = result.suggestions.length; |
performance.complete(); |
+ }).whenComplete(() { |
+ if (_currentRequest == completionRequest) { |
+ _currentRequest = null; |
+ } |
}); |
// initial response without results |
@@ -198,6 +215,16 @@ class CompletionDomainHandler implements RequestHandler { |
completionId, replacementOffset, replacementLength, results, true) |
.toNotification()); |
} |
+ |
+ /** |
+ * Abort the current completion request, if any. |
+ */ |
+ void _abortCurrentRequest() { |
+ if (_currentRequest != null) { |
+ _currentRequest.abort(); |
+ _currentRequest = null; |
+ } |
+ } |
} |
/** |