OLD | NEW |
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'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/src/analysis_server.dart'; | 9 import 'package:analysis_server/src/analysis_server.dart'; |
10 import 'package:analysis_server/src/constants.dart'; | 10 import 'package:analysis_server/src/constants.dart'; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 /** | 82 /** |
83 * Return the completion manager for most recent [Source] and [AnalysisContext
], | 83 * Return the completion manager for most recent [Source] and [AnalysisContext
], |
84 * or `null` if none. | 84 * or `null` if none. |
85 */ | 85 */ |
86 CompletionManager get manager => _manager; | 86 CompletionManager get manager => _manager; |
87 | 87 |
88 /** | 88 /** |
89 * Return the [CompletionManager] for the given [context] and [source], | 89 * Return the [CompletionManager] for the given [context] and [source], |
90 * creating a new manager or returning an existing manager as necessary. | 90 * creating a new manager or returning an existing manager as necessary. |
91 */ | 91 */ |
92 CompletionManager completionManagerFor(AnalysisContext context, | 92 CompletionManager completionManagerFor( |
93 Source source) { | 93 AnalysisContext context, Source source) { |
94 if (_manager != null) { | 94 if (_manager != null) { |
95 if (_manager.context == context && _manager.source == source) { | 95 if (_manager.context == context && _manager.source == source) { |
96 return _manager; | 96 return _manager; |
97 } | 97 } |
98 _discardManager(); | 98 _discardManager(); |
99 } | 99 } |
100 _manager = createCompletionManager(context, source, searchEngine); | 100 _manager = createCompletionManager(context, source, searchEngine); |
101 if (context != null) { | 101 if (context != null) { |
102 _sourcesChangedSubscription = | 102 _sourcesChangedSubscription = |
103 context.onSourcesChanged.listen(sourcesChanged); | 103 context.onSourcesChanged.listen(sourcesChanged); |
104 } | 104 } |
105 return _manager; | 105 return _manager; |
106 } | 106 } |
107 | 107 |
108 /** | 108 /** |
109 * If the context associated with the cache has changed or been removed | 109 * If the context associated with the cache has changed or been removed |
110 * then discard the cache. | 110 * then discard the cache. |
111 */ | 111 */ |
112 void contextsChanged(ContextsChangedEvent event) { | 112 void contextsChanged(ContextsChangedEvent event) { |
113 if (_manager != null) { | 113 if (_manager != null) { |
114 AnalysisContext context = _manager.context; | 114 AnalysisContext context = _manager.context; |
115 if (event.changed.contains(context) || event.removed.contains(context)) { | 115 if (event.changed.contains(context) || event.removed.contains(context)) { |
116 _discardManager(); | 116 _discardManager(); |
117 } | 117 } |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 CompletionManager createCompletionManager(AnalysisContext context, | 121 CompletionManager createCompletionManager( |
122 Source source, SearchEngine searchEngine) { | 122 AnalysisContext context, Source source, SearchEngine searchEngine) { |
123 return new CompletionManager.create(context, source, searchEngine); | 123 return new CompletionManager.create(context, source, searchEngine); |
124 } | 124 } |
125 | 125 |
126 @override | 126 @override |
127 Response handleRequest(Request request) { | 127 Response handleRequest(Request request) { |
128 if (searchEngine == null) { | 128 if (searchEngine == null) { |
129 return new Response.noIndexGenerated(request); | 129 return new Response.noIndexGenerated(request); |
130 } | 130 } |
131 try { | 131 try { |
132 String requestName = request.method; | 132 String requestName = request.method; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 recordRequest(performance, context, source, params.offset); | 179 recordRequest(performance, context, source, params.offset); |
180 if (manager == null) { | 180 if (manager == null) { |
181 manager = completionManagerFor(context, source); | 181 manager = completionManagerFor(context, source); |
182 } | 182 } |
183 CompletionRequest completionRequest = | 183 CompletionRequest completionRequest = |
184 new CompletionRequest(params.offset, performance); | 184 new CompletionRequest(params.offset, performance); |
185 int notificationCount = 0; | 185 int notificationCount = 0; |
186 manager.results(completionRequest).listen((CompletionResult result) { | 186 manager.results(completionRequest).listen((CompletionResult result) { |
187 ++notificationCount; | 187 ++notificationCount; |
188 performance.logElapseTime("notification $notificationCount send", () { | 188 performance.logElapseTime("notification $notificationCount send", () { |
189 sendCompletionNotification( | 189 sendCompletionNotification(completionId, result.replacementOffset, |
190 completionId, | 190 result.replacementLength, result.suggestions, result.last); |
191 result.replacementOffset, | |
192 result.replacementLength, | |
193 result.suggestions, | |
194 result.last); | |
195 }); | 191 }); |
196 if (notificationCount == 1) { | 192 if (notificationCount == 1) { |
197 performance.logFirstNotificationComplete('notification 1 complete'); | 193 performance.logFirstNotificationComplete('notification 1 complete'); |
198 performance.suggestionCountFirst = result.suggestions.length; | 194 performance.suggestionCountFirst = result.suggestions.length; |
199 } | 195 } |
200 if (result.last) { | 196 if (result.last) { |
201 performance.notificationCount = notificationCount; | 197 performance.notificationCount = notificationCount; |
202 performance.suggestionCountLast = result.suggestions.length; | 198 performance.suggestionCountLast = result.suggestions.length; |
203 performance.complete(); | 199 performance.complete(); |
204 } | 200 } |
205 }); | 201 }); |
206 // initial response without results | 202 // initial response without results |
207 return new CompletionGetSuggestionsResult( | 203 return new CompletionGetSuggestionsResult(completionId) |
208 completionId).toResponse(request.id); | 204 .toResponse(request.id); |
209 } | 205 } |
210 | 206 |
211 /** | 207 /** |
212 * If tracking code completion performance over time, then | 208 * If tracking code completion performance over time, then |
213 * record addition information about the request in the performance record. | 209 * record addition information about the request in the performance record. |
214 */ | 210 */ |
215 void recordRequest(CompletionPerformance performance, AnalysisContext context, | 211 void recordRequest(CompletionPerformance performance, AnalysisContext context, |
216 Source source, int offset) { | 212 Source source, int offset) { |
217 performance.source = source; | 213 performance.source = source; |
218 if (performanceListMaxLength == 0 || context == null || source == null) { | 214 if (performanceListMaxLength == 0 || context == null || source == null) { |
219 return; | 215 return; |
220 } | 216 } |
221 TimestampedData<String> data = context.getContents(source); | 217 TimestampedData<String> data = context.getContents(source); |
222 if (data == null) { | 218 if (data == null) { |
223 return; | 219 return; |
224 } | 220 } |
225 performance.setContentsAndOffset(data.data, offset); | 221 performance.setContentsAndOffset(data.data, offset); |
226 while (performanceList.length >= performanceListMaxLength) { | 222 while (performanceList.length >= performanceListMaxLength) { |
227 performanceList.removeAt(0); | 223 performanceList.removeAt(0); |
228 } | 224 } |
229 performanceList.add(performance); | 225 performanceList.add(performance); |
230 } | 226 } |
231 | 227 |
232 /** | 228 /** |
233 * Send completion notification results. | 229 * Send completion notification results. |
234 */ | 230 */ |
235 void sendCompletionNotification(String completionId, int replacementOffset, | 231 void sendCompletionNotification(String completionId, int replacementOffset, |
236 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast
) { | 232 int replacementLength, Iterable<CompletionSuggestion> results, |
237 server.sendNotification( | 233 bool isLast) { |
238 new CompletionResultsParams( | 234 server.sendNotification(new CompletionResultsParams( |
239 completionId, | 235 completionId, replacementOffset, replacementLength, results, isLast) |
240 replacementOffset, | 236 .toNotification()); |
241 replacementLength, | |
242 results, | |
243 isLast).toNotification()); | |
244 } | 237 } |
245 | 238 |
246 /** | 239 /** |
247 * Discard the cache if a source other than the source referenced by | 240 * Discard the cache if a source other than the source referenced by |
248 * the cache changes or if any source is added, removed, or deleted. | 241 * the cache changes or if any source is added, removed, or deleted. |
249 */ | 242 */ |
250 void sourcesChanged(SourcesChangedEvent event) { | 243 void sourcesChanged(SourcesChangedEvent event) { |
251 | |
252 bool shouldDiscardManager(SourcesChangedEvent event) { | 244 bool shouldDiscardManager(SourcesChangedEvent event) { |
253 if (_manager == null) { | 245 if (_manager == null) { |
254 return false; | 246 return false; |
255 } | 247 } |
256 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) { | 248 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) { |
257 return true; | 249 return true; |
258 } | 250 } |
259 var changedSources = event.changedSources; | 251 var changedSources = event.changedSources; |
260 return changedSources.length > 2 || | 252 return changedSources.length > 2 || |
261 (changedSources.length == 1 && !changedSources.contains(_manager.sourc
e)); | 253 (changedSources.length == 1 && |
| 254 !changedSources.contains(_manager.source)); |
262 } | 255 } |
263 | 256 |
264 if (shouldDiscardManager(event)) { | 257 if (shouldDiscardManager(event)) { |
265 _discardManager(); | 258 _discardManager(); |
266 } | 259 } |
267 } | 260 } |
268 | 261 |
269 /** | 262 /** |
270 * Discard the sourcesChanged subscription if any | 263 * Discard the sourcesChanged subscription if any |
271 */ | 264 */ |
272 void _discardManager() { | 265 void _discardManager() { |
273 if (_sourcesChangedSubscription != null) { | 266 if (_sourcesChangedSubscription != null) { |
274 _sourcesChangedSubscription.cancel(); | 267 _sourcesChangedSubscription.cancel(); |
275 _sourcesChangedSubscription = null; | 268 _sourcesChangedSubscription = null; |
276 } | 269 } |
277 if (_manager != null) { | 270 if (_manager != null) { |
278 _manager.dispose(); | 271 _manager.dispose(); |
279 _manager = null; | 272 _manager = null; |
280 } | 273 } |
281 } | 274 } |
282 } | 275 } |
OLD | NEW |