Issue 32849. Use export namespace for import prefix and combinator completions.
R=brianwilkerson@google.com
Closes https://github.com/dart-lang/sdk/issues/32849
Change-Id: I43621a1c917095fab6be1f1798ea8596f7c3a173
Reviewed-on: https://dart-review.googlesource.com/53863
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index 4d30f30..2914658 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -32,7 +32,9 @@
LibraryElementSuggestionBuilder builder =
new LibraryElementSuggestionBuilder(request.libraryElement,
CompletionSuggestionKind.IDENTIFIER, false, false);
- library.visitChildren(builder);
+ for (var element in library.exportNamespace.definedNames.values) {
+ element.accept(builder);
+ }
return builder.suggestions;
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 078959a..1e3c378 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -57,7 +57,9 @@
LibraryElementSuggestionBuilder builder =
new LibraryElementSuggestionBuilder(containingLibrary,
CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
- library.visitChildren(builder);
+ for (var element in library.exportNamespace.definedNames.values) {
+ element.accept(builder);
+ }
suggestions.addAll(builder.suggestions);
// If the import is 'deferred' then suggest 'loadLibrary'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 909345c..7c88a82 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -211,21 +211,15 @@
}
/**
- * This class visits elements in a library and provides suggestions based upon
- * the visible members in that library.
+ * This class creates suggestions based upon top-level elements.
*/
-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
+class LibraryElementSuggestionBuilder extends SimpleElementVisitor
with ElementSuggestionBuilder {
final LibraryElement containingLibrary;
final CompletionSuggestionKind kind;
final bool typesOnly;
final bool instCreation;
- /**
- * The set of libraries that have been, or are currently being, visited.
- */
- final Set<LibraryElement> visitedLibraries = new Set<LibraryElement>();
-
LibraryElementSuggestionBuilder(
this.containingLibrary, this.kind, this.typesOnly, this.instCreation);
@@ -239,17 +233,6 @@
}
@override
- visitCompilationUnitElement(CompilationUnitElement element) {
- element.visitChildren(this);
- LibraryElement containingLibrary = element.library;
- if (containingLibrary != null) {
- for (var lib in containingLibrary.exportedLibraries) {
- lib.accept(this);
- }
- }
- }
-
- @override
visitConstructorElement(ConstructorElement element) {
if (instCreation) {
ClassElement classElem = element.enclosingElement;
@@ -263,11 +246,6 @@
}
@override
- visitElement(Element element) {
- // ignored
- }
-
- @override
visitFunctionElement(FunctionElement element) {
if (!typesOnly) {
int relevance = element.library == containingLibrary
@@ -285,19 +263,13 @@
}
@override
- visitLibraryElement(LibraryElement element) {
- if (visitedLibraries.add(element)) {
- element.visitChildren(this);
- }
- }
-
- @override
- visitTopLevelVariableElement(TopLevelVariableElement element) {
+ visitPropertyAccessorElement(PropertyAccessorElement element) {
if (!typesOnly) {
- int relevance = element.library == containingLibrary
+ PropertyInducingElement variable = element.variable;
+ int relevance = variable.library == containingLibrary
? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
: DART_RELEVANCE_DEFAULT;
- addSuggestion(element, relevance: relevance);
+ addSuggestion(variable, relevance: relevance);
}
}
}
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index 2aa2825..ac4c454 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -123,6 +123,24 @@
assertNotSuggested('Object');
}
+ test_Combinator_show_export_withShow() async {
+ addSource('/a.dart', r'''
+class A {}
+class B {}
+''');
+ addSource('/b.dart', r'''
+export 'a.dart' show A;
+''');
+ addTestSource(r'''
+import 'b.dart' show ^;
+''');
+ await computeSuggestions();
+ assertSuggestClass('A',
+ relevance: DART_RELEVANCE_DEFAULT,
+ kind: CompletionSuggestionKind.IDENTIFIER);
+ assertNotSuggested('B');
+ }
+
test_Combinator_show_PI() async {
addTestSource('import "dart:math" show ^;');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 9679580..d190e7e 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -142,6 +142,45 @@
assertNotSuggested('==');
}
+ test_PrefixedIdentifier_library_export_withShow() async {
+ addSource('/a.dart', r'''
+class A {}
+class B {}
+''');
+ addSource('/b.dart', r'''
+export 'a.dart' show A;
+''');
+ addTestSource(r'''
+import 'b.dart' as p;
+main() {
+ p.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('B');
+ }
+
+ @failingTest
+ test_PrefixedIdentifier_library_import_withShow() async {
+ // As it is designed now, I think we should not suggest B.
+ // However an alternative design could be suggesting it, but updating show.
+ // This could be a part of project-wide suggesting and auto-importing.
+ addSource('/a.dart', r'''
+class A {}
+class B {}
+''');
+ addTestSource(r'''
+import 'a.dart' as p show A;
+main() {
+ p.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('B');
+ }
+
test_PrefixedIdentifier_library_inPart() async {
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';