Elements. Store name2 in TypeParameterElementImpl.

Change-Id: I93805cf3ac1b9e5aedb022e5d2f691137d188787
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390802
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 08ad58a..737dd4b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -96,7 +96,7 @@
 // TODO(scheglov): Clean up the list of implicitly analyzed files.
 class AnalysisDriver {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 398;
+  static const int DATA_VERSION = 399;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 3440eb0..1246ae2 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -10372,6 +10372,9 @@
 /// A concrete implementation of a [TypeParameterElement].
 class TypeParameterElementImpl extends ElementImpl
     implements TypeParameterElement, TypeParameterFragment {
+  @override
+  FragmentNameImpl? name2;
+
   /// The default value of the type parameter. It is used to provide the
   /// corresponding missing type argument in type annotations and as the
   /// fall-back type value in type inference.
@@ -10470,21 +10473,6 @@
   }
 
   @override
-  FragmentName? get name2 {
-    var name = this.name;
-
-    // If synthetic name.
-    if (name.isEmpty) {
-      return null;
-    }
-
-    return FragmentNameImpl(
-      name: name,
-      nameOffset: nameOffset,
-    );
-  }
-
-  @override
   // TODO(augmentations): Support chaining between the fragments.
   TypeParameterFragment? get nextFragment => null;
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index d5e4ce9..fa34bf5 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -1801,9 +1801,11 @@
   List<TypeParameterElementImpl> _readTypeParameters() {
     return _reader.readTypedList(() {
       var name = _reader.readStringReference();
+      var fragmentName = _readFragmentName();
       var varianceEncoding = _reader.readByte();
       var variance = _decodeVariance(varianceEncoding);
       var element = TypeParameterElementImpl(name, -1);
+      element.name2 = fragmentName;
       element.variance = variance;
       return element;
     });
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index fcbe4b9..5be4acf 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -723,13 +723,14 @@
     });
   }
 
-  void _writeTypeParameterElement(TypeParameterElement typeParameter) {
-    typeParameter as TypeParameterElementImpl;
-    _sink._writeStringReference(typeParameter.name);
-    _sink.writeByte(_encodeVariance(typeParameter).index);
-    _resolutionSink._writeAnnotationList(typeParameter.metadata);
-    _resolutionSink.writeType(typeParameter.bound);
-    _resolutionSink.writeType(typeParameter.defaultType);
+  void _writeTypeParameterElement(TypeParameterElement element) {
+    element as TypeParameterElementImpl;
+    _sink._writeStringReference(element.name);
+    _writeFragmentName(element.name2);
+    _sink.writeByte(_encodeVariance(element).index);
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeType(element.bound);
+    _resolutionSink.writeType(element.defaultType);
   }
 
   /// Add [typeParameters] to the indexing scope, so make them available
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index bd7e33a..fbcad55 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -1347,8 +1347,10 @@
   void visitTypeParameter(covariant TypeParameterImpl node) {
     var nameToken = node.name;
     var name = nameToken.lexeme;
+    var fragmentName = _buildFragmentName(nameToken);
 
     var element = TypeParameterElementImpl(name, nameToken.offset);
+    element.name2 = fragmentName;
     element.metadata = _buildAnnotations(node.metadata);
     _setCodeRange(element, node);
 
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 496439e..b823b74 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -816,6 +816,7 @@
         element as TypeParameterElementImpl;
         element.setCodeRange(info.codeOffset, info.codeLength);
         element.nameOffset = info.nameOffset;
+        _setFragmentNameOffset(element.name2, info.nameOffset2);
       },
     );
   }
@@ -2009,6 +2010,7 @@
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
       sink.writeUInt30(node.name.offset);
+      sink.writeOptionalUInt30(node.name.offsetIfNotEmpty);
     });
   }
 }
@@ -2046,12 +2048,14 @@
   final int codeOffset;
   final int codeLength;
   final int nameOffset;
+  final int? nameOffset2;
 
   factory _InfoTypeParameter(SummaryDataReader reader) {
     return _InfoTypeParameter._(
       codeOffset: reader.readUInt30(),
       codeLength: reader.readUInt30(),
       nameOffset: reader.readUInt30(),
+      nameOffset2: reader.readOptionalUInt30(),
     );
   }
 
@@ -2059,6 +2063,7 @@
     required this.codeOffset,
     required this.codeLength,
     required this.nameOffset,
+    required this.nameOffset2,
   });
 }
 
diff --git a/pkg/analyzer/test/src/summary/elements/class_test.dart b/pkg/analyzer/test/src/summary/elements/class_test.dart
index 89c2b46..a2e57b0 100644
--- a/pkg/analyzer/test/src/summary/elements/class_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/class_test.dart
@@ -25037,6 +25037,61 @@
 ''');
   }
 
+  test_class_typeParameters_missingName() async {
+    var library = await buildLibrary(r'''
+class A<T,> {}
+''');
+    checkElementText(library, r'''
+library
+  reference: <testLibrary>
+  definingUnit: <testLibraryFragment>
+  units
+    <testLibraryFragment>
+      enclosingElement3: <null>
+      classes
+        class A @6
+          reference: <testLibraryFragment>::@class::A
+          enclosingElement3: <testLibraryFragment>
+          typeParameters
+            covariant T @8
+              defaultType: dynamic
+            covariant @10
+              defaultType: dynamic
+          constructors
+            synthetic @-1
+              reference: <testLibraryFragment>::@class::A::@constructor::new
+              enclosingElement3: <testLibraryFragment>::@class::A
+----------------------------------------
+library
+  reference: <testLibrary>
+  fragments
+    <testLibraryFragment>
+      element: <testLibrary>
+      classes
+        class A @6
+          reference: <testLibraryFragment>::@class::A
+          element: <testLibraryFragment>::@class::A#element
+          typeParameters
+            T @8
+              element: <not-implemented>
+            <null-name>
+              element: <not-implemented>
+          constructors
+            synthetic <null-name>
+              reference: <testLibraryFragment>::@class::A::@constructor::new
+              element: <testLibraryFragment>::@class::A::@constructor::new#element
+  classes
+    class A
+      firstFragment: <testLibraryFragment>::@class::A
+      typeParameters
+        T
+        
+      constructors
+        synthetic new
+          firstFragment: <testLibraryFragment>::@class::A::@constructor::new
+''');
+  }
+
   test_class_typeParameters_variance_contravariant() async {
     var library = await buildLibrary('class C<in T> {}');
     checkElementText(library, r'''