Issue 60791. Don't add elements without names to exported references.

Bug: https://github.com/dart-lang/sdk/issues/60791
Change-Id: I1b83c16dbcfa5ba8b4371606d643efc4a1193733
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431140
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 6b2dd0b..5a37136 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -117,7 +117,8 @@
     var name = nameToken.lexeme;
 
     var fragment = ClassFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAbstract = node.abstractKeyword != null;
     fragment.isAugmentation = node.augmentKeyword != null;
@@ -139,8 +140,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var fragmentReference = _enclosingContext.addClass(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, fragmentReference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, fragmentReference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -189,7 +190,8 @@
     var name = nameToken.lexeme;
 
     var fragment = ClassFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAbstract = node.abstractKeyword != null;
     fragment.isBase = node.baseKeyword != null;
@@ -210,8 +212,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addClass(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, reference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, reference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -304,7 +306,8 @@
     var nameOffset = nameToken.offset;
 
     var fragment = EnumFragmentImpl(name, nameOffset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAugmentation = node.augmentKeyword != null;
     fragment.metadata = _buildAnnotations(node.metadata);
@@ -316,8 +319,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addEnum(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, reference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, reference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -531,7 +534,8 @@
     var nameOffset = nameToken?.offset ?? -1;
 
     var fragment = ExtensionFragmentImpl(name, nameOffset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAugmentation = node.augmentKeyword != null;
     fragment.metadata = _buildAnnotations(node.metadata);
@@ -545,8 +549,8 @@
     var reference = _enclosingContext.addExtension(refName, fragment);
 
     if (name != null) {
-      if (!fragment.isAugmentation) {
-        _libraryBuilder.declare(name, reference);
+      if (!fragment.isAugmentation && name2 != null) {
+        _libraryBuilder.declare(name2, reference);
       }
     }
 
@@ -613,7 +617,8 @@
     var name = nameToken.lexeme;
 
     var fragment = ExtensionTypeFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAugmentation = node.augmentKeyword != null;
     fragment.metadata = _buildAnnotations(node.metadata);
@@ -625,8 +630,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addExtensionType(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, reference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, reference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -802,6 +807,7 @@
     var nameToken = node.name;
     var name = nameToken.lexeme;
     var nameOffset = nameToken.offset;
+    var name2 = _getFragmentName(nameToken);
 
     var functionExpression = node.functionExpression;
     var body = functionExpression.body;
@@ -811,7 +817,7 @@
     FragmentedElementBuilder? elementBuilder;
     if (node.isGetter) {
       var getterFragment = GetterFragmentImpl(name, nameOffset);
-      getterFragment.name2 = _getFragmentName(nameToken);
+      getterFragment.name2 = name2;
       getterFragment.nameOffset2 = _getFragmentNameOffset(nameToken);
       getterFragment.isAugmentation = node.augmentKeyword != null;
       getterFragment.isStatic = true;
@@ -847,7 +853,7 @@
       }
     } else if (node.isSetter) {
       var setterFragment = SetterFragmentImpl(name, nameOffset);
-      setterFragment.name2 = _getFragmentName(nameToken);
+      setterFragment.name2 = name2;
       setterFragment.nameOffset2 = _getFragmentNameOffset(nameToken);
       setterFragment.isAugmentation = node.augmentKeyword != null;
       setterFragment.isStatic = true;
@@ -883,7 +889,7 @@
       }
     } else {
       var fragment = TopLevelFunctionFragmentImpl(name, nameOffset);
-      fragment.name2 = _getFragmentName(nameToken);
+      fragment.name2 = name2;
       fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
       fragment.isAugmentation = node.augmentKeyword != null;
       fragment.isStatic = true;
@@ -931,9 +937,8 @@
       typeParameters: functionExpression.typeParameters,
     );
 
-    var getterOrSetterName = node.isSetter ? '$name=' : name;
-
-    if (!executableFragment.isAugmentation) {
+    if (!executableFragment.isAugmentation && name2 != null) {
+      var getterOrSetterName = node.isSetter ? '$name2=' : name2;
       _libraryBuilder.declare(getterOrSetterName, reference);
     }
 
@@ -946,7 +951,8 @@
     var name = nameToken.lexeme;
 
     var fragment = TypeAliasFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isFunctionTypeAliasBased = true;
     fragment.metadata = _buildAnnotations(node.metadata);
@@ -958,7 +964,9 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addTypeAlias(refName, fragment);
-    _libraryBuilder.declare(name, reference);
+    if (name2 != null) {
+      _libraryBuilder.declare(name2, reference);
+    }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
     elementBuilder ??= _libraryBuilder.elementBuilderSetters[name];
@@ -1092,7 +1100,8 @@
     var name = nameToken.lexeme;
 
     var fragment = TypeAliasFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAugmentation = node.augmentKeyword != null;
     fragment.metadata = _buildAnnotations(node.metadata);
@@ -1104,8 +1113,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addTypeAlias(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, reference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, reference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -1264,7 +1273,8 @@
     var name = nameToken.lexeme;
 
     var fragment = MixinFragmentImpl(name, nameToken.offset);
-    fragment.name2 = _getFragmentName(nameToken);
+    var name2 = _getFragmentName(nameToken);
+    fragment.name2 = name2;
     fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
     fragment.isAugmentation = node.augmentKeyword != null;
     fragment.isBase = node.baseKeyword != null;
@@ -1277,8 +1287,8 @@
 
     var refName = fragment.name2 ?? '${_nextUnnamedId++}';
     var reference = _enclosingContext.addMixin(refName, fragment);
-    if (!fragment.isAugmentation) {
-      _libraryBuilder.declare(name, reference);
+    if (!fragment.isAugmentation && name2 != null) {
+      _libraryBuilder.declare(name2, reference);
     }
 
     var elementBuilder = _libraryBuilder.elementBuilderGetters[name];
@@ -1497,7 +1507,8 @@
         fragment = TopLevelVariableFragmentImpl(name, nameOffset);
       }
 
-      fragment.name2 = _getFragmentName(nameToken);
+      var name2 = _getFragmentName(nameToken);
+      fragment.name2 = name2;
       fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
       fragment.hasInitializer = variable.initializer != null;
       fragment.isAugmentation = node.augmentKeyword != null;
@@ -1521,7 +1532,9 @@
           var ref = enclosingRef.getChild('@getter').addChild(refName);
           var getter = fragment.createImplicitGetter(ref);
           _enclosingContext.addPropertyAccessorSynthetic(getter);
-          _libraryBuilder.declare(name, ref);
+          if (name2 != null) {
+            _libraryBuilder.declare(name2, ref);
+          }
 
           var elementBuilder = GetterElementBuilder(
             element: GetterElementImpl(getter),
@@ -1534,7 +1547,9 @@
           var ref = enclosingRef.getChild('@setter').addChild(refName);
           var setter = fragment.createImplicitSetter(ref);
           _enclosingContext.addPropertyAccessorSynthetic(setter);
-          _libraryBuilder.declare('$name=', ref);
+          if (name2 != null) {
+            _libraryBuilder.declare('$name2=', ref);
+          }
 
           var elementBuilder = SetterElementBuilder(
             element: SetterElementImpl(setter),
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index a549794..cc2da94 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -260,6 +260,9 @@
   }
 
   void declare(String name, Reference reference) {
+    // If the element name is missing, don't attempt adding it.
+    assert(name.isNotEmpty);
+
     _declaredReferences[name] = reference;
   }
 
diff --git a/pkg/analyzer/test/src/summary/elements/class_test.dart b/pkg/analyzer/test/src/summary/elements/class_test.dart
index 065f0db..8a3f827 100644
--- a/pkg/analyzer/test/src/summary/elements/class_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/class_test.dart
@@ -13085,6 +13085,7 @@
   }
 
   test_class_missingName() async {
+    configuration.withExportScope = true;
     var library = await buildLibrary(r'''
 class {}
 ''');
@@ -13110,6 +13111,8 @@
       constructors
         synthetic new
           firstFragment: <testLibraryFragment>::@class::0::@constructor::new
+  exportedReferences
+  exportNamespace
 ''');
   }
 
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 c4607cf..91e3762 100644
--- a/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/library_fragment_test.dart
@@ -561,6 +561,33 @@
     );
   }
 
+  test_scope_hasPrefix_lookup_ambiguous_missingName() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class {}
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
+class {}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart' as prefix;
+import 'b.dart' as prefix;
+''');
+
+    _assertScopeLookups(
+      library,
+      [Uri.parse('package:test/test.dart')],
+      ['prefix.A'],
+      r'''
+package:test/test.dart
+  prefix.A
+    prefix: <testLibraryFragment>::@prefix2::prefix
+    getter: <null>
+''',
+    );
+  }
+
   test_scope_hasPrefix_lookup_ambiguous_notSdk_both() async {
     newFile('$testPackageLibPath/a.dart', r'''
 var foo = 0;