Chromium Code Reviews| Index: pkg/analysis_services/lib/src/completion/imported_type_computer.dart |
| diff --git a/pkg/analysis_services/lib/src/completion/imported_type_computer.dart b/pkg/analysis_services/lib/src/completion/imported_type_computer.dart |
| index 8c04570805826078bafaba08129c4050d875c875..49ed892761343e1c0d9afab43f385dca5a91a795 100644 |
| --- a/pkg/analysis_services/lib/src/completion/imported_type_computer.dart |
| +++ b/pkg/analysis_services/lib/src/completion/imported_type_computer.dart |
| @@ -19,7 +19,7 @@ import 'package:analyzer/src/generated/element.dart'; |
| class ImportedTypeComputer extends CompletionComputer { |
| @override |
| - bool computeFast(CompilationUnit unit, |
| + bool computeFast(CompilationUnit unit, AstNode node, |
| List<CompletionSuggestion> suggestions) { |
| // TODO: implement computeFast |
| // - compute results based upon current search, then replace those results |
| @@ -29,31 +29,67 @@ class ImportedTypeComputer extends CompletionComputer { |
| } |
| @override |
| - Future<bool> computeFull(CompilationUnit unit, |
| + Future<bool> computeFull(CompilationUnit unit, AstNode node, |
| List<CompletionSuggestion> suggestions) { |
| + return node.accept( |
| + new _ImportedTypeVisitor(searchEngine, unit, suggestions)); |
| + } |
| +} |
| + |
| +/** |
| + * Visits the node at which the completion is requested |
| + * and builds the list of suggestions. |
| + */ |
| +class _ImportedTypeVisitor extends GeneralizingAstVisitor<Future<bool>> { |
| + final SearchEngine searchEngine; |
| + final CompilationUnit unit; |
| + final List<CompletionSuggestion> suggestions; |
| + |
| + _ImportedTypeVisitor(this.searchEngine, this.unit, this.suggestions); |
| + |
| + Future<bool> visitCombinator(Combinator node) { |
| + var directive = node.getAncestor((parent) => parent is NamespaceDirective); |
| + if (directive is NamespaceDirective) { |
| + return _addLibraryElements(directive.uriElement); |
| + } |
| + return new Future.value(true); |
| + } |
| + |
| + Future<bool> visitNode(AstNode node) { |
| + return _addImportedElements(); |
| + } |
| + |
| + Future<bool> visitSimpleIdentifier(SimpleIdentifier node) { |
| + return node.parent.accept(this); |
| + } |
| + |
| + Future<bool> _addImportedElements() { |
| var future = searchEngine.searchTopLevelDeclarations(''); |
| return future.then((List<SearchMatch> matches) { |
| + var visibleLibs = new Set<LibraryElement>(); |
| + var excludedLibs = new Set<LibraryElement>(); |
| + var showNames = new Map<LibraryElement, Set<String>>(); |
| + var hideNames = new Map<LibraryElement, Set<String>>(); |
| // Exclude elements from the local library |
| - // which will be included by the LocalComputer |
| - |
| - // Compute the set of visible libraries to determine relevance |
| - var visibleLibraries = new Set<LibraryElement>(); |
| - var excludedLibraries = new Set<LibraryElement>(); |
| - var unitLibrary = unit.element.library; |
| - excludedLibraries.add(unitLibrary); |
| - unitLibrary.importedLibraries.forEach((LibraryElement library) { |
| - if (library.isDartCore) { |
| - visibleLibraries.add(library); |
| - } |
| - }); |
| + // as they will be included by the LocalComputer |
| + excludedLibs.add(unit.element.library); |
| unit.directives.forEach((Directive directive) { |
| if (directive is ImportDirective) { |
| - LibraryElement library = directive.element.importedLibrary; |
| + LibraryElement lib = directive.element.importedLibrary; |
|
scheglov
2014/08/12 05:02:21
BTW, you get the unit using getParsedCompilationUn
danrubel
2014/08/12 14:52:56
computeFast receives a compilation unit that may n
|
| if (directive.prefix == null) { |
| - visibleLibraries.add(library); |
| + visibleLibs.add(lib); |
| + directive.combinators.forEach((Combinator combinator) { |
| + if (combinator is ShowCombinator) { |
| + showNames[lib] = combinator.shownNames.map( |
| + (SimpleIdentifier id) => id.name).toSet(); |
| + } else if (combinator is HideCombinator) { |
| + hideNames[lib] = combinator.hiddenNames.map( |
| + (SimpleIdentifier id) => id.name).toSet(); |
| + } |
| + }); |
| } else { |
| - excludedLibraries.add(library); |
| + excludedLibs.add(lib); |
| } |
| } |
| }); |
| @@ -62,26 +98,78 @@ class ImportedTypeComputer extends CompletionComputer { |
| matches.forEach((SearchMatch match) { |
| if (match.kind == MatchKind.DECLARATION) { |
| Element element = match.element; |
| - if (element.isPublic && |
| - !excludedLibraries.contains(element.library)) { |
| + var lib = element.library; |
| + if (element.isPublic && !excludedLibs.contains(lib)) { |
| String completion = element.displayName; |
| - var relevance = visibleLibraries.contains(element.library) ? |
| - CompletionRelevance.DEFAULT : |
| - CompletionRelevance.LOW; |
| - suggestions.add( |
| - new CompletionSuggestion( |
| - CompletionSuggestionKind.fromElementKind(element.kind), |
| - relevance, |
| - completion, |
| - completion.length, |
| - 0, |
| - element.isDeprecated, |
| - false // isPotential |
| - )); |
| + var show = showNames[lib]; |
|
scheglov
2014/08/12 05:02:21
Could we please use type annotations?
I think it i
danrubel
2014/08/12 14:52:56
Done.
|
| + var hide = hideNames[lib]; |
| + if ((show == null || show.contains(completion)) && |
| + (hide == null || !hide.contains(completion))) { |
| + suggestions.add( |
| + new CompletionSuggestion( |
| + CompletionSuggestionKind.fromElementKind(element.kind), |
| + visibleLibs.contains(lib) || lib.isDartCore ? |
| + CompletionRelevance.DEFAULT : |
| + CompletionRelevance.LOW, |
| + completion, |
| + completion.length, |
| + 0, |
| + element.isDeprecated, |
| + false // isPotential |
| + )); |
| + } |
| } |
| } |
| }); |
| return true; |
| }); |
| } |
| + |
| + Future<bool> _addLibraryElements(LibraryElement library) { |
| + library.visitChildren(new _LibraryElementVisitor(suggestions)); |
| + return new Future.value(true); |
| + } |
| +} |
| + |
| +/** |
| + * Builds a list of suggestions based upon elements in a library |
| + */ |
| +class _LibraryElementVisitor extends GeneralizingElementVisitor { |
| + final List<CompletionSuggestion> suggestions; |
| + |
| + _LibraryElementVisitor(this.suggestions); |
| + |
| + visitClassElement(ClassElement element) { |
| + _addSuggestion(element); |
| + } |
| + |
| + visitCompilationUnitElement(CompilationUnitElement element) { |
| + element.visitChildren(this); |
| + } |
| + |
| + visitElement(Element element) { |
| + // ignored |
| + } |
| + |
| + visitTopLevelVariableElement(TopLevelVariableElement element) { |
|
scheglov
2014/08/12 05:02:22
Do we want to add FunctionTypeAliasElement?
You co
danrubel
2014/08/12 14:52:56
Done.
|
| + _addSuggestion(element); |
| + } |
| + |
| + void _addSuggestion(Element element) { |
| + if (element != null) { |
| + var completion = element.name; |
| + if (completion != null && completion.length > 0) { |
| + suggestions.add( |
| + new CompletionSuggestion( |
| + CompletionSuggestionKind.fromElementKind(element.kind), |
| + CompletionRelevance.DEFAULT, |
| + completion, |
| + completion.length, |
| + 0, |
| + element.isDeprecated, |
| + false // isPotential |
| + )); |
| + } |
| + } |
| + } |
| } |