| 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'; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 /** | 138 /** |
| 139 * The [LibraryElement] representing dart:core | 139 * The [LibraryElement] representing dart:core |
| 140 */ | 140 */ |
| 141 LibraryElement _coreLib; | 141 LibraryElement _coreLib; |
| 142 | 142 |
| 143 /** | 143 /** |
| 144 * The [DartType] for Object in dart:core | 144 * The [DartType] for Object in dart:core |
| 145 */ | 145 */ |
| 146 InterfaceType _objectType; | 146 InterfaceType _objectType; |
| 147 | 147 |
| 148 /** | |
| 149 * A list of resolved [ImportElement]s for the imported libraries | |
| 150 * or `null` if not computed. | |
| 151 */ | |
| 152 List<ImportElement> _resolvedImports; | |
| 153 | |
| 154 /** | |
| 155 * The resolved [CompilationUnitElement]s comprising the library | |
| 156 * or `null` if not computed. | |
| 157 */ | |
| 158 List<CompilationUnitElement> _resolvedUnits; | |
| 159 | |
| 160 OpType _opType; | 148 OpType _opType; |
| 161 | 149 |
| 162 final CompletionRequest _originalRequest; | 150 final CompletionRequest _originalRequest; |
| 163 | 151 |
| 164 final CompletionPerformance performance; | 152 final CompletionPerformance performance; |
| 165 | 153 |
| 166 DartCompletionRequestImpl._( | 154 DartCompletionRequestImpl._( |
| 167 this.result, | 155 this.result, |
| 168 this.context, | 156 this.context, |
| 169 this.resourceProvider, | 157 this.resourceProvider, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 return context?.sourceFactory ?? result.sourceFactory; | 225 return context?.sourceFactory ?? result.sourceFactory; |
| 238 } | 226 } |
| 239 | 227 |
| 240 /** | 228 /** |
| 241 * Throw [AbortCompletion] if the completion request has been aborted. | 229 * Throw [AbortCompletion] if the completion request has been aborted. |
| 242 */ | 230 */ |
| 243 void checkAborted() { | 231 void checkAborted() { |
| 244 _originalRequest.checkAborted(); | 232 _originalRequest.checkAborted(); |
| 245 } | 233 } |
| 246 | 234 |
| 247 @override | |
| 248 Future resolveContainingExpression(AstNode node) async { | |
| 249 // TODO When an Expression can be resolved instead of just an entire unit, | |
| 250 // this will be revisited with code searching up the parent until an | |
| 251 // Expression is found. | |
| 252 | |
| 253 return resolveContainingStatement(node); | |
| 254 } | |
| 255 | |
| 256 @override | |
| 257 Future resolveContainingStatement(AstNode node) async { | |
| 258 // TODO When a Statement can be resolved instead of just an entire unit, | |
| 259 // this will be revisited with code searching up the parent until a | |
| 260 // Statement is found. | |
| 261 | |
| 262 checkAborted(); | |
| 263 | |
| 264 // Return immediately if the expression has already been resolved | |
| 265 if (node is Expression && node.propagatedType != null) { | |
| 266 return; | |
| 267 } | |
| 268 | |
| 269 // Gracefully degrade if librarySource cannot be determined | |
| 270 if (librarySource == null) { | |
| 271 return; | |
| 272 } | |
| 273 | |
| 274 // Resolve declarations in the target unit | |
| 275 // TODO(danrubel) resolve the expression or containing method | |
| 276 // rather than the entire compilation unit | |
| 277 CompilationUnit resolvedUnit; | |
| 278 if (result != null) { | |
| 279 resolvedUnit = result.unit; | |
| 280 } else { | |
| 281 resolvedUnit = await _computeAsync( | |
| 282 this, | |
| 283 new LibrarySpecificUnit(librarySource, source), | |
| 284 RESOLVED_UNIT, | |
| 285 performance, | |
| 286 'resolve expression'); | |
| 287 } | |
| 288 | |
| 289 // TODO(danrubel) determine if the underlying source has been modified | |
| 290 // in a way that invalidates the completion request | |
| 291 // and return null | |
| 292 | |
| 293 // Gracefully degrade if unit cannot be resolved | |
| 294 if (resolvedUnit == null) { | |
| 295 return; | |
| 296 } | |
| 297 | |
| 298 // Recompute the target for the newly resolved unit | |
| 299 _updateTargets(resolvedUnit); | |
| 300 } | |
| 301 | |
| 302 @override | |
| 303 Future<List<ImportElement>> resolveImports() async { | |
| 304 checkAborted(); | |
| 305 if (_resolvedImports != null) { | |
| 306 return _resolvedImports; | |
| 307 } | |
| 308 LibraryElement libElem = libraryElement; | |
| 309 if (libElem == null) { | |
| 310 return null; | |
| 311 } | |
| 312 if (result != null) { | |
| 313 _resolvedImports = libElem.imports; | |
| 314 } else { | |
| 315 _resolvedImports = <ImportElement>[]; | |
| 316 for (ImportElement importElem in libElem.imports) { | |
| 317 if (importElem.importedLibrary?.exportNamespace == null) { | |
| 318 await _computeAsync(this, importElem.importedLibrary.source, | |
| 319 LIBRARY_ELEMENT4, performance, 'resolve imported library'); | |
| 320 checkAborted(); | |
| 321 } | |
| 322 _resolvedImports.add(importElem); | |
| 323 } | |
| 324 } | |
| 325 return _resolvedImports; | |
| 326 } | |
| 327 | |
| 328 @override | |
| 329 Future<List<CompilationUnitElement>> resolveUnits() async { | |
| 330 checkAborted(); | |
| 331 if (_resolvedUnits != null) { | |
| 332 return _resolvedUnits; | |
| 333 } | |
| 334 if (result != null) { | |
| 335 _resolvedUnits = resolutionMap | |
| 336 .elementDeclaredByCompilationUnit(result.unit) | |
| 337 .library | |
| 338 .units; | |
| 339 return _resolvedUnits; | |
| 340 } | |
| 341 LibraryElement libElem = libraryElement; | |
| 342 if (libElem == null) { | |
| 343 return null; | |
| 344 } | |
| 345 _resolvedUnits = <CompilationUnitElement>[]; | |
| 346 for (CompilationUnitElement unresolvedUnit in libElem.units) { | |
| 347 CompilationUnit unit = await _computeAsync( | |
| 348 this, | |
| 349 new LibrarySpecificUnit(libElem.source, unresolvedUnit.source), | |
| 350 RESOLVED_UNIT5, | |
| 351 performance, | |
| 352 'resolve library unit'); | |
| 353 checkAborted(); | |
| 354 CompilationUnitElement resolvedUnit = unit?.element; | |
| 355 if (resolvedUnit != null) { | |
| 356 _resolvedUnits.add(resolvedUnit); | |
| 357 } | |
| 358 } | |
| 359 return _resolvedUnits; | |
| 360 } | |
| 361 | |
| 362 /** | 235 /** |
| 363 * Update the completion [target] and [dotTarget] based on the given [unit]. | 236 * Update the completion [target] and [dotTarget] based on the given [unit]. |
| 364 */ | 237 */ |
| 365 void _updateTargets(CompilationUnit unit) { | 238 void _updateTargets(CompilationUnit unit) { |
| 366 _opType = null; | 239 _opType = null; |
| 367 dotTarget = null; | 240 dotTarget = null; |
| 368 target = new CompletionTarget.forOffset(unit, offset); | 241 target = new CompletionTarget.forOffset(unit, offset); |
| 369 AstNode node = target.containingNode; | 242 AstNode node = target.containingNode; |
| 370 if (node is MethodInvocation) { | 243 if (node is MethodInvocation) { |
| 371 if (identical(node.methodName, target.entity)) { | 244 if (identical(node.methodName, target.entity)) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 request.context, | 314 request.context, |
| 442 request.resourceProvider, | 315 request.resourceProvider, |
| 443 libSource, | 316 libSource, |
| 444 request.source, | 317 request.source, |
| 445 request.offset, | 318 request.offset, |
| 446 unit, | 319 unit, |
| 447 request, | 320 request, |
| 448 performance, | 321 performance, |
| 449 request.ideOptions); | 322 request.ideOptions); |
| 450 | 323 |
| 451 // Resolve the expression in which the completion occurs | |
| 452 // to properly determine if identifiers should be suggested | |
| 453 // rather than invocations. | |
| 454 if (dartRequest.target.maybeFunctionalArgument()) { | |
| 455 AstNode node = dartRequest.target.containingNode.parent; | |
| 456 if (node is Expression) { | |
| 457 const FUNCTIONAL_ARG_TAG = 'resolve expression for isFunctionalArg'; | |
| 458 performance.logStartTime(FUNCTIONAL_ARG_TAG); | |
| 459 await dartRequest.resolveContainingExpression(node); | |
| 460 performance.logElapseTime(FUNCTIONAL_ARG_TAG); | |
| 461 dartRequest.checkAborted(); | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 performance.logElapseTime(BUILD_REQUEST_TAG); | 324 performance.logElapseTime(BUILD_REQUEST_TAG); |
| 466 return dartRequest; | 325 return dartRequest; |
| 467 } | 326 } |
| 468 | 327 |
| 469 static Future _computeAsync( | 328 static Future _computeAsync( |
| 470 CompletionRequest request, | 329 CompletionRequest request, |
| 471 AnalysisTarget target, | 330 AnalysisTarget target, |
| 472 ResultDescriptor descriptor, | 331 ResultDescriptor descriptor, |
| 473 CompletionPerformance performance, | 332 CompletionPerformance performance, |
| 474 String perfTag) async { | 333 String perfTag) async { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 if (start <= requestOffset && requestOffset <= end) { | 397 if (start <= requestOffset && requestOffset <= end) { |
| 539 // Replacement range for import URI | 398 // Replacement range for import URI |
| 540 return new ReplacementRange(start, end - start); | 399 return new ReplacementRange(start, end - start); |
| 541 } | 400 } |
| 542 } | 401 } |
| 543 } | 402 } |
| 544 } | 403 } |
| 545 return new ReplacementRange(requestOffset, 0); | 404 return new ReplacementRange(requestOffset, 0); |
| 546 } | 405 } |
| 547 } | 406 } |
| OLD | NEW |