Elements. Migrate PrefixElementResolutionTest into LibraryFragmentElementTest.

Change-Id: Id894f7a51504de5dd9dd8bce62f0fddca4734267
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406440
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 50fdd6dd..9e6dc2f 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -1559,7 +1559,9 @@
   readElement2: <null>
   readType: null
   writeElement: <null>
-  writeElement2: <null>
+  writeElement2: multiplyDefinedElement
+    package:test/a.dart::@class::C
+    package:test/b.dart::@class::C
   writeType: InvalidType
   staticElement: <null>
   element: <null>
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 a81ac82..d5d6a2a 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1765,7 +1765,9 @@
   methodName: SimpleIdentifier
     token: foo
     staticElement: <null>
-    element: <null>
+    element: multiplyDefinedElement
+      package:test/a.dart::@function::foo
+      package:test/b.dart::@function::foo
     staticType: void Function(int)
   argumentList: ArgumentList
     leftParenthesis: (
@@ -1811,7 +1813,9 @@
   methodName: SimpleIdentifier
     token: foo
     staticElement: <null>
-    element: <null>
+    element: multiplyDefinedElement
+      package:test/a.dart::@function::foo
+      package:test/b.dart::@function::foo
     staticType: void Function(int)
   argumentList: ArgumentList
     leftParenthesis: (
diff --git a/pkg/analyzer/test/src/dart/resolution/named_type_test.dart b/pkg/analyzer/test/src/dart/resolution/named_type_test.dart
index dc12bd6..3911de5 100644
--- a/pkg/analyzer/test/src/dart/resolution/named_type_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/named_type_test.dart
@@ -788,7 +788,9 @@
 NamedType
   name: A
   element: <null>
-  element2: <null>
+  element2: multiplyDefinedElement
+    package:test/a.dart::@class::A
+    package:test/b.dart::@class::A
   type: InvalidType
 ''');
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_element_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_element_test.dart
deleted file mode 100644
index d9c56e0..0000000
--- a/pkg/analyzer/test/src/dart/resolution/prefix_element_test.dart
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// ignore_for_file: analyzer_use_new_elements
-
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'context_collection_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(PrefixElementResolutionTest);
-  });
-}
-
-@reflectiveTest
-class PrefixElementResolutionTest extends PubPackageResolutionTest {
-  test_scope_lookup() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var foo = 0;
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'a.dart' as prefix;
-''');
-
-    var scope = findElement2.prefix('prefix').scope;
-    var importFind = findElement2.importFind('package:test/a.dart');
-
-    assertElement(
-      scope.lookup('foo').getter2,
-      declaration: importFind.topGet('foo'),
-    );
-
-    assertElement(
-      scope.lookup('foo').setter2,
-      declaration: importFind.topSet('foo'),
-    );
-  }
-
-  test_scope_lookup_ambiguous_notSdk_both() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var foo = 0;
-''');
-
-    newFile('$testPackageLibPath/b.dart', r'''
-var foo = 1.2;
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'a.dart' as prefix;
-
-// ignore:unused_import
-import 'b.dart' as prefix;
-''');
-
-    var scope = findElement.prefix('prefix').scope;
-
-    var aImport = findElement.importFind('package:test/a.dart');
-    var bImport = findElement.importFind('package:test/b.dart');
-
-    expect(
-      scope.lookup('foo').getter,
-      multiplyDefinedElementMatcher([
-        aImport.topGet('foo'),
-        bImport.topGet('foo'),
-      ]),
-    );
-
-    expect(
-      scope.lookup('foo').setter,
-      multiplyDefinedElementMatcher([
-        aImport.topSet('foo'),
-        bImport.topSet('foo'),
-      ]),
-    );
-  }
-
-  test_scope_lookup_ambiguous_notSdk_first() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var pi = 4;
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'a.dart' as prefix;
-
-// ignore:unused_import
-import 'dart:math' as prefix;
-''');
-
-    var scope = findElement2.prefix('prefix').scope;
-    var aImport = findElement2.importFind('package:test/a.dart');
-
-    assertElement(
-      scope.lookup('pi').getter2,
-      declaration: aImport.topGet('pi'),
-    );
-  }
-
-  test_scope_lookup_ambiguous_notSdk_second() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var pi = 4;
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'dart:math' as prefix;
-
-// ignore:unused_import
-import 'a.dart' as prefix;
-''');
-
-    var scope = findElement2.prefix('prefix').scope;
-    var aImport = findElement2.importFind('package:test/a.dart');
-
-    assertElement(
-      scope.lookup('pi').getter2,
-      declaration: aImport.topGet('pi'),
-    );
-  }
-
-  test_scope_lookup_ambiguous_same() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var foo = 0;
-''');
-
-    newFile('$testPackageLibPath/b.dart', r'''
-export 'a.dart';
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'a.dart' as prefix;
-
-// ignore:unused_import
-import 'b.dart' as prefix;
-''');
-
-    var scope = findElement2.prefix('prefix').scope;
-    var importFind = findElement2.importFind('package:test/a.dart');
-
-    assertElement(
-      scope.lookup('foo').getter2,
-      declaration: importFind.topGet('foo'),
-    );
-
-    assertElement(
-      scope.lookup('foo').setter2,
-      declaration: importFind.topSet('foo'),
-    );
-  }
-
-  test_scope_lookup_differentPrefix() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-var foo = 0;
-''');
-
-    newFile('$testPackageLibPath/b.dart', r'''
-var bar = 0;
-''');
-
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'a.dart' as prefix;
-
-// ignore:unused_import
-import 'b.dart' as prefix2;
-''');
-
-    var scope = findElement2.prefix('prefix').scope;
-    var importFind = findElement2.importFind('package:test/a.dart');
-
-    assertElement(
-      scope.lookup('foo').getter2,
-      declaration: importFind.topGet('foo'),
-    );
-    assertElement(
-      scope.lookup('foo').setter2,
-      declaration: importFind.topSet('foo'),
-    );
-
-    assertElementNull(
-      scope.lookup('bar').getter2,
-    );
-    assertElementNull(
-      scope.lookup('bar').setter2,
-    );
-  }
-
-  test_scope_lookup_notFound() async {
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'dart:math' as math;
-''');
-
-    var scope = findElement.prefix('math').scope;
-
-    assertElementNull(
-      scope.lookup('noSuchGetter').getter2,
-    );
-
-    assertElementNull(
-      scope.lookup('noSuchSetter').setter2,
-    );
-  }
-
-  test_scope_lookup_respectsCombinator_hide() async {
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'dart:math' as math hide sin;
-''');
-
-    var scope = findElement2.prefix('math').scope;
-    var mathFind = findElement2.importFind('dart:math');
-
-    assertElementNull(
-      scope.lookup('sin').getter2,
-    );
-
-    assertElement(
-      scope.lookup('cos').getter2,
-      declaration: mathFind.topFunction('cos'),
-    );
-    assertElement(
-      scope.lookup('tan').getter2,
-      declaration: mathFind.topFunction('tan'),
-    );
-  }
-
-  test_scope_lookup_respectsCombinator_show() async {
-    await assertNoErrorsInCode(r'''
-// ignore:unused_import
-import 'dart:math' as math show sin;
-''');
-
-    var scope = findElement2.prefix('math').scope;
-    var mathFind = findElement2.importFind('dart:math');
-
-    assertElement(
-      scope.lookup('sin').getter2,
-      declaration: mathFind.topFunction('sin'),
-    );
-
-    assertElementNull(
-      scope.lookup('cos').getter2,
-    );
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 4585487..8be6d29 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -447,10 +447,6 @@
   ExpectedContextMessage message(File file, int offset, int length) =>
       ExpectedContextMessage(file, offset, length);
 
-  Matcher multiplyDefinedElementMatcher(List<Element> elements) {
-    return _MultiplyDefinedElementMatcher(elements);
-  }
-
   Future<ResolvedUnitResult> resolveFile(File file);
 
   /// Resolve [file] into [result].
@@ -507,27 +503,6 @@
   }
 }
 
