Version 2.15.0-101.0.dev

Merge commit '30abce99f3b779d843e9caebd1896099ea515507' into 'dev'
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 4fa2db3..4271825 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -682,11 +682,7 @@
     // TODO(scheglov) The `ConstructorName` in a tear-off always has a name,
     //  but this is not expressed via types.
     computer._addRegion_node(
-      constructorName.name!,
-      HighlightRegionType.CONSTRUCTOR_TEAR_OFF,
-      semanticTokenType: SemanticTokenTypes.method,
-      semanticTokenModifiers: {CustomSemanticTokenModifiers.constructor},
-    );
+        constructorName.name!, HighlightRegionType.CONSTRUCTOR_TEAR_OFF);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
index 4d44191..1758d41 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
@@ -4,17 +4,17 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
-import 'package:analysis_server/src/lsp/semantic_tokens/legend.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
-final highlightRegionMapper = RegionTypeMapper();
-
 /// A mapping from [HighlightRegionType] to a set of [SemanticTokenModifiers].
 final highlightRegionTokenModifiers =
     <HighlightRegionType, Set<SemanticTokenModifiers>>{
   HighlightRegionType.COMMENT_DOCUMENTATION: {
     SemanticTokenModifiers.documentation
   },
+  HighlightRegionType.CONSTRUCTOR_TEAR_OFF: {
+    CustomSemanticTokenModifiers.constructor
+  },
   HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION: {
     SemanticTokenModifiers.declaration
   },
@@ -56,6 +56,7 @@
     SemanticTokenModifiers.static,
   },
   HighlightRegionType.STATIC_METHOD_REFERENCE: {SemanticTokenModifiers.static},
+  HighlightRegionType.STATIC_METHOD_TEAR_OFF: {SemanticTokenModifiers.static},
   HighlightRegionType.STATIC_SETTER_DECLARATION: {
     SemanticTokenModifiers.declaration,
     SemanticTokenModifiers.static,
@@ -87,6 +88,7 @@
   HighlightRegionType.COMMENT_BLOCK: SemanticTokenTypes.comment,
   HighlightRegionType.COMMENT_DOCUMENTATION: SemanticTokenTypes.comment,
   HighlightRegionType.COMMENT_END_OF_LINE: SemanticTokenTypes.comment,
+  HighlightRegionType.CONSTRUCTOR_TEAR_OFF: SemanticTokenTypes.method,
   HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION:
       SemanticTokenTypes.variable,
   HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE:
@@ -104,6 +106,7 @@
   HighlightRegionType.INSTANCE_GETTER_REFERENCE: SemanticTokenTypes.property,
   HighlightRegionType.INSTANCE_METHOD_DECLARATION: SemanticTokenTypes.method,
   HighlightRegionType.INSTANCE_METHOD_REFERENCE: SemanticTokenTypes.method,
+  HighlightRegionType.INSTANCE_METHOD_TEAR_OFF: SemanticTokenTypes.method,
   HighlightRegionType.INSTANCE_SETTER_DECLARATION: SemanticTokenTypes.property,
   HighlightRegionType.INSTANCE_SETTER_REFERENCE: SemanticTokenTypes.property,
   HighlightRegionType.KEYWORD: SemanticTokenTypes.keyword,
@@ -114,6 +117,7 @@
   HighlightRegionType.LITERAL_STRING: SemanticTokenTypes.string,
   HighlightRegionType.LOCAL_FUNCTION_DECLARATION: SemanticTokenTypes.function,
   HighlightRegionType.LOCAL_FUNCTION_REFERENCE: SemanticTokenTypes.function,
+  HighlightRegionType.LOCAL_FUNCTION_TEAR_OFF: SemanticTokenTypes.function,
   HighlightRegionType.LOCAL_VARIABLE_DECLARATION: SemanticTokenTypes.variable,
   HighlightRegionType.LOCAL_VARIABLE_REFERENCE: SemanticTokenTypes.variable,
   HighlightRegionType.PARAMETER_DECLARATION: SemanticTokenTypes.parameter,
@@ -123,11 +127,13 @@
   HighlightRegionType.STATIC_GETTER_REFERENCE: SemanticTokenTypes.property,
   HighlightRegionType.STATIC_METHOD_DECLARATION: SemanticTokenTypes.method,
   HighlightRegionType.STATIC_METHOD_REFERENCE: SemanticTokenTypes.method,
+  HighlightRegionType.STATIC_METHOD_TEAR_OFF: SemanticTokenTypes.method,
   HighlightRegionType.STATIC_SETTER_DECLARATION: SemanticTokenTypes.property,
   HighlightRegionType.STATIC_SETTER_REFERENCE: SemanticTokenTypes.property,
   HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION:
       SemanticTokenTypes.function,
   HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE: SemanticTokenTypes.function,
+  HighlightRegionType.TOP_LEVEL_FUNCTION_TEAR_OFF: SemanticTokenTypes.function,
   HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION: SemanticTokenTypes.property,
   HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE: SemanticTokenTypes.property,
   HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION: SemanticTokenTypes.property,
@@ -142,37 +148,3 @@
       CustomSemanticTokenTypes.source,
   HighlightRegionType.VALID_STRING_ESCAPE: SemanticTokenTypes.string,
 };
