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 services.completion.dart; | 5 library services.completion.dart; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 9 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
10 import 'package:analysis_server/src/analysis_server.dart'; | 10 import 'package:analysis_server/src/analysis_server.dart'; |
11 import 'package:analysis_server/src/provisional/completion/completion_core.dart' | 11 import 'package:analysis_server/src/provisional/completion/completion_core.dart' |
12 show AnalysisRequest, CompletionRequest; | 12 show AnalysisRequest, CompletionRequest; |
13 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; | 13 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; |
14 import 'package:analysis_server/src/services/completion/arglist_contributor.dart
'; | 14 import 'package:analysis_server/src/services/completion/arglist_contributor.dart
'; |
15 import 'package:analysis_server/src/services/completion/combinator_contributor.d
art'; | 15 import 'package:analysis_server/src/services/completion/combinator_contributor.d
art'; |
16 import 'package:analysis_server/src/services/completion/common_usage_computer.da
rt'; | |
17 import 'package:analysis_server/src/services/completion/completion_manager.dart'
; | 16 import 'package:analysis_server/src/services/completion/completion_manager.dart'
; |
18 import 'package:analysis_server/src/services/completion/contribution_sorter.dart
'; | 17 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter
.dart'; |
| 18 import 'package:analysis_server/src/services/completion/dart/contribution_sorter
.dart'; |
19 import 'package:analysis_server/src/services/completion/dart_completion_cache.da
rt'; | 19 import 'package:analysis_server/src/services/completion/dart_completion_cache.da
rt'; |
20 import 'package:analysis_server/src/services/completion/imported_reference_contr
ibutor.dart'; | 20 import 'package:analysis_server/src/services/completion/imported_reference_contr
ibutor.dart'; |
21 import 'package:analysis_server/src/services/completion/keyword_contributor.dart
'; | 21 import 'package:analysis_server/src/services/completion/keyword_contributor.dart
'; |
22 import 'package:analysis_server/src/services/completion/local_reference_contribu
tor.dart'; | 22 import 'package:analysis_server/src/services/completion/local_reference_contribu
tor.dart'; |
23 import 'package:analysis_server/src/services/completion/optype.dart'; | 23 import 'package:analysis_server/src/services/completion/optype.dart'; |
24 import 'package:analysis_server/src/services/completion/prefixed_element_contrib
utor.dart'; | 24 import 'package:analysis_server/src/services/completion/prefixed_element_contrib
utor.dart'; |
25 import 'package:analysis_server/src/services/completion/uri_contributor.dart'; | 25 import 'package:analysis_server/src/services/completion/uri_contributor.dart'; |
26 import 'package:analysis_server/src/services/search/search_engine.dart'; | 26 import 'package:analysis_server/src/services/search/search_engine.dart'; |
27 import 'package:analyzer/src/context/context.dart' | |
28 show AnalysisFutureHelper, AnalysisContextImpl; | |
29 import 'package:analyzer/src/generated/ast.dart'; | 27 import 'package:analyzer/src/generated/ast.dart'; |
30 import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl; | 28 import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl; |
31 import 'package:analyzer/src/generated/scanner.dart'; | 29 import 'package:analyzer/src/generated/scanner.dart'; |
32 import 'package:analyzer/src/generated/source.dart'; | 30 import 'package:analyzer/src/generated/source.dart'; |
33 | 31 |
34 const int DART_RELEVANCE_COMMON_USAGE = 1200; | 32 const int DART_RELEVANCE_COMMON_USAGE = 1200; |
35 const int DART_RELEVANCE_DEFAULT = 1000; | 33 const int DART_RELEVANCE_DEFAULT = 1000; |
36 const int DART_RELEVANCE_HIGH = 2000; | 34 const int DART_RELEVANCE_HIGH = 2000; |
37 const int DART_RELEVANCE_INHERITED_ACCESSOR = 1057; | 35 const int DART_RELEVANCE_INHERITED_ACCESSOR = 1057; |
38 const int DART_RELEVANCE_INHERITED_FIELD = 1058; | 36 const int DART_RELEVANCE_INHERITED_FIELD = 1058; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } | 70 } |
73 | 71 |
74 /** | 72 /** |
75 * Manages code completion for a given Dart file completion request. | 73 * Manages code completion for a given Dart file completion request. |
76 */ | 74 */ |
77 class DartCompletionManager extends CompletionManager { | 75 class DartCompletionManager extends CompletionManager { |
78 /** | 76 /** |
79 * The [defaultContributionSorter] is a long-lived object that isn't allowed | 77 * The [defaultContributionSorter] is a long-lived object that isn't allowed |
80 * to maintain state between calls to [ContributionSorter#sort(...)]. | 78 * to maintain state between calls to [ContributionSorter#sort(...)]. |
81 */ | 79 */ |
82 static ContributionSorter defaultContributionSorter = | 80 static DartContributionSorter defaultContributionSorter = |
83 new CommonUsageComputer(); | 81 new CommonUsageSorter(); |
84 | 82 |
85 final SearchEngine searchEngine; | 83 final SearchEngine searchEngine; |
86 final DartCompletionCache cache; | 84 final DartCompletionCache cache; |
87 List<DartCompletionContributor> contributors; | 85 List<DartCompletionContributor> contributors; |
88 ContributionSorter contributionSorter; | 86 DartContributionSorter contributionSorter; |
89 | 87 |
90 DartCompletionManager( | 88 DartCompletionManager( |
91 AnalysisContext context, this.searchEngine, Source source, this.cache, | 89 AnalysisContext context, this.searchEngine, Source source, this.cache, |
92 [this.contributors, this.contributionSorter]) | 90 [this.contributors, this.contributionSorter]) |
93 : super(context, source) { | 91 : super(context, source) { |
94 if (contributors == null) { | 92 if (contributors == null) { |
95 contributors = [ | 93 contributors = [ |
96 // LocalReferenceContributor before ImportedReferenceContributor | 94 // LocalReferenceContributor before ImportedReferenceContributor |
97 // because local suggestions take precedence | 95 // because local suggestions take precedence |
98 // and can hide other suggestions with the same name | 96 // and can hide other suggestions with the same name |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 171 } |
174 } | 172 } |
175 } | 173 } |
176 | 174 |
177 List<DartCompletionContributor> todo = new List.from(contributors); | 175 List<DartCompletionContributor> todo = new List.from(contributors); |
178 todo.removeWhere((DartCompletionContributor c) { | 176 todo.removeWhere((DartCompletionContributor c) { |
179 return performance.logElapseTime('computeFast ${c.runtimeType}', () { | 177 return performance.logElapseTime('computeFast ${c.runtimeType}', () { |
180 return c.computeFast(request); | 178 return c.computeFast(request); |
181 }); | 179 }); |
182 }); | 180 }); |
183 _processAnalysisRequest(request, | 181 // TODO(danrubel) current sorter requires no additional analysis, |
184 contributionSorter.sort(request, request.suggestions)); | 182 // but need to handle the returned future the same way that futures |
| 183 // returned from contributors are handled once this method is refactored |
| 184 // to be async. |
| 185 /* await */ contributionSorter.sort(request, request.suggestions); |
185 // TODO (danrubel) if request is obsolete | 186 // TODO (danrubel) if request is obsolete |
186 // (processAnalysisRequest returns false) | 187 // (processAnalysisRequest returns false) |
187 // then send empty results | 188 // then send empty results |
188 if (todo.isEmpty) { | 189 if (todo.isEmpty) { |
189 sendResults(request, todo.isEmpty); | 190 sendResults(request, todo.isEmpty); |
190 } | 191 } |
191 return todo; | 192 return todo; |
192 }); | 193 }); |
193 } | 194 } |
194 | 195 |
(...skipping 22 matching lines...) Expand all Loading... |
217 int count = todo.length; | 218 int count = todo.length; |
218 todo.forEach((DartCompletionContributor c) { | 219 todo.forEach((DartCompletionContributor c) { |
219 String name = c.runtimeType.toString(); | 220 String name = c.runtimeType.toString(); |
220 String completeTag = 'computeFull $name complete'; | 221 String completeTag = 'computeFull $name complete'; |
221 performance.logStartTime(completeTag); | 222 performance.logStartTime(completeTag); |
222 performance.logElapseTime('computeFull $name', () { | 223 performance.logElapseTime('computeFull $name', () { |
223 c.computeFull(request).then((bool changed) { | 224 c.computeFull(request).then((bool changed) { |
224 performance.logElapseTime(completeTag); | 225 performance.logElapseTime(completeTag); |
225 bool last = --count == 0; | 226 bool last = --count == 0; |
226 if (changed || last) { | 227 if (changed || last) { |
227 _processAnalysisRequest(request, | 228 // TODO(danrubel) current sorter requires no additional analysis
, |
228 contributionSorter.sort(request, request.suggestions)); | 229 // but need to handle the returned future the same way that futu
res |
| 230 // returned from contributors are handled once this method is re
factored |
| 231 // to be async. |
| 232 /* await */ contributionSorter.sort(request, request.suggestions
); |
229 // TODO (danrubel) if request is obsolete | 233 // TODO (danrubel) if request is obsolete |
230 // (processAnalysisRequest returns false) | 234 // (processAnalysisRequest returns false) |
231 // then send empty results | 235 // then send empty results |
232 sendResults(request, last); | 236 sendResults(request, last); |
233 } | 237 } |
234 }); | 238 }); |
235 }); | 239 }); |
236 }); | 240 }); |
237 }); | 241 }); |
238 }); | 242 }); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 Source libSource = libraries[0]; | 283 Source libSource = libraries[0]; |
280 assert(libSource != null); | 284 assert(libSource != null); |
281 return context | 285 return context |
282 .computeResolvedCompilationUnitAsync(source, libSource) | 286 .computeResolvedCompilationUnitAsync(source, libSource) |
283 .catchError((_) { | 287 .catchError((_) { |
284 // This source file is not scheduled for analysis, so a resolved | 288 // This source file is not scheduled for analysis, so a resolved |
285 // compilation unit is never going to get computed. | 289 // compilation unit is never going to get computed. |
286 return null; | 290 return null; |
287 }, test: (e) => e is AnalysisNotScheduledError); | 291 }, test: (e) => e is AnalysisNotScheduledError); |
288 } | 292 } |
289 | |
290 /** | |
291 * Process the analysis [analysis] and any subsequent requests. | |
292 * Return a [Future] that returns `true` | |
293 * once all analysis requests have been processed | |
294 * or `false` if the original completion request is obsolete | |
295 * and processing requests was terminated before finished. | |
296 */ | |
297 Future<bool> _processAnalysisRequest( | |
298 CompletionRequest request, AnalysisRequest analysis) { | |
299 // Return if no additional analysis is necessary | |
300 if (analysis == null) { | |
301 return new Future.value(true); | |
302 } | |
303 | |
304 // Check to see if the result is already cached | |
305 var cachedValue = context.getResult(analysis.target, analysis.descriptor); | |
306 if (cachedValue != null) { | |
307 return _processAnalysisRequest( | |
308 request, analysis.callback(request, cachedValue)); | |
309 } | |
310 | |
311 // TODO (danrubel) determine when completion request is obsolete | |
312 // and analysis should be terminated before requesting additional analysis | |
313 | |
314 // Request additional analysis | |
315 return new AnalysisFutureHelper((context as AnalysisContextImpl), | |
316 analysis.target, analysis.descriptor).computeAsync().then((value) { | |
317 return _processAnalysisRequest( | |
318 request, analysis.callback(request, cachedValue)); | |
319 }); | |
320 } | |
321 } | 293 } |
322 | 294 |
323 /** | 295 /** |
324 * The context in which the completion is requested. | 296 * The context in which the completion is requested. |
325 */ | 297 */ |
326 class DartCompletionRequest extends CompletionRequestImpl { | 298 class DartCompletionRequest extends CompletionRequestImpl { |
327 /** | 299 /** |
328 * Cached information from a prior code completion operation. | 300 * Cached information from a prior code completion operation. |
329 */ | 301 */ |
330 final DartCompletionCache cache; | 302 final DartCompletionCache cache; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 parameterNames: suggestion.parameterNames, | 419 parameterNames: suggestion.parameterNames, |
448 parameterTypes: suggestion.parameterTypes, | 420 parameterTypes: suggestion.parameterTypes, |
449 requiredParameterCount: suggestion.requiredParameterCount, | 421 requiredParameterCount: suggestion.requiredParameterCount, |
450 hasNamedParameters: suggestion.hasNamedParameters, | 422 hasNamedParameters: suggestion.hasNamedParameters, |
451 returnType: suggestion.returnType, | 423 returnType: suggestion.returnType, |
452 element: suggestion.element); | 424 element: suggestion.element); |
453 } | 425 } |
454 } | 426 } |
455 } | 427 } |
456 } | 428 } |
OLD | NEW |