Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Unified Diff: pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart

Issue 752833002: refactor import caching to exclude suggestions for inherited members (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: cleanup unused imports Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
new file mode 100644
index 0000000000000000000000000000000000000000..2053b343920559273f4b2741ce0222707347232d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
@@ -0,0 +1,217 @@
+// 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/suggestion_builder.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.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;
+
+ /**
+ * Library prefix suggestions based upon imports,
+ * or `null` if nothing has been cached.
+ */
+ List<CompletionSuggestion> libraryPrefixSuggestions;
+
+ /**
+ * 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;
+
+ /**
+ * 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;
+
+ 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;
+
+ /**
+ * Compute suggestions based upon the imports in the given compilation unit.
+ * Return a future that completes when the information has been cached.
+ */
+ Future<bool> computeImportInfo(CompilationUnit unit,
+ SearchEngine searchEngine) {
+ importedTypeSuggestions = <CompletionSuggestion>[];
+ libraryPrefixSuggestions = <CompletionSuggestion>[];
+ otherImportedSuggestions = <CompletionSuggestion>[];
+ importedVoidReturnSuggestions = <CompletionSuggestion>[];
+ importedClassMap = new Map<String, ClassElement>();
+ _importedCompletions = new HashSet<String>();
+
+ // Exclude elements from local library
+ // because they are provided by LocalComputer
+ Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
+ excludedLibs.add(unit.element.enclosingElement);
+
+ // Include explicitly imported elements
+ unit.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, CompletionRelevance.DEFAULT);
+ });
+ } else {
+ // Exclude elements from prefixed imports
+ // because they are provided by InvocationComputer
+ excludedLibs.add(importElem.importedLibrary);
+ _addLibraryPrefixSuggestion(importElem);
+ }
+ }
+ }
+ });
+
+ // Include implicitly imported dart:core elements
+ Source coreUri = context.sourceFactory.forUri('dart:core');
+ LibraryElement coreLib = context.getLibraryElement(coreUri);
+ Namespace coreNamespace =
+ new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
+ coreNamespace.definedNames.forEach((String name, Element elem) {
+ if (elem is ClassElement) {
+ importedClassMap[name] = elem;
+ }
+ addSuggestion(elem, CompletionRelevance.DEFAULT);
+ });
+
+ // Add non-imported elements as low relevance
+ var future = searchEngine.searchTopLevelDeclarations('');
+ return future.then((List<SearchMatch> matches) {
+ matches.forEach((SearchMatch match) {
+ if (match.kind == MatchKind.DECLARATION) {
+ Element element = match.element;
+ if (element.isPublic &&
+ !excludedLibs.contains(element.library) &&
+ !_importedCompletions.contains(element.displayName)) {
+ addSuggestion(element, CompletionRelevance.LOW);
+ }
+ }
+ });
+ _importKey = _computeImportKey(unit);
+ return true;
+ });
+ }
+
+ /**
+ * Return `true` if the import information is cached for the given
+ * compilation unit.
+ */
+ bool isImportInfoCached(CompilationUnit unit) =>
+ _importKey != null && _importKey == _computeImportKey(unit);
+
+ void _addLibraryPrefixSuggestion(ImportElement importElem) {
+ CompletionSuggestion suggestion = null;
+ String completion = importElem.prefix.displayName;
+ if (completion != null && completion.length > 0) {
+ suggestion = new CompletionSuggestion(
+ CompletionSuggestionKind.INVOCATION,
+ CompletionRelevance.DEFAULT,
+ completion,
+ completion.length,
+ 0,
+ importElem.isDeprecated,
+ false);
+ LibraryElement lib = importElem.importedLibrary;
+ if (lib != null) {
+ suggestion.element = newElement_fromEngine(lib);
+ }
+ libraryPrefixSuggestions.add(suggestion);
+ _importedCompletions.add(suggestion.completion);
+ }
+ }
+
+ void addSuggestion(Element element, CompletionRelevance relevance) {
+
+ if (element is ExecutableElement) {
+ if (element.isOperator) {
+ return;
+ }
+ }
+
+ CompletionSuggestion suggestion =
+ createElementSuggestion(element, relevance: relevance);
+
+ if (element is ExecutableElement) {
+ DartType returnType = element.returnType;
+ if (returnType != null && returnType.isVoid) {
+ importedVoidReturnSuggestions.add(suggestion);
+ } else {
+ otherImportedSuggestions.add(suggestion);
+ }
+ } else if (element is ClassElement) {
+ importedTypeSuggestions.add(suggestion);
+ } 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) {
+ if (directive is ImportDirective) {
+ sb.write(directive.toSource());
+ }
+ });
+ return sb.toString();
+ }
+}
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698