-
-/// A helper for converting from Server highlight regions to LSP semantic tokens.
-class RegionTypeMapper {
-  /// A map to get the [SemanticTokenTypes] index directly from a [HighlightRegionType].
-  final Map<HighlightRegionType, int> _tokenTypeIndexForHighlightRegion = {};
-
-  /// A map to get the [SemanticTokenModifiers] bitmask directly from a [HighlightRegionType].
-  final Map<HighlightRegionType, int> _tokenModifierBitmaskForHighlightRegion =
-      {};
-
-  RegionTypeMapper() {
-    // Build mappings that go directly from [HighlightRegionType] to index/bitmask
-    // for faster lookups.
-    for (final regionType in highlightRegionTokenTypes.keys) {
-      _tokenTypeIndexForHighlightRegion[regionType] = semanticTokenLegend
-          .indexForType(highlightRegionTokenTypes[regionType]!);
-    }
-
-    for (final regionType in highlightRegionTokenTypes.keys) {
-      _tokenModifierBitmaskForHighlightRegion[regionType] = semanticTokenLegend
-          .bitmaskForModifiers(highlightRegionTokenModifiers[regionType]);
-    }
-  }
-
-  /// Gets the [SemanticTokenModifiers] bitmask for a [HighlightRegionType]. Returns
-  /// null if the region type has not been mapped.
-  int bitmaskForModifier(HighlightRegionType type) =>
-      _tokenModifierBitmaskForHighlightRegion[type]!;
-
-  /// Gets the [SemanticTokenTypes] index for a [HighlightRegionType]. Returns
-  /// null if the region type has not been mapped.
-  int indexForToken(HighlightRegionType type) =>
-      _tokenTypeIndexForHighlightRegion[type]!;
-}
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 1b5d9a5..de5f35a 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -93,6 +93,7 @@
     final a = MyClass();
     final b = MyClass.named();
     final c = MyClass.factory();
+    final d = MyClass.named;
     ''';
 
     final expected = [
@@ -126,7 +127,13 @@
       _Token('MyClass', SemanticTokenTypes.class_,
           [CustomSemanticTokenModifiers.constructor]),
       _Token('factory', SemanticTokenTypes.method,
-          [CustomSemanticTokenModifiers.constructor])
+          [CustomSemanticTokenModifiers.constructor]),
+      _Token('final', SemanticTokenTypes.keyword),
+      _Token('d', SemanticTokenTypes.variable,
+          [SemanticTokenModifiers.declaration]),
+      _Token('MyClass', SemanticTokenTypes.class_),
+      _Token('named', SemanticTokenTypes.method,
+          [CustomSemanticTokenModifiers.constructor]),
     ];
 
     await initialize();
@@ -287,6 +294,8 @@
       final a = MyClass();
       a.myMethod();
       MyClass.myStaticMethod();
+      final b = a.myMethod;
+      final c = MyClass.myStaticMethod;
     }
     ''';
 
@@ -321,6 +330,17 @@
       _Token('MyClass', SemanticTokenTypes.class_),
       _Token('myStaticMethod', SemanticTokenTypes.method,
           [SemanticTokenModifiers.static]),
