| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.manager; | 5 library services.completion.dart.manager; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/protocol/protocol_generated.dart'; | 9 import 'package:analysis_server/protocol/protocol_generated.dart'; |
| 10 import 'package:analysis_server/src/ide_options.dart'; | 10 import 'package:analysis_server/src/ide_options.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 CompletionContributor, CompletionRequest; | 12 show CompletionContributor, CompletionRequest; |
| 13 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; | 13 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
dart'; |
| 14 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi
n.dart'; | 14 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi
n.dart'; |
| 15 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; | 15 import 'package:analysis_server/src/provisional/completion/dart/completion_targe
t.dart'; |
| 16 import 'package:analysis_server/src/services/completion/completion_core.dart'; | 16 import 'package:analysis_server/src/services/completion/completion_core.dart'; |
| 17 import 'package:analysis_server/src/services/completion/completion_performance.d
art'; | 17 import 'package:analysis_server/src/services/completion/completion_performance.d
art'; |
| 18 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter
.dart'; | 18 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter
.dart'; |
| 19 import 'package:analysis_server/src/services/completion/dart/contribution_sorter
.dart'; | 19 import 'package:analysis_server/src/services/completion/dart/contribution_sorter
.dart'; |
| 20 import 'package:analysis_server/src/services/completion/dart/optype.dart'; | 20 import 'package:analysis_server/src/services/completion/dart/optype.dart'; |
| 21 import 'package:analyzer/dart/ast/ast.dart'; | 21 import 'package:analyzer/dart/ast/ast.dart'; |
| 22 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; | 22 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; |
| 23 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 23 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| 24 import 'package:analyzer/dart/ast/token.dart'; | 24 import 'package:analyzer/dart/ast/token.dart'; |
| 25 import 'package:analyzer/dart/element/element.dart'; | 25 import 'package:analyzer/dart/element/element.dart'; |
| 26 import 'package:analyzer/dart/element/type.dart'; | 26 import 'package:analyzer/dart/element/type.dart'; |
| 27 import 'package:analyzer/exception/exception.dart'; | |
| 28 import 'package:analyzer/file_system/file_system.dart'; | 27 import 'package:analyzer/file_system/file_system.dart'; |
| 29 import 'package:analyzer/src/context/context.dart' show AnalysisFutureHelper; | |
| 30 import 'package:analyzer/src/dart/analysis/driver.dart'; | 28 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 31 import 'package:analyzer/src/dart/ast/token.dart'; | 29 import 'package:analyzer/src/dart/ast/token.dart'; |
| 32 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; | 30 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; |
| 33 import 'package:analyzer/src/generated/source.dart'; | 31 import 'package:analyzer/src/generated/source.dart'; |
| 34 import 'package:analyzer/src/task/dart.dart'; | |
| 35 import 'package:analyzer/task/dart.dart'; | |
| 36 import 'package:analyzer/task/model.dart'; | 32 import 'package:analyzer/task/model.dart'; |
| 37 | 33 |
| 38 /** | 34 /** |
| 39 * [DartCompletionManager] determines if a completion request is Dart specific | 35 * [DartCompletionManager] determines if a completion request is Dart specific |
| 40 * and forwards those requests to all [DartCompletionContributor]s. | 36 * and forwards those requests to all [DartCompletionContributor]s. |
| 41 */ | 37 */ |
| 42 class DartCompletionManager implements CompletionContributor { | 38 class DartCompletionManager implements CompletionContributor { |
| 43 /** | 39 /** |
| 44 * The [contributionSorter] is a long-lived object that isn't allowed | 40 * The [contributionSorter] is a long-lived object that isn't allowed |
| 45 * to maintain state between calls to [DartContributionSorter#sort(...)]. | 41 * to maintain state between calls to [DartContributionSorter#sort(...)]. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 } | 101 } |
| 106 | 102 |
| 107 /** | 103 /** |
| 108 * The information about a requested list of completions within a Dart file. | 104 * The information about a requested list of completions within a Dart file. |
| 109 */ | 105 */ |
| 110 class DartCompletionRequestImpl implements DartCompletionRequest { | 106 class DartCompletionRequestImpl implements DartCompletionRequest { |
| 111 @override | 107 @override |
| 112 final AnalysisResult result; | 108 final AnalysisResult result; |
| 113 | 109 |
| 114 @override | 110 @override |
| 115 final AnalysisContext context; | |
| 116 | |
| 117 @override | |
| 118 IdeOptions ideOptions; | 111 IdeOptions ideOptions; |
| 119 | 112 |
| 120 @override | 113 @override |
| 114 final LibraryElement coreLib; |
| 115 |
| 116 @override |
| 121 final Source source; | 117 final Source source; |
| 122 | 118 |
| 123 @override | 119 @override |
| 124 final int offset; | 120 final int offset; |
| 125 | 121 |
| 126 @override | 122 @override |
| 127 Expression dotTarget; | 123 Expression dotTarget; |
| 128 | 124 |
| 129 @override | 125 @override |
| 130 Source librarySource; | 126 Source librarySource; |
| 131 | 127 |
| 132 @override | 128 @override |
| 133 final ResourceProvider resourceProvider; | 129 final ResourceProvider resourceProvider; |
| 134 | 130 |
| 135 @override | 131 @override |
| 136 CompletionTarget target; | 132 CompletionTarget target; |
| 137 | 133 |
| 138 /** | 134 /** |
| 139 * The [LibraryElement] representing dart:core | |
| 140 */ | |
| 141 LibraryElement _coreLib; | |
| 142 | |
| 143 /** | |
| 144 * The [DartType] for Object in dart:core | 135 * The [DartType] for Object in dart:core |
| 145 */ | 136 */ |
| 146 InterfaceType _objectType; | 137 InterfaceType _objectType; |
| 147 | 138 |
| 148 OpType _opType; | 139 OpType _opType; |
| 149 | 140 |
| 150 final CompletionRequest _originalRequest; | 141 final CompletionRequest _originalRequest; |
| 151 | 142 |
| 152 final CompletionPerformance performance; | 143 final CompletionPerformance performance; |
| 153 | 144 |
| 154 DartCompletionRequestImpl._( | 145 DartCompletionRequestImpl._( |
| 155 this.result, | 146 this.result, |
| 156 this.context, | |
| 157 this.resourceProvider, | 147 this.resourceProvider, |
| 148 this.coreLib, |
| 158 this.librarySource, | 149 this.librarySource, |
| 159 this.source, | 150 this.source, |
| 160 this.offset, | 151 this.offset, |
| 161 CompilationUnit unit, | 152 CompilationUnit unit, |
| 162 this._originalRequest, | 153 this._originalRequest, |
| 163 this.performance, | 154 this.performance, |
| 164 this.ideOptions) { | 155 this.ideOptions) { |
| 165 _updateTargets(unit); | 156 _updateTargets(unit); |
| 166 } | 157 } |
| 167 | 158 |
| 168 @override | 159 @override |
| 169 LibraryElement get coreLib { | |
| 170 if (result != null) { | |
| 171 AnalysisContext context = | |
| 172 resolutionMap.elementDeclaredByCompilationUnit(result.unit).context; | |
| 173 _coreLib = context.typeProvider.objectType.element.library; | |
| 174 } else { | |
| 175 Source coreUri = sourceFactory.forUri('dart:core'); | |
| 176 _coreLib = context.computeLibraryElement(coreUri); | |
| 177 } | |
| 178 return _coreLib; | |
| 179 } | |
| 180 | |
| 181 @override | |
| 182 bool get includeIdentifiers { | 160 bool get includeIdentifiers { |
| 183 return opType.includeIdentifiers; | 161 return opType.includeIdentifiers; |
| 184 } | 162 } |
| 185 | 163 |
| 186 @override | 164 @override |
| 187 LibraryElement get libraryElement { | 165 LibraryElement get libraryElement { |
| 188 //TODO(danrubel) build the library element rather than all the declarations | 166 //TODO(danrubel) build the library element rather than all the declarations |
| 189 CompilationUnit unit = target.unit; | 167 CompilationUnit unit = target.unit; |
| 190 if (unit != null) { | 168 if (unit != null) { |
| 191 CompilationUnitElement elem = unit.element; | 169 CompilationUnitElement elem = unit.element; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 205 } | 183 } |
| 206 | 184 |
| 207 OpType get opType { | 185 OpType get opType { |
| 208 if (_opType == null) { | 186 if (_opType == null) { |
| 209 _opType = new OpType.forCompletion(target, offset); | 187 _opType = new OpType.forCompletion(target, offset); |
| 210 } | 188 } |
| 211 return _opType; | 189 return _opType; |
| 212 } | 190 } |
| 213 | 191 |
| 214 @override | 192 @override |
| 215 String get sourceContents { | 193 String get sourceContents => result.content; |
| 216 if (result != null) { | |
| 217 return result.content; | |
| 218 } else { | |
| 219 return context.getContents(source)?.data; | |
| 220 } | |
| 221 } | |
| 222 | 194 |
| 223 @override | 195 @override |
| 224 SourceFactory get sourceFactory { | 196 SourceFactory get sourceFactory => result.sourceFactory; |
| 225 return context?.sourceFactory ?? result.sourceFactory; | |
| 226 } | |
| 227 | 197 |
| 228 /** | 198 /** |
| 229 * Throw [AbortCompletion] if the completion request has been aborted. | 199 * Throw [AbortCompletion] if the completion request has been aborted. |
| 230 */ | 200 */ |
| 231 void checkAborted() { | 201 void checkAborted() { |
| 232 _originalRequest.checkAborted(); | 202 _originalRequest.checkAborted(); |
| 233 } | 203 } |
| 234 | 204 |
| 235 /** | 205 /** |
| 236 * Update the completion [target] and [dotTarget] based on the given [unit]. | 206 * Update the completion [target] and [dotTarget] based on the given [unit]. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 static Future<DartCompletionRequest> from(CompletionRequest request, | 239 static Future<DartCompletionRequest> from(CompletionRequest request, |
| 270 {ResultDescriptor resultDescriptor}) async { | 240 {ResultDescriptor resultDescriptor}) async { |
| 271 request.checkAborted(); | 241 request.checkAborted(); |
| 272 CompletionPerformance performance = | 242 CompletionPerformance performance = |
| 273 (request as CompletionRequestImpl).performance; | 243 (request as CompletionRequestImpl).performance; |
| 274 const BUILD_REQUEST_TAG = 'build DartCompletionRequest'; | 244 const BUILD_REQUEST_TAG = 'build DartCompletionRequest'; |
| 275 performance.logStartTime(BUILD_REQUEST_TAG); | 245 performance.logStartTime(BUILD_REQUEST_TAG); |
| 276 | 246 |
| 277 Source libSource; | 247 Source libSource; |
| 278 CompilationUnit unit; | 248 CompilationUnit unit; |
| 279 if (request.context == null) { | 249 unit = request.result.unit; |
| 280 unit = request.result.unit; | 250 // TODO(scheglov) support for parts |
| 281 // TODO(scheglov) support for parts | 251 libSource = resolutionMap.elementDeclaredByCompilationUnit(unit).source; |
| 282 libSource = resolutionMap.elementDeclaredByCompilationUnit(unit).source; | |
| 283 } else { | |
| 284 Source source = request.source; | |
| 285 AnalysisContext context = request.context; | |
| 286 | 252 |
| 287 const PARSE_TAG = 'parse unit'; | 253 LibraryElement coreLib = |
| 288 performance.logStartTime(PARSE_TAG); | 254 await request.result.driver.getLibraryByUri('dart:core'); |
| 289 unit = request.context.computeResult(source, PARSED_UNIT); | |
| 290 performance.logElapseTime(PARSE_TAG); | |
| 291 | |
| 292 if (unit.directives.any((d) => d is PartOfDirective)) { | |
| 293 List<Source> libraries = context.getLibrariesContaining(source); | |
| 294 if (libraries.isNotEmpty) { | |
| 295 libSource = libraries[0]; | |
| 296 } | |
| 297 } else { | |
| 298 libSource = source; | |
| 299 } | |
| 300 | |
| 301 // Most (all?) contributors need declarations in scope to be resolved | |
| 302 if (libSource != null) { | |
| 303 unit = await _computeAsync( | |
| 304 request, | |
| 305 new LibrarySpecificUnit(libSource, source), | |
| 306 resultDescriptor ?? RESOLVED_UNIT5, | |
| 307 performance, | |
| 308 'resolve declarations'); | |
| 309 } | |
| 310 } | |
| 311 | 255 |
| 312 DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._( | 256 DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._( |
| 313 request.result, | 257 request.result, |
| 314 request.context, | |
| 315 request.resourceProvider, | 258 request.resourceProvider, |
| 259 coreLib, |
| 316 libSource, | 260 libSource, |
| 317 request.source, | 261 request.source, |
| 318 request.offset, | 262 request.offset, |
| 319 unit, | 263 unit, |
| 320 request, | 264 request, |
| 321 performance, | 265 performance, |
| 322 request.ideOptions); | 266 request.ideOptions); |
| 323 | 267 |
| 324 performance.logElapseTime(BUILD_REQUEST_TAG); | 268 performance.logElapseTime(BUILD_REQUEST_TAG); |
| 325 return dartRequest; | 269 return dartRequest; |
| 326 } | 270 } |
| 327 | |
| 328 static Future _computeAsync( | |
| 329 CompletionRequest request, | |
| 330 AnalysisTarget target, | |
| 331 ResultDescriptor descriptor, | |
| 332 CompletionPerformance performance, | |
| 333 String perfTag) async { | |
| 334 request.checkAborted(); | |
| 335 performance.logStartTime(perfTag); | |
| 336 var result; | |
| 337 try { | |
| 338 result = | |
| 339 await new AnalysisFutureHelper(request.context, target, descriptor) | |
| 340 .computeAsync(); | |
| 341 } catch (e, s) { | |
| 342 if (e is AnalysisNotScheduledError) { | |
| 343 request.checkAborted(); | |
| 344 } | |
| 345 throw new AnalysisException( | |
| 346 'failed to $perfTag', new CaughtException(e, s)); | |
| 347 } | |
| 348 request.checkAborted(); | |
| 349 return result; | |
| 350 } | |
| 351 } | 271 } |
| 352 | 272 |
| 353 /** | 273 /** |
| 354 * Utility class for computing the code completion replacement range | 274 * Utility class for computing the code completion replacement range |
| 355 */ | 275 */ |
| 356 class ReplacementRange { | 276 class ReplacementRange { |
| 357 int offset; | 277 int offset; |
| 358 int length; | 278 int length; |
| 359 | 279 |
| 360 ReplacementRange(this.offset, this.length); | 280 ReplacementRange(this.offset, this.length); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 if (start <= requestOffset && requestOffset <= end) { | 317 if (start <= requestOffset && requestOffset <= end) { |
| 398 // Replacement range for import URI | 318 // Replacement range for import URI |
| 399 return new ReplacementRange(start, end - start); | 319 return new ReplacementRange(start, end - start); |
| 400 } | 320 } |
| 401 } | 321 } |
| 402 } | 322 } |
| 403 } | 323 } |
| 404 return new ReplacementRange(requestOffset, 0); | 324 return new ReplacementRange(requestOffset, 0); |
| 405 } | 325 } |
| 406 } | 326 } |
| OLD | NEW |