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

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

Issue 816233002: refactor/cleanup dart completion cache (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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 | no next file » | 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
index 7265c9d7bca98c95ebaf065b86f3fe839d74a72f..dac2eeb889b5501bc9d625b3baf793cde3385eea 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
@@ -81,6 +81,20 @@ class DartCompletionCache extends CompletionCache {
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.getLibraryElement(coreUri);
+ Namespace coreNamespace =
+ new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
+ _objectClassElement = coreNamespace.definedNames['Object'];
scheglov 2014/12/21 04:38:05 Using Namespace seems too heavyweight here. You co
danrubel 2014/12/22 22:06:11 Great suggestion. Done.
+ }
+ 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
@@ -114,59 +128,16 @@ class DartCompletionCache extends CompletionCache {
// Determine the compilation unit defining the library containing
// this compilation unit
List<Source> libraries = context.getLibrariesContaining(source);
- Source libSource = null;
- Future<CompilationUnit> futureLibUnit;
- if (libraries != null && libraries.length > 0) {
- libSource = libraries[0];
- if (libSource == source) {
- // If the sources are the same then we already have the library unit
- futureLibUnit = new Future.value(unit);
- } else {
- // If the sources are different, then get the library unit
- // to traverse the library directives and cache the imported elements
- futureLibUnit =
- context.computeResolvedCompilationUnitAsync(libSource, libSource);
- }
- } else {
- futureLibUnit = new Future.value(null);
- }
+ assert(libraries != null);
+ Source libSource = libraries.length > 0 ? libraries[0] : null;
+ Future<CompilationUnit> futureLibUnit = _computeLibUnit(libSource, unit);
- // Include explicitly imported elements
+ // Include implicitly imported dart:core elements
+ _addDartCoreSuggestions();
+
+ // Include explicitly imported and part elements
Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
- 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, CompletionRelevance.DEFAULT);
- });
- } else {
- // Exclude elements from prefixed imports
- // because they are provided by InvocationComputer
- excludedLibs.add(importElem.importedLibrary);
- _addLibraryPrefixSuggestion(importElem);
- }
- }
- } else if (directive is PartDirective) {
- CompilationUnitElement partElem = directive.element;
- if (partElem != null && partElem.source != source) {
- partElem.accept(new _NonLocalElementCacheVisitor(this));
- }
- }
- });
- if (libSource != source) {
- libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
- }
- }
+ _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.
@@ -174,34 +145,12 @@ class DartCompletionCache extends CompletionCache {
return true;
});
- // 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);
- });
- _objectClassElement = importedClassMap['Object'];
-
// 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) {
- 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);
- }
- }
- });
+ _addNonImportedElementSuggestions(matches, excludedLibs);
return true;
});
});
@@ -212,26 +161,71 @@ class DartCompletionCache extends CompletionCache {
}
/**
- * Return the [ClassElement] for Object.
- */
- ClassElement get objectClassElement {
- if (_objectClassElement == null) {
- Source coreUri = context.sourceFactory.forUri('dart:core');
- LibraryElement coreLib = context.getLibraryElement(coreUri);
- Namespace coreNamespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
- _objectClassElement = coreNamespace.definedNames['Object'];
- }
- return _objectClassElement;
- }
-
- /**
* Return `true` if the import information is cached for the given
* compilation unit.
*/
bool isImportInfoCached(CompilationUnit unit) =>
_importKey != null && _importKey == _computeImportKey(unit);
+ /**
+ * Add suggestions for implicitly imported elements in dart:core.
+ */
+ void _addDartCoreSuggestions() {
+ 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);
+ });
+ _objectClassElement = importedClassMap['Object'];
+ }
+
+ /**
+ * 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, CompletionRelevance.DEFAULT);
+ });
+ } else {
+ // Exclude elements from prefixed imports
+ // because they are provided by InvocationComputer
+ _addLibraryPrefixSuggestion(importElem);
+ excludedLibs.add(importElem.importedLibrary);
+ }
+ }
+ } else if (directive is PartDirective) {
+ CompilationUnitElement partElem = directive.element;
+ if (partElem != null && partElem.source != source) {
+ partElem.accept(new _NonLocalElementCacheVisitor(this));
+ }
+ }
+ });
+ if (libSource != source) {
+ libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
+ }
+ }
+ }
+
void _addLibraryPrefixSuggestion(ImportElement importElem) {
CompletionSuggestion suggestion = null;
String completion = importElem.prefix.displayName;
@@ -253,7 +247,28 @@ class DartCompletionCache extends CompletionCache {
}
}
- void addSuggestion(Element element, CompletionRelevance relevance) {
+ /**
+ * 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) {
+ 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);
+ }
+ }
+ });
+ }
+
+ /**
+ * Add a suggestion for the given element.
+ */
+ void _addSuggestion(Element element, CompletionRelevance relevance) {
if (element is ExecutableElement) {
if (element.isOperator) {
@@ -289,6 +304,23 @@ class DartCompletionCache extends CompletionCache {
});
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);
+ }
}
/**
@@ -303,7 +335,7 @@ class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor {
@override
void visitClassElement(ClassElement element) {
- cache.addSuggestion(element, CompletionRelevance.DEFAULT);
+ cache._addSuggestion(element, CompletionRelevance.DEFAULT);
}
@override
@@ -318,16 +350,16 @@ class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor {
@override
void visitFunctionElement(FunctionElement element) {
- cache.addSuggestion(element, CompletionRelevance.DEFAULT);
+ cache._addSuggestion(element, CompletionRelevance.DEFAULT);
}
@override
void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
- cache.addSuggestion(element, CompletionRelevance.DEFAULT);
+ cache._addSuggestion(element, CompletionRelevance.DEFAULT);
}
@override
void visitTopLevelVariableElement(TopLevelVariableElement element) {
- cache.addSuggestion(element, CompletionRelevance.DEFAULT);
+ cache._addSuggestion(element, CompletionRelevance.DEFAULT);
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698