+      _Token('final', SemanticTokenTypes.keyword),
+      _Token('b', SemanticTokenTypes.variable,
+          [SemanticTokenModifiers.declaration]),
+      _Token('a', SemanticTokenTypes.variable),
+      _Token('myMethod', SemanticTokenTypes.method),
+      _Token('final', SemanticTokenTypes.keyword),
+      _Token('c', SemanticTokenTypes.variable,
+          [SemanticTokenModifiers.declaration]),
+      _Token('MyClass', SemanticTokenTypes.class_),
+      _Token('myStaticMethod', SemanticTokenTypes.method,
+          [SemanticTokenModifiers.static]),
     ];
 
     await initialize();
@@ -612,6 +632,38 @@
     expect(decoded, equals(expected));
   }
 
+  Future<void> test_local() async {
+    final content = '''
+    main() {
+      func(String a) => print(a);
+      final funcTearOff = func;
+    }
+    ''';
+
+    final expected = [
+      _Token('main', SemanticTokenTypes.function,
+          [SemanticTokenModifiers.declaration, SemanticTokenModifiers.static]),
+      _Token('func', SemanticTokenTypes.function,
+          [SemanticTokenModifiers.declaration]),
+      _Token('String', SemanticTokenTypes.class_),
+      _Token('a', SemanticTokenTypes.parameter,
+          [SemanticTokenModifiers.declaration]),
+      _Token('print', SemanticTokenTypes.function),
+      _Token('a', SemanticTokenTypes.parameter),
+      _Token('final', SemanticTokenTypes.keyword),
+      _Token('funcTearOff', SemanticTokenTypes.variable,
+          [SemanticTokenModifiers.declaration]),
+      _Token('func', SemanticTokenTypes.function),
+    ];
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final tokens = await getSemanticTokens(mainFileUri);
+    final decoded = decodeSemanticTokens(content, tokens);
+    expect(decoded, equals(expected));
+  }
+
   Future<void> test_manyBools_bug() async {
     // Similar to test_manyImports_sortBug, this code triggered inconsistent tokens
     // for "false" because tokens were sorted incorrectly (because both boolean and
@@ -990,6 +1042,8 @@
 
     /// abc docs
     bool get abc => true;
+
+    final funcTearOff = func;
     ''';
 
     final expected = [
@@ -1019,6 +1073,10 @@
       _Token('abc', SemanticTokenTypes.property,
           [SemanticTokenModifiers.declaration]),
       _Token('true', CustomSemanticTokenTypes.boolean),
+      _Token('final', SemanticTokenTypes.keyword),
+      _Token('funcTearOff', SemanticTokenTypes.variable,
+          [SemanticTokenModifiers.declaration]),
+      _Token('func', SemanticTokenTypes.function),
     ];
 
     await initialize();
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index 4db5773..aabb65f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -387,7 +387,8 @@
         );
 
         if (methodElement == null) {
-          // TODO(srawlins): Can we get here?
+          // The target is known, but the method is not; [UNDEFINED_GETTER] is
+          // reported elsewhere.
           node.staticType = DynamicTypeImpl.instance;
           return;
         } else {
@@ -395,7 +396,7 @@
           return;
         }
       } else {
-        // TODO(srawlins): Can we get here?
+        // The prefix is unknown; [UNDEFINED_IDENTIFIER] is reported elsewhere.
         node.staticType = DynamicTypeImpl.instance;
         return;
       }
@@ -440,7 +441,7 @@
   void _resolveReceiverPrefix(
     FunctionReferenceImpl node,
     PrefixElement prefixElement,
-    PrefixedIdentifier prefix,
+    PrefixedIdentifierImpl prefix,
     Element element,
   ) {
     if (element is MultiplyDefinedElement) {
@@ -477,10 +478,19 @@
         name: element.name,
       );
       return;
+    } else if (element is ExtensionElement) {
+      prefix.identifier.staticElement = element;
+      prefix.identifier.staticType = DynamicTypeImpl.instance;
+      prefix.staticType = DynamicTypeImpl.instance;
+      _resolveDisallowedExpression(node, DynamicTypeImpl.instance);
+      return;
     }
 
-    // TODO(srawlins): Report undefined prefixed identifier.
-
+    assert(
+      false,
+      'Member of prefixed element, $prefixElement, is not a class, mixin, '
+      'type alias, or executable element: $element (${element.runtimeType})',
+    );
     node.staticType = DynamicTypeImpl.instance;
   }
 
@@ -590,6 +600,11 @@
       function.staticType = element.type;
       _resolve(node: node, rawType: element.type);
       return;
+    } else if (element is ExtensionElement) {
+      function.staticElement = element;
+      function.staticType = DynamicTypeImpl.instance;
+      _resolveDisallowedExpression(node, DynamicTypeImpl.instance);
+      return;
     } else {
       _resolveDisallowedExpression(node, DynamicTypeImpl.instance);
       return;
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index b0d0ce9..1f36c75 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -19,7 +19,7 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(AssignabilityTest);
+    defineReflectiveTests(AssignabilityWithoutNullSafetyTest);
     defineReflectiveTests(TryPromoteToTest);
   });
 }
@@ -87,7 +87,8 @@
 }
 
 @reflectiveTest
-class AssignabilityTest extends AbstractTypeSystemWithoutNullSafetyTest {
+class AssignabilityWithoutNullSafetyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest {
   void test_isAssignableTo_bottom_isBottom() {
     var A = class_(name: 'A');
     List<DartType> interassignable = <DartType>[
@@ -435,7 +436,7 @@
 }
 
 @reflectiveTest
-class TryPromoteToTest extends AbstractTypeSystemWithoutNullSafetyTest {
+class TryPromoteToTest extends AbstractTypeSystemTest {
   void notPromotes(DartType from, DartType to) {
     var result = typeSystem.tryPromoteToType(to, from);
     expect(result, isNull);
diff --git a/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
index cf35b13..a6ab0bc 100644
--- a/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
+++ b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
@@ -15,38 +15,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ClassHierarchyLegacyTest);
-    defineReflectiveTests(ClassHierarchyNullSafetyTest);
+    defineReflectiveTests(ClassHierarchyTest);
+    defineReflectiveTests(ClassHierarchyWithoutNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class ClassHierarchyLegacyTest extends AbstractTypeSystemWithoutNullSafetyTest
-    with _AbstractClassHierarchyMixin {
-  @override
-  void setUp() {
-    super.setUp();
-    _createSharedElements();
-  }
-
-  test_invalid() {
-    _checkA(
-      typeArguments: [intNone, doubleNone],
-      interfaces: ['A<int*>'],
-      errors: ['A<int*> vs. A<double*>'],
-    );
-  }
-
-  test_valid() {
-    _checkA(
-      typeArguments: [intNone, intQuestion],
-      interfaces: ['A<int*>'],
-    );
-  }
-}
-
-@reflectiveTest
-class ClassHierarchyNullSafetyTest extends AbstractTypeSystemTest
+class ClassHierarchyTest extends AbstractTypeSystemTest
     with _AbstractClassHierarchyMixin {
   @override
   void setUp() {
@@ -84,6 +59,32 @@
   }
 }
 
+@reflectiveTest
+class ClassHierarchyWithoutNullSafetyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest
+    with _AbstractClassHierarchyMixin {
+  @override
+  void setUp() {
+    super.setUp();
+    _createSharedElements();
+  }
+
+  test_invalid() {
+    _checkA(
+      typeArguments: [intNone, doubleNone],
+      interfaces: ['A<int*>'],
+      errors: ['A<int*> vs. A<double*>'],
+    );
+  }
+
+  test_valid() {
+    _checkA(
+      typeArguments: [intNone, intQuestion],
+      interfaces: ['A<int*>'],
+    );
+  }
+}
+
 mixin _AbstractClassHierarchyMixin on ElementsTypesMixin {
   late ClassElementImpl A;
 
diff --git a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
index 9c1f2df..1e0d20f 100644
--- a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
@@ -11,138 +11,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(GreatestClosureLegacyTest);
-    defineReflectiveTests(GreatestClosureNullSafetyTest);
+    defineReflectiveTests(GreatestClosureTest);
+    defineReflectiveTests(GreatestClosureWithoutNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class GreatestClosureLegacyTest
-    extends AbstractTypeSystemWithoutNullSafetyTest {
-  late final TypeParameterElement T;
-  late final TypeParameterType T_none;
-  late final TypeParameterType T_question;
-  late final TypeParameterType T_star;
-
-  @override
-  void setUp() {
-    super.setUp();
-
-    T = typeParameter('T');
-    T_none = typeParameterTypeNone(T);
-    T_question = typeParameterTypeQuestion(T);
-    T_star = typeParameterTypeStar(T);
-  }
-
-  test_contravariant() {
-    _check(
-      functionTypeStar(returnType: voidNone, parameters: [
-        requiredParameter(type: T_star),
-      ]),
-      greatest: 'void Function(Null*)*',
-      least: 'void Function(dynamic)*',
-    );
-
-    _check(
-      functionTypeStar(
-        returnType: functionTypeStar(
-          returnType: voidNone,
-          parameters: [
-            requiredParameter(type: T_star),
-          ],
-        ),
-      ),
-      greatest: 'void Function(Null*)* Function()*',
-      least: 'void Function(dynamic)* Function()*',
-    );
-  }
-
-  test_covariant() {
-    _check(T_star, greatest: 'dynamic', least: 'Null*');
-
-    _check(
-      listStar(T_star),
-      greatest: 'List<dynamic>*',
-      least: 'List<Null*>*',
-    );
-
-    _check(
-      functionTypeStar(returnType: voidNone, parameters: [
-        requiredParameter(
-          type: functionTypeStar(returnType: intStar, parameters: [
-            requiredParameter(type: T_star),
-          ]),
-        ),
-      ]),
-      greatest: 'void Function(int* Function(dynamic)*)*',
-      least: 'void Function(int* Function(Null*)*)*',
-    );
-  }
-
-  test_function() {
-    // void Function<U extends T>()
-    _check(
-      functionTypeStar(
-        typeFormals: [
-          typeParameter('U', bound: T_star),
-        ],
-        returnType: voidNone,
-      ),
-      greatest: 'Function*',
-      least: 'Null*',
-    );
-  }
-
-  test_unrelated() {
-    _check1(intStar, 'int*');
-    _check1(listStar(intStar), 'List<int*>*');
-
-    _check1(objectStar, 'Object*');
-    _check1(neverStar, 'Never*');
-    _check1(nullStar, 'Null*');
-
-    _check1(dynamicNone, 'dynamic');
-
-    _check1(
-      functionTypeStar(returnType: stringStar, parameters: [
-        requiredParameter(type: intStar),
-      ]),
-      'String* Function(int*)*',
-    );
-
-    _check1(
-      typeParameterTypeStar(
-        typeParameter('U'),
-      ),
-      'U*',
-    );
-  }
-
-  void _check(
-    DartType type, {
-    required String greatest,
-    required String least,
-  }) {
-    var greatestResult = typeSystem.greatestClosure(type, [T]);
-    expect(
-      greatestResult.getDisplayString(withNullability: true),
-      greatest,
-    );
-
-    var leastResult = typeSystem.leastClosure(type, [T]);
-    expect(
-      leastResult.getDisplayString(withNullability: true),
-      least,
-    );
-  }
-
-  void _check1(DartType type, String expected) {
-    _check(type, greatest: expected, least: expected);
-  }
-}
-
-@reflectiveTest
-class GreatestClosureNullSafetyTest extends AbstractTypeSystemTest {
+class GreatestClosureTest extends AbstractTypeSystemTest {
   late final TypeParameterElement T;
   late final TypeParameterType T_none;
   late final TypeParameterType T_question;
@@ -273,3 +148,128 @@
     _check(type, greatest: expected, least: expected);
   }
 }
+
+@reflectiveTest
+class GreatestClosureWithoutNullSafetyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest {
+  late final TypeParameterElement T;
+  late final TypeParameterType T_none;
+  late final TypeParameterType T_question;
+  late final TypeParameterType T_star;
+
+  @override
+  void setUp() {
+    super.setUp();
+
+    T = typeParameter('T');
+    T_none = typeParameterTypeNone(T);
+    T_question = typeParameterTypeQuestion(T);
+    T_star = typeParameterTypeStar(T);
+  }
+
+  test_contravariant() {
+    _check(
+      functionTypeStar(returnType: voidNone, parameters: [
+        requiredParameter(type: T_star),
+      ]),
+      greatest: 'void Function(Null*)*',
+      least: 'void Function(dynamic)*',
+    );
+
+    _check(
+      functionTypeStar(
+        returnType: functionTypeStar(
+          returnType: voidNone,
+          parameters: [
+            requiredParameter(type: T_star),
+          ],
+        ),
+      ),
+      greatest: 'void Function(Null*)* Function()*',
+      least: 'void Function(dynamic)* Function()*',
+    );
+  }
+
+  test_covariant() {
+    _check(T_star, greatest: 'dynamic', least: 'Null*');
+
+    _check(
+      listStar(T_star),
+      greatest: 'List<dynamic>*',
+      least: 'List<Null*>*',
+    );
+
+    _check(
+      functionTypeStar(returnType: voidNone, parameters: [
+        requiredParameter(
+          type: functionTypeStar(returnType: intStar, parameters: [
+            requiredParameter(type: T_star),
+          ]),
+        ),
+      ]),
+      greatest: 'void Function(int* Function(dynamic)*)*',
+      least: 'void Function(int* Function(Null*)*)*',
+    );
+  }
+
+  test_function() {
+    // void Function<U extends T>()
+    _check(
+      functionTypeStar(
+        typeFormals: [
+          typeParameter('U', bound: T_star),
+        ],
+        returnType: voidNone,
+      ),
+      greatest: 'Function*',
+      least: 'Null*',
+    );
+  }
+
+  test_unrelated() {
+    _check1(intStar, 'int*');
+    _check1(listStar(intStar), 'List<int*>*');
+
+    _check1(objectStar, 'Object*');
+    _check1(neverStar, 'Never*');
+    _check1(nullStar, 'Null*');
+
+    _check1(dynamicNone, 'dynamic');
+
+    _check1(
+      functionTypeStar(returnType: stringStar, parameters: [
+        requiredParameter(type: intStar),
+      ]),
+      'String* Function(int*)*',
+    );
+
+    _check1(
+      typeParameterTypeStar(
+        typeParameter('U'),
+      ),
+      'U*',
+    );
+  }
+
+  void _check(
+    DartType type, {
+    required String greatest,
+    required String least,
+  }) {
+    var greatestResult = typeSystem.greatestClosure(type, [T]);
+    expect(
+      greatestResult.getDisplayString(withNullability: true),
+      greatest,
+    );
+
+    var leastResult = typeSystem.leastClosure(type, [T]);
+    expect(
+      leastResult.getDisplayString(withNullability: true),
+      least,
+    );
+  }
+
+  void _check1(DartType type, String expected) {
+    _check(type, greatest: expected, least: expected);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index 83fc399..c5e85ce 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -21,7 +21,7 @@
 }
 
 @reflectiveTest
-class PathToObjectTest extends AbstractTypeSystemWithoutNullSafetyTest {
+class PathToObjectTest extends AbstractTypeSystemTest {
   @override
   final TestTypeProvider typeProvider = TestTypeProvider();
 
@@ -351,7 +351,7 @@
 }
 
 @reflectiveTest
-class SuperinterfaceSetTest extends AbstractTypeSystemWithoutNullSafetyTest {
+class SuperinterfaceSetTest extends AbstractTypeSystemTest {
   @override
   final TestTypeProvider typeProvider = TestTypeProvider();
 
diff --git a/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart b/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
index ffdc9cc..af99f15 100644
--- a/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
+++ b/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
@@ -12,73 +12,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ReplaceTopBottomLegacyTest);
-    defineReflectiveTests(ReplaceTopBottomNullSafetyTest);
+    defineReflectiveTests(ReplaceTopBottomTest);
+    defineReflectiveTests(ReplaceTopBottomWithoutNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class ReplaceTopBottomLegacyTest
-    extends AbstractTypeSystemWithoutNullSafetyTest {
-  test_contravariant_bottom() {
-    // Not contravariant.
-    _check(nullStar, 'Null*');
-
-    _check(
-      functionTypeStar(returnType: intStar, parameters: [
-        requiredParameter(type: nullStar),
-      ]),
-      'int* Function(dynamic)*',
-    );
-  }
-
-  test_covariant_top() {
-    _check(objectStar, 'Null*');
-    _check(dynamicNone, 'Null*');
-    _check(voidNone, 'Null*');
-
-    _check(listStar(objectStar), 'List<Null*>*');
-    _check(listStar(dynamicNone), 'List<Null*>*');
-    _check(listStar(voidNone), 'List<Null*>*');
-
-    _check(futureOrStar(objectStar), 'Null*');
-    _check(futureOrStar(dynamicNone), 'Null*');
-    _check(futureOrStar(voidNone), 'Null*');
-    _check(futureOrStar(futureOrStar(voidNone)), 'Null*');
-
-    _check(
-      functionTypeStar(returnType: intStar, parameters: [
-        requiredParameter(
-          type: functionTypeStar(returnType: intStar, parameters: [
-            requiredParameter(type: objectStar),
-          ]),
-        ),
-      ]),
-      'int* Function(int* Function(Null*)*)*',
-      typeStr: 'int* Function(int* Function(Object*)*)*',
-    );
-
-    _check(intStar, 'int*');
-    _check(listStar(intStar), 'List<int*>*');
-  }
-
-  void _check(DartType type, String expectedStr, {String? typeStr}) {
-    if (typeStr != null) {
-      expect(_typeString(type), typeStr);
-    }
-
-    var result = typeSystem.replaceTopAndBottom(type);
-    var resultStr = _typeString(result);
-    expect(resultStr, expectedStr);
-  }
-
-  String _typeString(DartType type) {
-    return type.getDisplayString(withNullability: true);
-  }
-}
-
-@reflectiveTest
-class ReplaceTopBottomNullSafetyTest extends AbstractTypeSystemTest {
+class ReplaceTopBottomTest extends AbstractTypeSystemTest {
   test_contravariant_bottom() {
     // Not contravariant.
     _check(neverNone, 'Never');
@@ -174,3 +114,63 @@
     return type.getDisplayString(withNullability: true);
   }
 }
+
+@reflectiveTest
+class ReplaceTopBottomWithoutNullSafetyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest {
+  test_contravariant_bottom() {
+    // Not contravariant.
+    _check(nullStar, 'Null*');
+
+    _check(
+      functionTypeStar(returnType: intStar, parameters: [
+        requiredParameter(type: nullStar),
+      ]),
+      'int* Function(dynamic)*',
+    );
+  }
+
+  test_covariant_top() {
+    _check(objectStar, 'Null*');
+    _check(dynamicNone, 'Null*');
+    _check(voidNone, 'Null*');
+
+    _check(listStar(objectStar), 'List<Null*>*');
+    _check(listStar(dynamicNone), 'List<Null*>*');
+    _check(listStar(voidNone), 'List<Null*>*');
+
+    _check(futureOrStar(objectStar), 'Null*');
+    _check(futureOrStar(dynamicNone), 'Null*');
+    _check(futureOrStar(voidNone), 'Null*');
+    _check(futureOrStar(futureOrStar(voidNone)), 'Null*');
+
+    _check(
+      functionTypeStar(returnType: intStar, parameters: [
+        requiredParameter(
+          type: functionTypeStar(returnType: intStar, parameters: [
+            requiredParameter(type: objectStar),
+          ]),
+        ),
+      ]),
+      'int* Function(int* Function(Null*)*)*',
+      typeStr: 'int* Function(int* Function(Object*)*)*',
+    );
+
+    _check(intStar, 'int*');
+    _check(listStar(intStar), 'List<int*>*');
+  }
+
+  void _check(DartType type, String expectedStr, {String? typeStr}) {
+    if (typeStr != null) {
+      expect(_typeString(type), typeStr);
+    }
+
+    var result = typeSystem.replaceTopAndBottom(type);
+    var resultStr = _typeString(result);
+    expect(resultStr, expectedStr);
+  }
+
+  String _typeString(DartType type) {
+    return type.getDisplayString(withNullability: true);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index f695287..aa9f1fe 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -109,6 +109,50 @@
         findNode.functionReference('foo<int>;'), null, 'dynamic');
   }
 
+  test_extension() async {
+    await assertErrorsInCode('''
+extension E<T> on String {}
+
+void foo() {
+  E<int>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 44, 1),
+    ]);
+
+    var reference = findNode.functionReference('E<int>;');
+    assertFunctionReference(
+      reference,
+      findElement.extension_('E'),
+      'dynamic',
+    );
+  }
+
+  test_extension_prefixed() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+extension E<T> on String {}
+''');
+    await assertErrorsInCode('''
+import 'a.dart' as a;
+
+void foo() {
+  a.E<int>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 3),
+    ]);
+
+    assertImportPrefix(findNode.simple('a.E'), findElement.prefix('a'));
+    var reference = findNode.functionReference('E<int>;');
+    assertFunctionReference(
+      reference,
+      findElement.importFind('package:test/a.dart').extension_('E'),
+      'dynamic',
+    );
+  }
+
   test_extensionGetter_extensionOverride() async {
     await assertErrorsInCode('''
 class A {}
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index cadb164..66bd3bd 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -552,7 +552,7 @@
 
   const char* kScript = R"(
     const y = 0xDEADBEEF;
-    final int x = 0xFEEDFEED;
+    final int x = int.parse('0xFEEDFEED');
 
     void main(List<String> args) {
       print(x);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 7464bef..03d5a27 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2776,6 +2776,10 @@
              Class::Handle(field.Owner()).Name() == Symbols::ClassID().ptr());
       return Constant(Instance::ZoneHandle(
           Z, Instance::RawCast(field.StaticConstFieldValue())));
+    } else if (field.is_final() && field.has_trivial_initializer()) {
+      // Final fields with trivial initializers are effectively constant.
+      return Constant(Instance::ZoneHandle(
+          Z, Instance::RawCast(field.StaticConstFieldValue())));
     } else {
       const Class& owner = Class::Handle(Z, field.Owner());
       const String& getter_name = H.DartGetterName(target);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc
index f280b55..6bb19fa 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc
@@ -340,4 +340,44 @@
   // clang-format on
 }
 
+ISOLATE_UNIT_TEST_CASE(
+    StreamingFlowGraphBuilder_StaticGetFinalFieldWithTrivialInitializer) {
+  const char* kScript = R"(
+    final int x = 0xFEEDFEED;
+    test() {
+      return x;
+    }
+  )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& function = Function::Handle(GetFunction(root_library, "test"));
+
+  Invoke(root_library, "test");
+
+  TestPipeline pipeline(function, CompilerPass::kJIT);
+  FlowGraph* flow_graph = pipeline.RunPasses({
+      CompilerPass::kComputeSSA,
+  });
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+
+  ReturnInstr* return_instr = nullptr;
+
+  ILMatcher cursor(flow_graph, entry);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMatchAndMoveFunctionEntry,
+      kMatchAndMoveCheckStackOverflow,
+      kMoveDebugStepChecks,
+      {kMatchReturn, &return_instr},
+  }));
+
+  EXPECT(return_instr != nullptr);
+  ConstantInstr* const_value =
+      return_instr->value()->definition()->AsConstant();
+  EXPECT(const_value != nullptr);
+  EXPECT(const_value->value().IsInteger());
+  EXPECT_EQ(0xFEEDFEED, Integer::Cast(const_value->value()).AsInt64Value());
+}
+
 }  // namespace dart
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index f018ad4..6efc565 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -881,7 +881,8 @@
     SimpleExpressionConverter converter(&H, &helper_);
     const bool has_simple_initializer =
         converter.IsSimple(helper_.ReaderOffset() + 1);
-    if (!has_simple_initializer || !converter.SimpleValue().IsNull()) {
+    if (!has_simple_initializer ||
+        (!field.is_static() && !converter.SimpleValue().IsNull())) {
       field.set_has_nontrivial_initializer(true);
     }
     return;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 7a9fc6e..249c950 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11172,7 +11172,8 @@
 }
 
 ObjectPtr Field::StaticConstFieldValue() const {
-  ASSERT(is_static() && is_const());
+  ASSERT(is_static() &&
+         (is_const() || (is_final() && has_trivial_initializer())));
 
   auto thread = Thread::Current();
   auto zone = thread->zone();
@@ -11183,7 +11184,11 @@
   auto& value = Object::Handle(
       zone, initial_field_table->At(field_id(), /*concurrent_use=*/true));
   if (value.ptr() == Object::sentinel().ptr()) {
+    // Fields with trivial initializers get their initial value
+    // eagerly when they are registered.
+    ASSERT(is_const());
     ASSERT(has_initializer());
+    ASSERT(has_nontrivial_initializer());
     value = EvaluateInitializer();
     if (!value.IsError()) {
       ASSERT(value.IsNull() || value.IsInstance());
diff --git a/tools/VERSION b/tools/VERSION
index a417d59..c2f4478 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 100
+PRERELEASE 101
 PRERELEASE_PATCH 0
\ No newline at end of file