| Index: pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
|
| diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
|
| deleted file mode 100644
|
| index 5a33c9277db69c77af5dd02e02b5d0776180f168..0000000000000000000000000000000000000000
|
| --- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
|
| +++ /dev/null
|
| @@ -1,358 +0,0 @@
|
| -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -library services.completion.dart.cache;
|
| -
|
| -import 'dart:async';
|
| -import 'dart:collection';
|
| -
|
| -import 'package:analysis_server/src/protocol_server.dart'
|
| - hide Element, ElementKind;
|
| -import 'package:analysis_server/src/services/completion/completion_manager.dart';
|
| -import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
|
| -import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
|
| -import 'package:analysis_server/src/services/search/search_engine.dart';
|
| -import 'package:analyzer/dart/element/element.dart';
|
| -import 'package:analyzer/dart/element/type.dart';
|
| -import 'package:analyzer/src/generated/ast.dart';
|
| -import 'package:analyzer/src/generated/engine.dart';
|
| -import 'package:analyzer/src/generated/resolver.dart';
|
| -import 'package:analyzer/src/generated/source.dart';
|
| -import 'package:analyzer/src/task/dart.dart';
|
| -
|
| -/**
|
| - * The `DartCompletionCache` contains cached information from a prior code
|
| - * completion operation.
|
| - */
|
| -class DartCompletionCache extends CompletionCache {
|
| - /**
|
| - * A hash of the import directives
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - String _importKey;
|
| -
|
| - /**
|
| - * Type suggestions based upon imports,
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - List<CompletionSuggestion> importedTypeSuggestions;
|
| -
|
| - /**
|
| - * Suggestions for methods and functions that have void return type,
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - List<CompletionSuggestion> importedVoidReturnSuggestions;
|
| -
|
| - /**
|
| - * Other suggestions based upon imports,
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - List<CompletionSuggestion> otherImportedSuggestions;
|
| -
|
| - /**
|
| - * Suggestions for constructors
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - List<CompletionSuggestion> importedConstructorSuggestions;
|
| -
|
| - /**
|
| - * A collection of all imported completions
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - HashSet<String> _importedCompletions;
|
| -
|
| - /**
|
| - * A map of simple identifier to imported class element
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - Map<String, ClassElement> importedClassMap;
|
| -
|
| - /**
|
| - * The [ClassElement] for Object.
|
| - */
|
| - ClassElement _objectClassElement;
|
| -
|
| - DartCompletionCache(AnalysisContext context, Source source)
|
| - : super(context, source);
|
| -
|
| - /**
|
| - * Return a hash of the import directives for the cached import info
|
| - * or `null` if nothing has been cached.
|
| - */
|
| - String get importKey => _importKey;
|
| -
|
| - /**
|
| - * Return the [ClassElement] for Object.
|
| - */
|
| - ClassElement get objectClassElement {
|
| - if (_objectClassElement == null) {
|
| - Source coreUri = context.sourceFactory.forUri('dart:core');
|
| - LibraryElement coreLib = context.getResult(coreUri, LIBRARY_ELEMENT8);
|
| - _objectClassElement = coreLib.getType('Object');
|
| - }
|
| - return _objectClassElement;
|
| - }
|
| -
|
| - /**
|
| - * Given a resolved compilation unit, compute suggestions based upon the
|
| - * imports and other dart files (e.g. "part" files) in the library containing
|
| - * the given compilation unit. The returned future completes when the cache
|
| - * is populated.
|
| - *
|
| - * If [shouldWaitForLowPrioritySuggestions] is `true` then the returned
|
| - * future will complete when the cache is fully populated. If `false`,
|
| - * the returned future will complete sooner, but the cache will not include
|
| - * the lower priority suggestions added as a result of a global search.
|
| - * In this case, those lower priority suggestions will be added later
|
| - * when the index has been updated and the global search completes.
|
| - */
|
| - Future<bool> computeImportInfo(CompilationUnit unit,
|
| - SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
|
| - importedTypeSuggestions = <CompletionSuggestion>[];
|
| - otherImportedSuggestions = <CompletionSuggestion>[];
|
| - importedConstructorSuggestions = <CompletionSuggestion>[];
|
| - importedVoidReturnSuggestions = <CompletionSuggestion>[];
|
| - importedClassMap = new Map<String, ClassElement>();
|
| - _importedCompletions = new HashSet<String>();
|
| -
|
| - // Assert that the compilation unit is resolved
|
| - // and represents the expected source
|
| - assert(unit.element.source == source);
|
| -
|
| - // Exclude elements from local library
|
| - // because they are provided by LocalReferenceContributor
|
| - Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
|
| - excludedLibs.add(unit.element.enclosingElement);
|
| -
|
| - // Determine the compilation unit defining the library containing
|
| - // this compilation unit
|
| - List<Source> libraries = context.getLibrariesContaining(source);
|
| - assert(libraries != null);
|
| - Source libSource = libraries.length > 0 ? libraries[0] : null;
|
| - Future<CompilationUnit> futureLibUnit = _computeLibUnit(libSource, unit);
|
| -
|
| - // Include implicitly imported dart:core elements
|
| - _addDartCoreSuggestions();
|
| -
|
| - // Include explicitly imported and part elements
|
| - Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
|
| - _addImportedElemSuggestions(libSource, libUnit, excludedLibs);
|
| - // Don't wait for search of lower relevance results to complete.
|
| - // Set key indicating results are ready, and lower relevance results
|
| - // will be added to the cache when the search completes.
|
| - _importKey = _computeImportKey(unit);
|
| - return true;
|
| - });
|
| -
|
| - // Add non-imported elements as low relevance
|
| - // after the imported element suggestions have been added
|
| - Future<bool> futureAllCached = futureImportsCached.then((_) {
|
| - return searchEngine
|
| - .searchTopLevelDeclarations('')
|
| - .then((List<SearchMatch> matches) {
|
| - _addNonImportedElementSuggestions(matches, excludedLibs);
|
| - return true;
|
| - });
|
| - });
|
| -
|
| - return shouldWaitForLowPrioritySuggestions
|
| - ? futureAllCached
|
| - : futureImportsCached;
|
| - }
|
| -
|
| - /**
|
| - * Return `true` if the import information is cached for the given
|
| - * compilation unit.
|
| - */
|
| - bool isImportInfoCached(CompilationUnit unit) =>
|
| - _importKey != null && _importKey == _computeImportKey(unit);
|
| -
|
| - /**
|
| - * Add constructor suggestions for the given class.
|
| - */
|
| - void _addConstructorSuggestions(
|
| - ClassElement classElem, int relevance, Source importForSource) {
|
| - String className = classElem.name;
|
| - for (ConstructorElement constructor in classElem.constructors) {
|
| - if (!constructor.isPrivate) {
|
| - CompletionSuggestion suggestion = createSuggestion(constructor,
|
| - relevance: relevance, importForSource: importForSource);
|
| - if (suggestion != null) {
|
| - String name = suggestion.completion;
|
| - name = name.length > 0 ? '$className.$name' : className;
|
| - suggestion.completion = name;
|
| - suggestion.selectionOffset = suggestion.completion.length;
|
| - importedConstructorSuggestions.add(suggestion);
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Add suggestions for implicitly imported elements in dart:core.
|
| - */
|
| - void _addDartCoreSuggestions() {
|
| - Source coreUri = context.sourceFactory.forUri('dart:core');
|
| - LibraryElement coreLib = context.getResult(coreUri, LIBRARY_ELEMENT8);
|
| - if (coreLib == null) {
|
| - // If the core library has not been analyzed yet, then we cannot add any
|
| - // suggestions from it.
|
| - return;
|
| - }
|
| - Namespace coreNamespace =
|
| - new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
|
| - coreNamespace.definedNames.forEach((String name, Element elem) {
|
| - if (elem is ClassElement) {
|
| - importedClassMap[name] = elem;
|
| - }
|
| - _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Add suggestions for explicitly imported and part elements in the given
|
| - * library. Add libraries that should not have their elements suggested
|
| - * even as low priority to [excludedLibs].
|
| - */
|
| - void _addImportedElemSuggestions(Source libSource, CompilationUnit libUnit,
|
| - Set<LibraryElement> excludedLibs) {
|
| - if (libUnit != null) {
|
| - libUnit.directives.forEach((Directive directive) {
|
| - if (directive is ImportDirective) {
|
| - ImportElement importElem = directive.element;
|
| - if (importElem != null && importElem.importedLibrary != null) {
|
| - if (directive.prefix == null) {
|
| - Namespace importNamespace = new NamespaceBuilder()
|
| - .createImportNamespaceForDirective(importElem);
|
| - // Include top level elements
|
| - importNamespace.definedNames.forEach((String name, Element elem) {
|
| - if (elem is ClassElement) {
|
| - importedClassMap[name] = elem;
|
| - }
|
| - _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
|
| - });
|
| - } else {
|
| - // Exclude elements from prefixed imports
|
| - // because they are provided by PrefixedElementContributor
|
| - // Suggested by LibraryPrefixContributor
|
| - // _addLibraryPrefixSuggestion(importElem);
|
| - // excludedLibs.add(importElem.importedLibrary);
|
| - }
|
| - }
|
| - } else if (directive is PartDirective) {
|
| - // Suggested by LocalLibraryContributor
|
| - // CompilationUnitElement partElem = directive.element;
|
| - // if (partElem != null && partElem.source != source) {
|
| - // partElem.accept(new _NonLocalElementCacheVisitor(this));
|
| - // }
|
| - }
|
| - });
|
| - if (libSource != source) {
|
| - // Suggested by LocalLibraryContributor
|
| - // libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Add suggestions for all top level elements in the context
|
| - * excluding those elemnents for which suggestions have already been added.
|
| - */
|
| - void _addNonImportedElementSuggestions(
|
| - List<SearchMatch> matches, Set<LibraryElement> excludedLibs) {
|
| - // Exclude internal Dart SDK libraries
|
| - for (var lib in context.sourceFactory.dartSdk.sdkLibraries) {
|
| - if (lib.isInternal) {
|
| - Source libUri = context.sourceFactory.forUri(lib.shortName);
|
| - if (libUri != null) {
|
| - LibraryElement libElem = context.getResult(libUri, LIBRARY_ELEMENT8);
|
| - if (libElem != null) {
|
| - excludedLibs.add(libElem);
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
|
| - matches.forEach((SearchMatch match) {
|
| - if (match.kind == MatchKind.DECLARATION) {
|
| - Element element = match.element;
|
| - if ((element.context == context || element.context == sdkContext) &&
|
| - element.isPublic &&
|
| - !excludedLibs.contains(element.library) &&
|
| - !_importedCompletions.contains(element.displayName)) {
|
| - _addSuggestion(element, DART_RELEVANCE_LOW, importForSource: source);
|
| - }
|
| - }
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Add a suggestion for the given element.
|
| - */
|
| - void _addSuggestion(Element element, int relevance,
|
| - {Source importForSource}) {
|
| - if (element is ExecutableElement) {
|
| - // Do not suggest operators or local functions
|
| - if (element.isOperator) {
|
| - return;
|
| - }
|
| - if (element is FunctionElement) {
|
| - if (element.enclosingElement is! CompilationUnitElement) {
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -
|
| - CompletionSuggestion suggestion = createSuggestion(element,
|
| - relevance: relevance, importForSource: importForSource);
|
| -
|
| - if (suggestion != null) {
|
| - if (element is ExecutableElement) {
|
| - DartType returnType = element.returnType;
|
| - if (returnType != null && returnType.isVoid) {
|
| - importedVoidReturnSuggestions.add(suggestion);
|
| - } else {
|
| - otherImportedSuggestions.add(suggestion);
|
| - }
|
| - } else if (element is FunctionTypeAliasElement) {
|
| - importedTypeSuggestions.add(suggestion);
|
| - } else if (element is ClassElement) {
|
| - importedTypeSuggestions.add(suggestion);
|
| - _addConstructorSuggestions(element, relevance, importForSource);
|
| - } else {
|
| - otherImportedSuggestions.add(suggestion);
|
| - }
|
| - _importedCompletions.add(suggestion.completion);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Compute the hash of the imports for the given compilation unit.
|
| - */
|
| - String _computeImportKey(CompilationUnit unit) {
|
| - StringBuffer sb = new StringBuffer();
|
| - unit.directives.forEach((Directive directive) {
|
| - sb.write(directive.toSource());
|
| - });
|
| - return sb.toString();
|
| - }
|
| -
|
| - /**
|
| - * Compute the library unit for the given library source,
|
| - * where the [unit] is the resolved compilation unit associated with [source].
|
| - */
|
| - Future<CompilationUnit> _computeLibUnit(
|
| - Source libSource, CompilationUnit unit) {
|
| - // If the sources are the same then we already have the library unit
|
| - if (libSource == source) {
|
| - return new Future.value(unit);
|
| - }
|
| - // If [source] is a part, then compute the library unit
|
| - if (libSource != null) {
|
| - return context.computeResolvedCompilationUnitAsync(libSource, libSource);
|
| - }
|
| - return new Future.value(null);
|
| - }
|
| -}
|
|
|