-class _MultiplyDefinedElementMatcher extends Matcher {
-  final Iterable<Element> elements;
-
-  _MultiplyDefinedElementMatcher(this.elements);
-
-  @override
-  Description describe(Description description) {
-    return description.add('elements: $elements\n');
-  }
-
-  @override
-  bool matches(element, Map matchState) {
-    if (element is MultiplyDefinedElementImpl) {
-      var actualSet = element.conflictingElements.toSet();
-      actualSet.removeAll(elements);
-      return actualSet.isEmpty;
-    }
-    return false;
-  }
-}
-
 extension ResolvedUnitResultExtension on ResolvedUnitResult {
   FindElement get findElement {
     return FindElement(unit);
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 12811d0..97b1d8c 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -89,7 +89,6 @@
 import 'pattern_variable_declaration_statement_test.dart'
     as pattern_variable_declaration_statement;
 import 'postfix_expression_test.dart' as postfix_expression;
-import 'prefix_element_test.dart' as prefix_element;
 import 'prefix_expression_test.dart' as prefix_expression;
 import 'prefixed_identifier_test.dart' as prefixed_identifier;
 import 'property_access_test.dart' as property_access;
@@ -197,7 +196,6 @@
     pattern_assignment.main();
     pattern_variable_declaration_statement.main();
     postfix_expression.main();
-    prefix_element.main();
     prefix_expression.main();
     prefixed_identifier.main();
     property_access.main();
diff --git a/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart b/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart
index e0719e7..08a51c5 100644
--- a/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart
@@ -602,6 +602,235 @@
 ''');
   }
 
+  test_scope_hasPrefix_lookup_ambiguous_notSdk_both() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+var foo = 0;
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
+var foo = 1.2;
+''');
+
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'a.dart' as prefix;
+
+// ignore:unused_import
+import 'b.dart' as prefix;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'prefix.foo',
+    ], r'''
+package:test/test.dart
+  prefix.foo
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: multiplyDefinedElement
+      package:test/a.dart::<fragment>::@getter::foo#element
+      package:test/b.dart::<fragment>::@getter::foo#element
+    setter: multiplyDefinedElement
+      package:test/a.dart::<fragment>::@setter::foo#element
+      package:test/b.dart::<fragment>::@setter::foo#element
+''');
+  }
+
+  test_scope_hasPrefix_lookup_ambiguous_notSdk_first() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+var pi = 4;
+''');
+
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'a.dart' as prefix;
+
+// ignore:unused_import
+import 'dart:math' as prefix;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'prefix.pi',
+    ], r'''
+package:test/test.dart
+  prefix.pi
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: package:test/a.dart::<fragment>::@getter::pi#element
+    setter: package:test/a.dart::<fragment>::@setter::pi#element
+''');
+  }
+
+  test_scope_hasPrefix_lookup_ambiguous_notSdk_second() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+var pi = 4;
+''');
+
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'dart:math' as prefix;
+
+// ignore:unused_import
+import 'a.dart' as prefix;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'prefix.pi',
+    ], r'''
+package:test/test.dart
+  prefix.pi
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: package:test/a.dart::<fragment>::@getter::pi#element
+    setter: package:test/a.dart::<fragment>::@setter::pi#element
+''');
+  }
+
+  test_scope_hasPrefix_lookup_ambiguous_same() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+var foo = 0;
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
+export 'a.dart';
+''');
+
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'a.dart' as prefix;
+
+// ignore:unused_import
+import 'b.dart' as prefix;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'prefix.foo',
+    ], r'''
+package:test/test.dart
+  prefix.foo
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: package:test/a.dart::<fragment>::@getter::foo#element
+    setter: package:test/a.dart::<fragment>::@setter::foo#element
+''');
+  }
+
+  test_scope_hasPrefix_lookup_differentPrefix() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+var foo = 0;
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
+var bar = 0;
+''');
+
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'a.dart' as prefix;
+
+// ignore:unused_import
+import 'b.dart' as prefix2;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'prefix.foo',
+      'prefix.bar',
+      'prefix2.foo',
+      'prefix2.bar',
+    ], r'''
+package:test/test.dart
+  prefix.foo
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: package:test/a.dart::<fragment>::@getter::foo#element
+    setter: package:test/a.dart::<fragment>::@setter::foo#element
+  prefix.bar
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: <null>
+  prefix2.foo
+    prefix2: <testLibraryFragment>::@prefix2::prefix2
+    getter: <null>
+  prefix2.bar
+    prefix2: <testLibraryFragment>::@prefix2::prefix2
+    getter: package:test/b.dart::<fragment>::@getter::bar#element
+    setter: package:test/b.dart::<fragment>::@setter::bar#element
+''');
+  }
+
+  test_scope_hasPrefix_lookup_notFound() async {
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'dart:math' as math;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'math.noSuchElement',
+    ], r'''
+package:test/test.dart
+  math.noSuchElement
+    math: <testLibraryFragment>::@prefix2::math
+    getter: <null>
+''');
+  }
+
+  test_scope_hasPrefix_lookup_respectsCombinator_hide() async {
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'dart:math' as math hide sin;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'math.sin',
+      'math.cos',
+    ], r'''
+package:test/test.dart
+  math.sin
+    math: <testLibraryFragment>::@prefix2::math
+    getter: <null>
+  math.cos
+    math: <testLibraryFragment>::@prefix2::math
+    getter: dart:math::@function::cos
+''');
+  }
+
+  test_scope_hasPrefix_lookup_respectsCombinator_show() async {
+    await assertNoErrorsInCode(r'''
+// ignore:unused_import
+import 'dart:math' as math show sin;
+''');
+
+    var library = result.libraryElement2 as LibraryElementImpl;
+    _assertScopeLookups(library, [
+      Uri.parse('package:test/test.dart'),
+    ], [
+      'math.sin',
+      'math.cos',
+    ], r'''
+package:test/test.dart
+  math.sin
+    math: <testLibraryFragment>::@prefix2::math
+    getter: dart:math::@function::sin
+  math.cos
+    math: <testLibraryFragment>::@prefix2::math
+    getter: <null>
+''');
+  }
+
   test_scope_hasPrefix_shadow() async {
     newFile('$testPackageLibPath/x.dart', r'''
 class Directory {}
diff --git a/pkg/analyzer/test/src/summary/elements/metadata_test.dart b/pkg/analyzer/test/src/summary/elements/metadata_test.dart
index 8d094ad..0e644c7 100644
--- a/pkg/analyzer/test/src/summary/elements/metadata_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/metadata_test.dart
@@ -11949,6 +11949,8 @@
   }
 
   test_unresolved_annotation_simpleIdentifier_multiplyDefined() async {
+    if (!keepLinkingLibraries) return;
+
     newFile('$testPackageLibPath/a.dart', 'const v = 0;');
     newFile('$testPackageLibPath/b.dart', 'const v = 0;');
     var library = await buildLibrary('''
@@ -11980,7 +11982,9 @@
               name: SimpleIdentifier
                 token: v @36
                 staticElement: <null>
-                element: <null>
+                element: multiplyDefinedElement
+                  package:test/a.dart::<fragment>::@getter::v#element
+                  package:test/b.dart::<fragment>::@getter::v#element
                 staticType: null
               element: <null>
               element2: <null>
diff --git a/pkg/analyzer/test/src/summary/elements/types_test.dart b/pkg/analyzer/test/src/summary/elements/types_test.dart
index 31db74a..74d9340 100644
--- a/pkg/analyzer/test/src/summary/elements/types_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/types_test.dart
@@ -2592,6 +2592,8 @@
   }
 
   test_invalid_nameConflict_imported() async {
+    if (!keepLinkingLibraries) return;
+
     newFile('$testPackageLibPath/a.dart', 'V() {}');
     newFile('$testPackageLibPath/b.dart', 'V() {}');
     var library = await buildLibrary('''
@@ -2622,7 +2624,9 @@
                 SimpleIdentifier
                   token: V @43
                   staticElement: <null>
-                  element: <null>
+                  element: multiplyDefinedElement
+                    package:test/a.dart::@function::V
+                    package:test/b.dart::@function::V
                   staticType: InvalidType
           returnType: dynamic
 ----------------------------------------
diff --git a/pkg/analyzer/test/util/element_printer.dart b/pkg/analyzer/test/util/element_printer.dart
index 543d282..322a958 100644
--- a/pkg/analyzer/test/util/element_printer.dart
+++ b/pkg/analyzer/test/util/element_printer.dart
@@ -148,8 +148,17 @@
         var reference = firstFragment.reference;
         writeReference(reference!);
         _sink.write('#element');
-      case MultiplyDefinedElementImpl2():
-        _sink.write('<null>');
+      case MultiplyDefinedElementImpl2 multiElement:
+        _sink.writeln('multiplyDefinedElement');
+        _sink.withIndent(() {
+          for (var (i, element) in multiElement.conflictingElements2.indexed) {
+            if (i != 0) {
+              _sink.writeln();
+            }
+            _sink.writeIndent();
+            writeElement2(element);
+          }
+        });
       case NeverElementImpl():
         _sink.write('Never@-1');
       case ParameterMember():