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

Unified Diff: pkg/analysis_server/lib/src/services/completion/imported_computer.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
Index: pkg/analysis_server/lib/src/services/completion/imported_computer.dart
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
index d9be1da3ba1bc6dc2e2612540223b600f4031ede..0ac302a9329888ce0df900bd649e6454ab2a64f6 100644
--- a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
@@ -9,14 +9,12 @@ import 'dart:collection';
import 'package:analysis_server/src/protocol_server.dart' hide Element,
ElementKind;
+import 'package:analysis_server/src/services/completion/dart_completion_cache.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/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
/**
* A computer for calculating imported class and top level variable
@@ -29,7 +27,7 @@ class ImportedComputer extends DartCompletionComputer {
bool computeFast(DartCompletionRequest request) {
builder = request.node.accept(new _ImportedAstVisitor(request));
if (builder != null) {
- return builder.computeFast();
+ return builder.computeFast(request.node);
}
return true;
}
@@ -212,13 +210,11 @@ class _ImportedAstVisitor extends
* [_ImportedSuggestionBuilder] traverses the imports and builds suggestions
* based upon imported elements.
*/
-class _ImportedSuggestionBuilder {
+class _ImportedSuggestionBuilder implements SuggestionBuilder {
final DartCompletionRequest request;
final bool typesOnly;
final bool excludeVoidReturn;
- final HashSet<String> completions = new HashSet();
DartCompletionCache cache;
- String importKey;
_ImportedSuggestionBuilder(this.request, {this.typesOnly: false,
this.excludeVoidReturn: false}) {
@@ -226,118 +222,14 @@ class _ImportedSuggestionBuilder {
}
/**
- * Compute a hash of the import directives.
- */
- String get computeImportKey {
- if (importKey == null) {
- StringBuffer sb = new StringBuffer();
- request.unit.directives.forEach((Directive directive) {
- if (directive is ImportDirective) {
- sb.write(directive.toSource());
- }
- });
- importKey = sb.toString();
- }
- return importKey;
- }
-
- void addCachedSuggestions() {
- DartCompletionCache cache = request.cache;
- request.suggestions
- ..addAll(cache.importedTypeSuggestions)
- ..addAll(cache.libraryPrefixSuggestions);
- if (!typesOnly) {
- request.suggestions.addAll(cache.otherImportedSuggestions);
- if (!excludeVoidReturn) {
- request.suggestions.addAll(cache.importedVoidReturnSuggestions);
- }
- }
- }
-
- 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);
- }
- cache.libraryPrefixSuggestions.add(suggestion);
- completions.add(suggestion.completion);
- }
- }
-
- void addSuggestion(Element element, CompletionRelevance relevance) {
-
- if (element is ExecutableElement) {
- if (element.isOperator) {
- return;
- }
- }
-
- String completion = element.displayName;
- CompletionSuggestion suggestion = new CompletionSuggestion(
- CompletionSuggestionKind.INVOCATION,
- element.isDeprecated ? CompletionRelevance.LOW : relevance,
- completion,
- completion.length,
- 0,
- element.isDeprecated,
- false);
-
- suggestion.element = newElement_fromEngine(element);
-
- DartType type;
- if (element is FunctionElement) {
- type = element.returnType;
- } else if (element is PropertyAccessorElement && element.isGetter) {
- type = element.returnType;
- } else if (element is TopLevelVariableElement) {
- type = element.type;
- }
- if (type != null) {
- String name = type.displayName;
- if (name != null && name.length > 0 && name != 'dynamic') {
- suggestion.returnType = name;
- }
- }
-
- if (element is ExecutableElement) {
- DartType returnType = element.returnType;
- if (returnType != null && returnType.isVoid) {
- cache.importedVoidReturnSuggestions.add(suggestion);
- } else {
- cache.otherImportedSuggestions.add(suggestion);
- }
- } else if (element is ClassElement) {
- cache.importedTypeSuggestions.add(suggestion);
- } else {
- cache.otherImportedSuggestions.add(suggestion);
- }
- completions.add(suggestion.completion);
- }
-
- void addSuggestions(List<Element> elements) {
- elements.forEach((Element elem) {
- addSuggestion(elem, CompletionRelevance.DEFAULT);
- });
- }
-
- /**
* If the needed information is cached, then add suggestions and return `true`
* else return `false` indicating that additional work is necessary.
*/
- bool computeFast() {
- if (cache.importKey == computeImportKey) {
- addCachedSuggestions();
+ bool computeFast(AstNode node) {
+ CompilationUnit unit = request.unit;
+ if (cache.isImportInfoCached(unit)) {
+ _addInheritedSuggestions(node);
+ _addTopLevelSuggestions();
return true;
}
return false;
@@ -346,99 +238,84 @@ class _ImportedSuggestionBuilder {
/**
* Compute suggested based upon imported elements.
*/
- computeFull(AstNode node) {
- CompilationUnit unit = node.getAncestor((p) => p is CompilationUnit);
- cache.importedTypeSuggestions = <CompletionSuggestion>[];
- cache.libraryPrefixSuggestions = <CompletionSuggestion>[];
- cache.otherImportedSuggestions = <CompletionSuggestion>[];
- cache.importedVoidReturnSuggestions = <CompletionSuggestion>[];
-
- // 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
- Map<String, ClassElement> classMap = new Map<String, ClassElement>();
- 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) {
- classMap[name] = elem;
- }
- addSuggestion(elem, CompletionRelevance.DEFAULT);
- });
- } else {
- // Exclude elements from prefixed imports
- // because they are provided by InvocationComputer
- excludedLibs.add(importElem.importedLibrary);
- addLibraryPrefixSuggestion(importElem);
- }
- }
- }
+ Future<bool> computeFull(AstNode node) {
+ return cache.computeImportInfo(
+ request.unit,
+ request.searchEngine).then((_) {
+ _addInheritedSuggestions(node);
+ _addTopLevelSuggestions();
+ return true;
});
+ }
- // Include implicitly imported dart:core elements
- Source coreUri = request.context.sourceFactory.forUri('dart:core');
- LibraryElement coreLib = request.context.getLibraryElement(coreUri);
- Namespace coreNamespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
- coreNamespace.definedNames.forEach((String name, Element elem) {
- if (elem is ClassElement) {
- classMap[name] = elem;
+ /**
+ * Add imported element suggestions.
+ */
+ void _addElementSuggestions(List<Element> elements) {
+ elements.forEach((Element elem) {
+ if (elem is! ClassElement) {
+ if (typesOnly) {
+ return;
+ }
+ if (elem is ExecutableElement) {
+ if (elem.isOperator) {
+ return;
+ }
+ DartType returnType = elem.returnType;
+ if (returnType != null && returnType.isVoid) {
+ if (excludeVoidReturn) {
+ return;
+ }
+ }
+ }
}
- addSuggestion(elem, CompletionRelevance.DEFAULT);
+ request.suggestions.add(
+ createElementSuggestion(elem, relevance: CompletionRelevance.DEFAULT));
});
+ }
- // Build a list of inherited types that are imported
- // and include any inherited imported members
+ /**
+ * Add suggestions for any inherited imported members.
+ */
+ void _addInheritedSuggestions(AstNode node) {
var classDecl = node.getAncestor((p) => p is ClassDeclaration);
if (classDecl is ClassDeclaration) {
+ // Build a list of inherited types that are imported
+ // and include any inherited imported members
List<String> inheritedTypes = new List<String>();
- visitInheritedTypes(classDecl, (ClassDeclaration classDecl) {
- // ignored
+ visitInheritedTypes(classDecl, (_) {
+ // local declarations are handled by the local computer
}, (String typeName) {
inheritedTypes.add(typeName);
});
- Set<String> visited = new Set<String>();
+ HashSet<String> visited = new HashSet<String>();
while (inheritedTypes.length > 0) {
String name = inheritedTypes.removeLast();
- ClassElement elem = classMap[name];
+ ClassElement elem = cache.importedClassMap[name];
if (visited.add(name) && elem != null) {
- addSuggestions(elem.accessors);
- addSuggestions(elem.methods);
+ _addElementSuggestions(elem.accessors);
+ _addElementSuggestions(elem.methods);
elem.allSupertypes.forEach((InterfaceType type) {
if (visited.add(type.name)) {
- addSuggestions(type.accessors);
- addSuggestions(type.methods);
+ _addElementSuggestions(type.accessors);
+ _addElementSuggestions(type.methods);
}
});
}
}
}
+ }
- // Add non-imported elements as low relevance
- var future = request.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) &&
- !completions.contains(element.displayName)) {
- addSuggestion(element, CompletionRelevance.LOW);
- }
- }
- });
- cache.importKey = computeImportKey;
- addCachedSuggestions();
- return true;
- });
+ void _addTopLevelSuggestions() {
+ DartCompletionCache cache = request.cache;
+ request.suggestions
+ ..addAll(cache.importedTypeSuggestions)
+ ..addAll(cache.libraryPrefixSuggestions);
+ if (!typesOnly) {
+ request.suggestions.addAll(cache.otherImportedSuggestions);
+ if (!excludeVoidReturn) {
+ request.suggestions.addAll(cache.importedVoidReturnSuggestions);
+ }
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698