[CFE] Fix crash in expression evaluation related to type parameters

Change-Id: I9e86877a75c937fbb313ad1e492e15ced4a1be9d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448400
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/base/incremental_compiler.dart b/pkg/front_end/lib/src/base/incremental_compiler.dart
index adeaaf4..f08fd03c 100644
--- a/pkg/front_end/lib/src/base/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/base/incremental_compiler.dart
@@ -56,11 +56,13 @@
         VariableSet,
         VisitorDefault,
         VisitorVoidMixin,
-        Member;
+        Member,
+        TypeParameterType;
 import 'package:kernel/kernel.dart' as kernel show Combinator;
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/target/changed_structure_notifier.dart'
     show ChangedStructureNotifier;
+import 'package:kernel/type_algebra.dart' show Substitution;
 import 'package:package_config/package_config.dart' show Package, PackageConfig;
 
 import '../api_prototype/experimental_flags.dart';
@@ -1863,6 +1865,25 @@
             cls,
             offset,
           );
+
+          Map<TypeParameter, TypeParameterType> substitutionMap = {};
+          Map<String, TypeParameter> typeDefinitionNamesMap = {};
+          for (TypeParameter typeDefinition in typeDefinitions) {
+            if (typeDefinition.name != null) {
+              typeDefinitionNamesMap[typeDefinition.name!] = typeDefinition;
+            }
+          }
+          for (TypeParameter typeParameter in foundScope.typeParameters) {
+            TypeParameter? match = typeDefinitionNamesMap[typeParameter.name];
+            if (match != null) {
+              substitutionMap[typeParameter] = new TypeParameterType(
+                match,
+                match.computeNullabilityFromBound(),
+              );
+            }
+          }
+          Substitution substitution = Substitution.fromMap(substitutionMap);
+
           final bool alwaysInlineConstants = lastGoodKernelTarget
               .backendTarget
               .constantsBackend
@@ -1886,7 +1907,7 @@
                 extraKnownVariables.add(
                   new VariableDeclarationImpl(
                     def.key,
-                    type: def.value.type,
+                    type: substitution.substituteType(def.value.type),
                     isConst: true,
                     hasDeclaredInitializer: true,
                     initializer: def.value.initializer,
@@ -1905,7 +1926,7 @@
                 extraKnownVariables.add(
                   new VariableDeclarationImpl(
                     def.key,
-                    type: def.value.type,
+                    type: substitution.substituteType(def.value.type),
                     isConst: false,
                   )..fileOffset = def.value.fileOffset,
                 );
@@ -1914,7 +1935,9 @@
                 _ExtensionTypeFinder.isOrContainsExtensionType(
                   def.value.type,
                 )) {
-              usedDefinitions[def.key] = def.value.type;
+              usedDefinitions[def.key] = substitution.substituteType(
+                def.value.type,
+              );
             }
           }
         }
diff --git a/pkg/front_end/test/scopes/data/constructor.dart b/pkg/front_end/test/scopes/data/constructor.dart
index 8888384..bed1b98 100644
--- a/pkg/front_end/test/scopes/data/constructor.dart
+++ b/pkg/front_end/test/scopes/data/constructor.dart
@@ -101,9 +101,7 @@
      class=Foo2,
      member=foo,
      static,
-     typeParameters=[
-      Foo2.E,
-      Foo2.foo.E],
+     typeParameters=[Foo2.foo.E],
      variables=[a]
     */
     x;
@@ -131,7 +129,6 @@
      class=Foo2,
      member=bar,
      static,
-     typeParameters=[Foo2.E],
      variables=[a]
     */
     x;
@@ -143,9 +140,7 @@
      class=Foo2,
      member=baz,
      static,
-     typeParameters=[
-      Foo2.E,
-      Foo2.baz.E],
+     typeParameters=[Foo2.baz.E],
      variables=[a]
     */
     x;
