Add ImportElement.namespace and use it in completion.

R=brianwilkerson@google.com

Change-Id: I58cadf0e3239ad4ae8584d79485f4d9ebda10eba
Reviewed-on: https://dart-review.googlesource.com/54064
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/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 1e3c378..b7afbbe 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,7 @@
           LibraryElementSuggestionBuilder builder =
               new LibraryElementSuggestionBuilder(containingLibrary,
                   CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
-          for (var element in library.exportNamespace.definedNames.values) {
+          for (var element in importElem.namespace.definedNames.values) {
             element.accept(builder);
           }
           suggestions.addAll(builder.suggestions);
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index fc0d748..1419922 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -114,8 +114,7 @@
     if (importElementsMap.containsKey(importElement)) {
       continue;
     }
-    Namespace namespace =
-        new NamespaceBuilder().createImportNamespaceForDirective(importElement);
+    Namespace namespace = importElement.namespace;
     Set<Element> elements = new Set.from(namespace.definedNames.values);
     importElementsMap[importElement] = elements;
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 5281867..5878f8c 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -16,7 +16,6 @@
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show SourceChange, SourceEdit;
@@ -342,9 +341,7 @@
  * Returns the namespace of the given [ImportElement].
  */
 Map<String, Element> getImportNamespace(ImportElement imp) {
-  NamespaceBuilder builder = new NamespaceBuilder();
-  Namespace namespace = builder.createImportNamespaceForDirective(imp);
-  return namespace.definedNames;
+  return imp.namespace.definedNames;
 }
 
 /**
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 4a2270c..1e1aec8 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -1606,25 +1606,17 @@
         extraFiles: sources,
         failingTests: '1');
 
-    buildTests(
-        'test_importPrefix_hideCombinator',
-        '''
+    buildTests('test_importPrefix_hideCombinator', '''
 import 'dart:math' as math hide PI;
 main() {
   math.!1
-}''',
-        <String>["1-PI", "1+LN10"],
-        failingTests: '1');
+}''', <String>["1-PI", "1+LN10"]);
 
-    buildTests(
-        'test_importPrefix_showCombinator',
-        '''
+    buildTests('test_importPrefix_showCombinator', '''
 import 'dart:math' as math show PI;
 main() {
   math.!1
-}''',
-        <String>["1+PI", "1-LN10"],
-        failingTests: '1');
+}''', <String>["1+PI", "1-LN10"]);
 
     sources.clear();
     sources["/lib.dart"] = '''
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 d190e7e..3f3f9fc 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
@@ -161,11 +161,7 @@
     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 {}
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index ea8ebbb..8af9b7d 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1458,6 +1458,11 @@
   bool get isDeferred;
 
   /**
+   * The [Namespace] that this directive contributes to the containing library.
+   */
+  Namespace get namespace;
+
+  /**
    * Return the prefix that was specified as part of the import directive, or
    * `null` if there was no prefix specified.
    */
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 3933454..a54df1f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/resolver/scope.dart' show NamespaceBuilder;
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:collection/collection.dart';
 
@@ -823,11 +822,7 @@
   _ImportElementReferencesVisitor(
       ImportElement element, this.enclosingUnitElement)
       : importElement = element {
-    importedElements = new NamespaceBuilder()
-        .createImportNamespaceForDirective(element)
-        .definedNames
-        .values
-        .toSet();
+    importedElements = element.namespace.definedNames.values.toSet();
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index c81779b..ac82f5f 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5791,6 +5791,11 @@
   String _selectedUri;
 
   /**
+   * The cached value of [namespace].
+   */
+  Namespace _namespace;
+
+  /**
    * Initialize a newly created import element at the given [offset].
    * The offset may be `-1` if the import is synthetic.
    */
@@ -5939,6 +5944,12 @@
     return offset;
   }
 
+  @override
+  Namespace get namespace {
+    return _namespace ??=
+        new NamespaceBuilder().createImportNamespaceForDirective(this);
+  }
+
   PrefixElement get prefix {
     if (_prefix == null) {
       if (_kernel != null && _kernel.name != null) {
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 541f0d0..c3a659d 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -763,6 +763,9 @@
   ElementKind get kind => ElementKind.IMPORT;
 
   @override
+  Namespace get namespace => actualElement.namespace;
+
+  @override
   PrefixElement get prefix => actualElement.prefix;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index ef99e4c..a5533a8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -488,13 +488,11 @@
    * later reference.
    */
   void _createImportedNamespaces() {
-    NamespaceBuilder builder = new NamespaceBuilder();
     List<ImportElement> imports = _definingLibrary.imports;
     int count = imports.length;
     _importedNamespaces = new List<Namespace>(count);
     for (int i = 0; i < count; i++) {
-      _importedNamespaces[i] =
-          builder.createImportNamespaceForDirective(imports[i]);
+      _importedNamespaces[i] = imports[i].namespace;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 5562394..c93ad27 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4263,8 +4263,7 @@
       // the map.
       ImportElement importElement = importDirective.element;
       if (importElement != null) {
-        NamespaceBuilder builder = new NamespaceBuilder();
-        namespace = builder.createImportNamespaceForDirective(importElement);
+        namespace = importElement.namespace;
         _namespaceMap[importDirective] = namespace;
       }
     }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 86331a3..c429a6d 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -865,9 +865,7 @@
    * Return the namespace added by the given import [element].
    */
   Map<String, Element> _getImportNamespace(ImportElement element) {
-    NamespaceBuilder builder = new NamespaceBuilder();
-    Namespace namespace = builder.createImportNamespaceForDirective(element);
-    return namespace.definedNames;
+    return element.namespace.definedNames;
   }
 
   /**