| Index: pkg/analysis_server/lib/src/services/completion/completion_dart.dart
|
| diff --git a/pkg/analysis_server/lib/src/services/completion/completion_dart.dart b/pkg/analysis_server/lib/src/services/completion/completion_dart.dart
|
| index 1cfff042d6017ca98311ae8b46b881391146b2e3..1ccc28b5ede0492ae4196f3eb6b56c3b058f60b1 100644
|
| --- a/pkg/analysis_server/lib/src/services/completion/completion_dart.dart
|
| +++ b/pkg/analysis_server/lib/src/services/completion/completion_dart.dart
|
| @@ -4,11 +4,21 @@
|
|
|
| library analysis_server.src.services.completion.completion_dart;
|
|
|
| -import 'package:analysis_server/src/provisional/completion/completion_core.dart';
|
| +import 'dart:async';
|
| +
|
| +import 'package:analysis_server/src/provisional/completion/completion_core.dart'
|
| + show CompletionRequest;
|
| import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
|
| import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
|
| import 'package:analysis_server/src/services/completion/completion_core.dart';
|
| +import 'package:analyzer/file_system/file_system.dart';
|
| +import 'package:analyzer/src/context/context.dart'
|
| + show AnalysisFutureHelper, AnalysisContextImpl;
|
| import 'package:analyzer/src/generated/ast.dart';
|
| +import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/task/dart.dart';
|
| +import 'package:analyzer/task/dart.dart';
|
|
|
| /**
|
| * The information about a requested list of completions within a Dart file.
|
| @@ -16,26 +26,75 @@ import 'package:analyzer/src/generated/ast.dart';
|
| class DartCompletionRequestImpl extends CompletionRequestImpl
|
| implements DartCompletionRequest {
|
| /**
|
| - * The compilation unit in which the completion was requested.
|
| + * The cached completion target or `null` if not computed yet.
|
| */
|
| - final CompilationUnit unit;
|
| + CompletionTarget _target;
|
|
|
| /**
|
| - * A flag indicating whether the compilation [unit] is resolved.
|
| + * `true` if [resolveDeclarationsInScope] has partially resolved the unit
|
| + * referenced by [target], else `false`.
|
| */
|
| - final bool isResolved;
|
| + bool _haveResolveDeclarationsInScope = false;
|
|
|
| /**
|
| - * The completion target. This determines what part of the parse tree
|
| - * will receive the newly inserted text.
|
| + * Initialize a newly created completion request based on the given request.
|
| */
|
| - final CompletionTarget target;
|
| + factory DartCompletionRequestImpl.forRequest(CompletionRequest request) {
|
| + return new DartCompletionRequestImpl._(request.context,
|
| + request.resourceProvider, request.source, request.offset);
|
| + }
|
|
|
| - /**
|
| - * Initialize a newly created completion request based on the given arguments.
|
| - */
|
| - DartCompletionRequestImpl(
|
| - CompletionRequest request, this.unit, this.isResolved, this.target)
|
| - : super(request.context, request.resourceProvider, request.source,
|
| - request.offset);
|
| + DartCompletionRequestImpl._(AnalysisContext context,
|
| + ResourceProvider resourceProvider, Source source, int offset)
|
| + : super(context, resourceProvider, source, offset);
|
| +
|
| + @override
|
| + Future<CompilationUnit> resolveDeclarationsInScope() async {
|
| + CompilationUnit unit = target.unit;
|
| + if (_haveResolveDeclarationsInScope) {
|
| + return unit;
|
| + }
|
| +
|
| + // Determine the library source
|
| + Source librarySource;
|
| + if (unit.directives.any((d) => d is PartOfDirective)) {
|
| + List<Source> libraries = context.getLibrariesContaining(source);
|
| + if (libraries.isEmpty) {
|
| + return null;
|
| + }
|
| + librarySource = libraries[0];
|
| + } else {
|
| + librarySource = source;
|
| + }
|
| +
|
| + // 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
|
| + _target = new CompletionTarget.forOffset(resolvedUnit, offset);
|
| + _haveResolveDeclarationsInScope = true;
|
| + return resolvedUnit;
|
| + }
|
| +
|
| + @override
|
| + CompletionTarget get target {
|
| + if (_target == null) {
|
| + CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
|
| + _target = new CompletionTarget.forOffset(unit, offset);
|
| + }
|
| + return _target;
|
| + }
|
| }
|
|
|