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

Side by Side Diff: pkg/analysis_server/lib/src/domain_completion.dart

Issue 744043002: discard code completion cache if context or other sources change (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 years, 1 month 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
« no previous file with comments | « no previous file | pkg/analysis_server/test/domain_completion_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library domain.completion; 5 library domain.completion;
6 6
7 import 'dart:async';
8
7 import 'package:analysis_server/src/analysis_server.dart'; 9 import 'package:analysis_server/src/analysis_server.dart';
8 import 'package:analysis_server/src/constants.dart'; 10 import 'package:analysis_server/src/constants.dart';
9 import 'package:analysis_server/src/protocol.dart'; 11 import 'package:analysis_server/src/protocol.dart';
10 import 'package:analysis_server/src/services/completion/completion_manager.dart' ; 12 import 'package:analysis_server/src/services/completion/completion_manager.dart' ;
13 import 'package:analysis_server/src/services/search/search_engine.dart';
14 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/source.dart';
11 16
12 export 'package:analysis_server/src/services/completion/completion_manager.dart' 17 export 'package:analysis_server/src/services/completion/completion_manager.dart'
13 show CompletionPerformance, OperationPerformance; 18 show CompletionPerformance, OperationPerformance;
14 19
15 /** 20 /**
16 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler] 21 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler]
17 * that handles requests in the search domain. 22 * that handles requests in the search domain.
18 */ 23 */
19 class CompletionDomainHandler implements RequestHandler { 24 class CompletionDomainHandler implements RequestHandler {
20 /** 25 /**
21 * The analysis server that is using this handler to process requests. 26 * The analysis server that is using this handler to process requests.
22 */ 27 */
23 final AnalysisServer server; 28 final AnalysisServer server;
24 29
25 /** 30 /**
26 * The next completion response id. 31 * The next completion response id.
27 */ 32 */
28 int _nextCompletionId = 0; 33 int _nextCompletionId = 0;
29 34
30 /** 35 /**
31 * Cached information from a prior completion operation. 36 * Cached information from a prior completion operation.
32 * The type of cached information depends upon the completion operation. 37 * The type of cached information depends upon the completion operation.
33 */ 38 */
34 // TODO (danrubel) clear cache if either source or context changes
35 CompletionCache _cache; 39 CompletionCache _cache;
36 40
37 /** 41 /**
42 * The subscription for the cached context's source change stream.
43 */
44 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription;
45
46 /**
38 * Code completion peformance for the last completion operation. 47 * Code completion peformance for the last completion operation.
39 */ 48 */
40 CompletionPerformance performance; 49 CompletionPerformance performance;
41 50
42 /** 51 /**
43 * Initialize a new request handler for the given [server]. 52 * Initialize a new request handler for the given [server].
44 */ 53 */
45 CompletionDomainHandler(this.server); 54 CompletionDomainHandler(this.server) {
55 server.onContextsChanged.listen(contextsChanged);
56 }
57
58 /**
59 * If the context associated with the cache has changed or been removed
60 * then discard the cache.
61 */
62 void contextsChanged(ContextsChangedEvent event) {
63 if (_cache != null) {
64 AnalysisContext context = _cache.context;
65 if (event.changed.contains(context) || event.removed.contains(context)) {
66 _discardCache();
67 }
68 }
69 }
70
71 CompletionManager createCompletionManager(AnalysisContext context,
72 Source source, int offset, SearchEngine searchEngine, CompletionCache cach e,
73 CompletionPerformance performance) {
74 return new CompletionManager.create(
75 context,
76 source,
77 offset,
78 searchEngine,
79 cache,
80 performance);
81 }
46 82
47 @override 83 @override
48 Response handleRequest(Request request) { 84 Response handleRequest(Request request) {
49 try { 85 try {
50 String requestName = request.method; 86 String requestName = request.method;
51 if (requestName == COMPLETION_GET_SUGGESTIONS) { 87 if (requestName == COMPLETION_GET_SUGGESTIONS) {
52 return processRequest(request); 88 return processRequest(request);
53 } 89 }
54 } on RequestFailure catch (exception) { 90 } on RequestFailure catch (exception) {
55 return exception.response; 91 return exception.response;
56 } 92 }
57 return null; 93 return null;
58 } 94 }
59 95
60 /** 96 /**
61 * Process a `completion.getSuggestions` request. 97 * Process a `completion.getSuggestions` request.
62 */ 98 */
63 Response processRequest(Request request) { 99 Response processRequest(Request request) {
64 performance = new CompletionPerformance(); 100 performance = new CompletionPerformance();
65 // extract params 101 // extract params
66 CompletionGetSuggestionsParams params = 102 CompletionGetSuggestionsParams params =
67 new CompletionGetSuggestionsParams.fromRequest(request); 103 new CompletionGetSuggestionsParams.fromRequest(request);
68 // schedule completion analysis 104 // schedule completion analysis
69 String completionId = (_nextCompletionId++).toString(); 105 String completionId = (_nextCompletionId++).toString();
70 CompletionManager manager = new CompletionManager.create( 106 CompletionManager manager = createCompletionManager(
71 server.getAnalysisContext(params.file), 107 server.getAnalysisContext(params.file),
72 server.getSource(params.file), 108 server.getSource(params.file),
73 params.offset, 109 params.offset,
74 server.searchEngine, 110 server.searchEngine,
75 _cache, 111 _cache,
76 performance); 112 performance);
77 manager.results().listen((CompletionResult result) { 113 manager.results().listen((CompletionResult result) {
78 sendCompletionNotification( 114 sendCompletionNotification(
79 completionId, 115 completionId,
80 result.replacementOffset, 116 result.replacementOffset,
81 result.replacementLength, 117 result.replacementLength,
82 result.suggestions, 118 result.suggestions,
83 result.last); 119 result.last);
84 if (result.last) { 120 if (result.last) {
85 performance.complete(); 121 performance.complete();
86 _cache = manager.completionCache; 122 CompletionCache newCache = manager.completionCache;
123 if (_cache != newCache) {
124 if (_cache != null) {
125 _discardCache();
126 }
127 _cache = newCache;
128 if (_cache.context != null) {
129 _sourcesChangedSubscription =
130 _cache.context.onSourcesChanged.listen(sourcesChanged);
131 }
132 }
87 } 133 }
88 }); 134 });
89 // initial response without results 135 // initial response without results
90 return new CompletionGetSuggestionsResult( 136 return new CompletionGetSuggestionsResult(
91 completionId).toResponse(request.id); 137 completionId).toResponse(request.id);
92 } 138 }
93 139
94 /** 140 /**
95 * Send completion notification results. 141 * Send completion notification results.
96 */ 142 */
97 void sendCompletionNotification(String completionId, int replacementOffset, 143 void sendCompletionNotification(String completionId, int replacementOffset,
98 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast ) { 144 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast ) {
99 server.sendNotification( 145 server.sendNotification(
100 new CompletionResultsParams( 146 new CompletionResultsParams(
101 completionId, 147 completionId,
102 replacementOffset, 148 replacementOffset,
103 replacementLength, 149 replacementLength,
104 results, 150 results,
105 isLast).toNotification()); 151 isLast).toNotification());
106 } 152 }
153
154 /**
155 * Discard the cache if a source other than the source referenced by
156 * the cache changes or if any source is added, removed, or deleted.
157 */
158 void sourcesChanged(SourcesChangedEvent event) {
159
160 bool shouldDiscardCache(SourcesChangedEvent event) {
161 if (_cache == null) {
162 return false;
163 }
164 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) {
165 return true;
166 }
167 var changedSources = event.changedSources;
168 return changedSources.length > 2 ||
169 (changedSources.length == 1 && !changedSources.contains(_cache.source) );
170 }
171
172 if (shouldDiscardCache(event)) {
173 _discardCache();
174 }
175 }
176
177 /**
178 * Discard the sourcesChanged subscription if any
179 */
180 void _discardCache() {
181 if (_sourcesChangedSubscription != null) {
182 _sourcesChangedSubscription.cancel();
183 _sourcesChangedSubscription = null;
184 }
185 _cache = null;
186 }
107 } 187 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/domain_completion_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698