| Index: pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
|
| diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
|
| index 759a74156949c829c095fd69c3c5df376af2c122..452e2bf07a22c10ae009341c23428af6c3d5b923 100644
|
| --- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
|
| +++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
|
| @@ -31,24 +31,17 @@ import 'package:analyzer/task/dart.dart';
|
| class DartCompletionManager implements CompletionContributor {
|
| @override
|
| Future<List<CompletionSuggestion>> computeSuggestions(
|
| - CompletionRequest request) {
|
| - if (AnalysisEngine.isDartFileName(request.source.shortName)) {
|
| - return _computeDartSuggestions(
|
| - new DartCompletionRequestImpl.forRequest(request));
|
| + CompletionRequest request) async {
|
| + if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
|
| + return EMPTY_LIST;
|
| }
|
| - return new Future.value();
|
| - }
|
|
|
| - /**
|
| - * Return a [Future] that completes with a list of suggestions
|
| - * for the given completion [request].
|
| - */
|
| - Future<List<CompletionSuggestion>> _computeDartSuggestions(
|
| - DartCompletionRequest request) async {
|
| // Request Dart specific completions from each contributor
|
| + DartCompletionRequestImpl dartRequest =
|
| + await DartCompletionRequestImpl.from(request);
|
| List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
|
| for (DartCompletionContributor c in dartCompletionPlugin.contributors) {
|
| - suggestions.addAll(await c.computeSuggestions(request));
|
| + suggestions.addAll(await c.computeSuggestions(dartRequest));
|
| }
|
| return suggestions;
|
| }
|
| @@ -60,64 +53,71 @@ class DartCompletionManager implements CompletionContributor {
|
| class DartCompletionRequestImpl extends CompletionRequestImpl
|
| implements DartCompletionRequest {
|
| /**
|
| - * The source for the library containing the completion request.
|
| - * This may be different from the source in which the completion is requested
|
| - * if the completion is being requested in a part file.
|
| - * This may be `null` if the library for a part file cannot be determined.
|
| - */
|
| - Source _librarySource;
|
| -
|
| - /**
|
| - * The [DartType] for Object in dart:core
|
| - */
|
| - InterfaceType _objectType;
|
| -
|
| - /**
|
| - * `true` if [resolveDeclarationsInScope] has partially resolved the unit
|
| - * referenced by [target], else `false`.
|
| + * Return a [Future] that completes with a newly created completion request
|
| + * based on the given [request].
|
| */
|
| - bool _haveResolveDeclarationsInScope = false;
|
| + static Future<DartCompletionRequest> from(CompletionRequest request) async {
|
| + Source source = request.source;
|
| + AnalysisContext context = request.context;
|
| + CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
|
|
|
| - @override
|
| - Expression dotTarget;
|
| + Source libSource;
|
| + if (unit.directives.any((d) => d is PartOfDirective)) {
|
| + List<Source> libraries = context.getLibrariesContaining(source);
|
| + if (libraries.isNotEmpty) {
|
| + libSource = libraries[0];
|
| + }
|
| + } else {
|
| + libSource = source;
|
| + }
|
|
|
| - @override
|
| - CompletionTarget target;
|
| + // Most (all?) contributors need declarations in scope to be resolved
|
| + if (libSource != null) {
|
| + unit = await new AnalysisFutureHelper<CompilationUnit>(context,
|
| + new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
|
| + .computeAsync();
|
| + }
|
|
|
| - /**
|
| - * Initialize a newly created completion request based on the given request.
|
| - */
|
| - factory DartCompletionRequestImpl.forRequest(CompletionRequest request) {
|
| return new DartCompletionRequestImpl._(
|
| request.context,
|
| request.resourceProvider,
|
| request.searchEngine,
|
| + libSource,
|
| request.source,
|
| - request.offset);
|
| + request.offset,
|
| + unit);
|
| }
|
|
|
| DartCompletionRequestImpl._(
|
| AnalysisContext context,
|
| ResourceProvider resourceProvider,
|
| SearchEngine searchEngine,
|
| + this.librarySource,
|
| Source source,
|
| - int offset)
|
| + int offset,
|
| + CompilationUnit unit)
|
| : super(context, resourceProvider, searchEngine, source, offset) {
|
| - _updateTargets(context.computeResult(source, PARSED_UNIT));
|
| - if (target.unit.directives.any((d) => d is PartOfDirective)) {
|
| - List<Source> libraries = context.getLibrariesContaining(source);
|
| - if (libraries.isNotEmpty) {
|
| - _librarySource = libraries[0];
|
| - }
|
| - } else {
|
| - _librarySource = source;
|
| - }
|
| + _updateTargets(unit);
|
| }
|
|
|
| + /**
|
| + * The [DartType] for Object in dart:core
|
| + */
|
| + InterfaceType _objectType;
|
| +
|
| + @override
|
| + Expression dotTarget;
|
| +
|
| + @override
|
| + Source librarySource;
|
| +
|
| + @override
|
| + CompletionTarget target;
|
| +
|
| @override
|
| Future<LibraryElement> get libraryElement async {
|
| //TODO(danrubel) build the library element rather than all the declarations
|
| - CompilationUnit unit = await resolveDeclarationsInScope();
|
| + CompilationUnit unit = target.unit;
|
| if (unit != null) {
|
| CompilationUnitElement elem = unit.element;
|
| if (elem != null) {
|
| @@ -138,47 +138,15 @@ class DartCompletionRequestImpl extends CompletionRequestImpl
|
| }
|
|
|
| @override
|
| - Future<CompilationUnit> resolveDeclarationsInScope() async {
|
| - CompilationUnit unit = target.unit;
|
| - if (_haveResolveDeclarationsInScope) {
|
| - return unit;
|
| - }
|
| -
|
| - // Gracefully degrade if librarySource cannot be determined
|
| - if (_librarySource == null) {
|
| - return null;
|
| - }
|
| -
|
| - // Resolve declarations in the target unit
|
| - CompilationUnit resolvedUnit =
|
| - await new AnalysisFutureHelper<CompilationUnit>(context,
|
| - new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT3)
|
| - .computeAsync();
|
| -
|
| - // TODO(danrubel) determine if the underlying source has been modified
|
| - // in a way that invalidates the completion request
|
| - // and return null
|
| -
|
| - // Gracefully degrade if unit cannot be resolved
|
| - if (resolvedUnit == null) {
|
| - return null;
|
| - }
|
| -
|
| - // Recompute the target for the newly resolved unit
|
| - _updateTargets(resolvedUnit);
|
| - _haveResolveDeclarationsInScope = true;
|
| - return resolvedUnit;
|
| - }
|
| -
|
| - @override
|
| Future<List<Directive>> resolveDirectives() async {
|
| CompilationUnit libUnit;
|
| - if (_librarySource == source) {
|
| - libUnit = await resolveDeclarationsInScope();
|
| - } else if (_librarySource != null) {
|
| + if (librarySource == source) {
|
| + libUnit = target.unit;
|
| + } else if (librarySource != null) {
|
| + // TODO(danrubel) only resolve the directives
|
| libUnit = await new AnalysisFutureHelper<CompilationUnit>(
|
| context,
|
| - new LibrarySpecificUnit(_librarySource, _librarySource),
|
| + new LibrarySpecificUnit(librarySource, librarySource),
|
| RESOLVED_UNIT3)
|
| .computeAsync();
|
| }
|
| @@ -187,18 +155,22 @@ class DartCompletionRequestImpl extends CompletionRequestImpl
|
|
|
| @override
|
| Future resolveExpression(Expression expression) async {
|
| - //TODO(danrubel) resolve the expression or containing method
|
| - // rather than the entire complilation unit
|
| + // Return immediately if the expression has already been resolved
|
| + if (expression.propagatedType != null) {
|
| + return;
|
| + }
|
|
|
| // Gracefully degrade if librarySource cannot be determined
|
| - if (_librarySource == null) {
|
| - return null;
|
| + if (librarySource == null) {
|
| + return;
|
| }
|
|
|
| // Resolve declarations in the target unit
|
| + // TODO(danrubel) resolve the expression or containing method
|
| + // rather than the entire complilation unit
|
| CompilationUnit resolvedUnit =
|
| await new AnalysisFutureHelper<CompilationUnit>(context,
|
| - new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT)
|
| + new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
|
| .computeAsync();
|
|
|
| // TODO(danrubel) determine if the underlying source has been modified
|
| @@ -207,12 +179,11 @@ class DartCompletionRequestImpl extends CompletionRequestImpl
|
|
|
| // Gracefully degrade if unit cannot be resolved
|
| if (resolvedUnit == null) {
|
| - return null;
|
| + return;
|
| }
|
|
|
| // Recompute the target for the newly resolved unit
|
| _updateTargets(resolvedUnit);
|
| - _haveResolveDeclarationsInScope = true;
|
| }
|
|
|
| /**
|
|
|