| 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 |