Analyzer: Don't report on prefixed import with illegal references

Bug: TODO from https://github.com/dart-lang/sdk/issues/38784
Change-Id: I4ecdaf333c2613eb5fa0c57e4a8f8be56c35bb21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175184
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
index 5a1107c..e3e581b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -127,9 +126,7 @@
   c.Future v = null;
   print(v);
 }
-''', errorFilter: (error) {
-      return error.errorCode == CompileTimeErrorCode.UNDEFINED_CLASS;
-    });
+''');
   }
 
   Future<void> test_class_with() async {
@@ -180,9 +177,7 @@
   c.main();
 }
 ''');
-    await assertNoFix(errorFilter: (error) {
-      return error.errorCode == CompileTimeErrorCode.UNDEFINED_FUNCTION;
-    });
+    await assertNoFix();
   }
 
   Future<void> test_function_thisLibrary() async {
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index 713b451..198ee09 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -417,6 +417,13 @@
       // Find import directives using namespaces.
       for (var importDirective in _prefixElementMap[prefix] ?? []) {
         Namespace namespace = _computeNamespace(importDirective);
+        if (elements.isEmpty) {
+          // [prefix] and [elements] were added to [usedElements.prefixMap] but
+          // [elements] is empty, so the prefix was referenced incorrectly.
+          // Another diagnostic about the prefix reference is reported, and we
+          // shouldn't confuse by also reporting an unused prefix.
+          _unusedImports.remove(importDirective);
+        }
         for (var element in elements) {
           if (namespace?.getPrefixed(prefix.name, element.name) != null) {
             _unusedImports.remove(importDirective);
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 87797c5..07a3c23 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -271,9 +271,7 @@
 // ignore: undefined_prefixed_name
 f() => c.g;
 ''',
-      [
-        error(HintCode.UNUSED_IMPORT, 7, 17),
-      ],
+      [],
     );
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 5a97135..d07c1ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -1533,7 +1533,6 @@
   x = 2;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 37, 1),
     ]);
 
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index 362da76..66c665f 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -24,7 +24,6 @@
   p; // use
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 12),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 38, 1),
     ]);
 
@@ -41,7 +40,6 @@
   for (var x in p) {}
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 12),
       error(HintCode.UNUSED_LOCAL_VARIABLE, 47, 1),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 52, 1),
     ]);
@@ -66,7 +64,6 @@
   var x = new C(p);
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 12),
       error(HintCode.UNUSED_LOCAL_VARIABLE, 66, 1),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 76, 1),
     ]);
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 92450fb..bdd82f2 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -779,7 +779,6 @@
   foo();
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 3),
     ]);
     _assertInvalidInvocation(
@@ -808,7 +807,6 @@
   math.foo(0);
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 45, 3),
     ]);
     _assertUnresolvedMethodInvocation('foo(0);');
@@ -1789,7 +1787,6 @@
   math();
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 40, 4),
     ]);
     assertElement(findNode.simple('math()'), findElement.prefix('math'));
diff --git a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
index c9e0e3d..a58eac5 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -198,7 +198,6 @@
   new math.A();
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.NEW_WITH_NON_TYPE, 49, 1),
     ]);
 
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_non_type_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_non_type_test.dart
index 1f14038..67edb47 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_non_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_non_type_test.dart
@@ -23,7 +23,6 @@
   const lib.A();
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.CONST_WITH_NON_TYPE, 50, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
index 6f6cb91..5313441 100644
--- a/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
@@ -118,7 +118,6 @@
 
 class C extends p.A {}
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.EXTENDS_NON_CLASS, 42, 3),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
index 2c89f6d..8f903e5 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
@@ -260,7 +260,6 @@
   p?.x;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 8),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 31, 1),
     ]);
   }
@@ -472,7 +471,6 @@
   p?.x = 0;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 8),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 31, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart
index dbc72fa..948a8dd 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart
@@ -158,7 +158,6 @@
 
 class C with p.M {}
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.MIXIN_OF_NON_CLASS, 39, 3),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart b/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
index 686b88b..1979034 100644
--- a/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
@@ -27,7 +27,6 @@
   }
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 46, 1),
     ]);
   }
@@ -42,7 +41,6 @@
   p += 1;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 32, 1),
     ]);
   }
@@ -59,7 +57,6 @@
   }
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 46, 1),
     ]);
   }
@@ -93,7 +90,6 @@
   p = 1;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 32, 1),
     ]);
   }
@@ -108,7 +104,6 @@
   p += 1;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 32, 1),
     ]);
   }
@@ -154,7 +149,6 @@
   return p?.x;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 1),
     ]);
   }
@@ -169,7 +163,6 @@
   return p?.loadLibrary;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 48, 1),
     ]);
   }
@@ -185,7 +178,6 @@
   p?.x = null;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 32, 1),
     ]);
   }
@@ -200,7 +192,6 @@
   p?.loadLibrary = null;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 41, 1),
     ]);
   }
@@ -215,7 +206,6 @@
   return p;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
index 4012199..711ac51 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
@@ -52,7 +52,6 @@
 main() {
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 25, 13),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
index 7c35f6a..025eb5f 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
@@ -140,7 +140,6 @@
 
 p.A a;
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.UNDEFINED_CLASS, 26, 3),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
index 611ed57..87cafbf 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
@@ -21,7 +21,6 @@
 import 'lib.dart' as p;
 f() => p.c;
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME, 33, 1),
     ]);
   }
@@ -34,7 +33,6 @@
   p.c = 0;
 }
 ''', [
-      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME, 34, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index b057f27..af40e72 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -49,9 +49,6 @@
     // Need a way to make auxiliary files that (a) are not included in the
     // generated docs or (b) can be made persistent for fixes.
     'CompileTimeErrorCode.PART_OF_NON_PART',
-    // Need to avoid reporting an unused import with a prefix, when the prefix
-    // is only referenced in an invalid way.
-    'CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT',
     // Produces the diagnostic HintCode.UNUSED_LOCAL_VARIABLE when it shouldn't.
     'CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT',
     // The code has been replaced but is not yet removed.