diff --git a/pkg/front_end/test/scopes/data/mixins.dart b/pkg/front_end/test/scopes/data/mixins.dart
index b3987e3..5426efe 100644
--- a/pkg/front_end/test/scopes/data/mixins.dart
+++ b/pkg/front_end/test/scopes/data/mixins.dart
@@ -94,8 +94,7 @@
 
   static var field = /*
    class=GenericMixin,
-   member=field,
-   typeParameters=[GenericMixin.T]
+   member=field
   */
       x;
 
@@ -103,8 +102,7 @@
     /*
      class=GenericMixin,
      member=empty,
-     static,
-     typeParameters=[GenericMixin.T]
+     static
     */
     x;
   }
@@ -114,7 +112,6 @@
      class=GenericMixin,
      member=oneParameter,
      static,
-     typeParameters=[GenericMixin.T],
      variables=[a]
     */
     x;
@@ -125,7 +122,6 @@
      class=GenericMixin,
      member=twoParameters,
      static,
-     typeParameters=[GenericMixin.T],
      variables=[
       a,
       b]
@@ -138,7 +134,6 @@
      class=GenericMixin,
      member=optionalParameter,
      static,
-     typeParameters=[GenericMixin.T],
      variables=[
       a,
       b]
@@ -151,7 +146,6 @@
      class=GenericMixin,
      member=namedParameter,
      static,
-     typeParameters=[GenericMixin.T],
      variables=[
       a,
       b]
@@ -164,9 +158,7 @@
      class=GenericMixin,
      member=oneTypeParameter,
      static,
-     typeParameters=[
-      GenericMixin.T,
-      GenericMixin.oneTypeParameter.T]
+     typeParameters=[GenericMixin.oneTypeParameter.T]
     */
     x;
   }
diff --git a/pkg/kernel/lib/dart_scope_calculator.dart b/pkg/kernel/lib/dart_scope_calculator.dart
index 8084844..253eaac 100644
--- a/pkg/kernel/lib/dart_scope_calculator.dart
+++ b/pkg/kernel/lib/dart_scope_calculator.dart
@@ -111,10 +111,19 @@
         }
       }
     }
-    // TODO(jensj): If the current member is static and we're in a class we have
-    // to skip the typeParameters from the class.
+    int fromIndex = 0;
+    if (_currentCls != null &&
+        _currentMember != null &&
+        !_currentMember!.isInstanceMember &&
+        _currentMember is! Constructor) {
+      // We're inside a class, but currently in a static member (that is not a
+      // constructor). The first list in [typeParameterScopes] are the class
+      // ones, so we'll skip those here.
+      fromIndex = 1;
+    }
     List<TypeParameter> typeParameters = [];
-    for (List<TypeParameter> typeParameterScope in typeParameterScopes) {
+    for (int i = fromIndex; i < typeParameterScopes.length; i++) {
+      List<TypeParameter> typeParameterScope = typeParameterScopes[i];
       typeParameters.addAll(typeParameterScope);
     }
     DartScope2 findScope = new DartScope2(node, _library, _currentCls,
diff --git a/pkg/kernel/test/dart_scope_calculator_test.dart b/pkg/kernel/test/dart_scope_calculator_test.dart
index fb5a011..a0f7f4b 100644
--- a/pkg/kernel/test/dart_scope_calculator_test.dart
+++ b/pkg/kernel/test/dart_scope_calculator_test.dart
@@ -350,6 +350,15 @@
 
       List<Object> expectedTypeParameters =
           getTypeParameterIndexerForTesting().index.keys.toList();
+      if (currentMember != null &&
+          !currentMember!.isInstanceMember &&
+          currentMember is! Constructor &&
+          currentClass != null &&
+          currentClass!.typeParameters.isNotEmpty) {
+        expectedTypeParameters = (expectedTypeParameters.toSet()
+              ..removeAll(currentClass!.typeParameters))
+            .toList();
+      }
 
       VariableIndexer2? varIndexer =
           getVariableIndexerForTesting() as VariableIndexer2?;