Version 2.18.0-17.0.dev

Merge commit '3f9898cb5c684e519e31af514a59caf7fb1d6aab' into 'dev'
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
index f2a2aaa..eb6de83 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
@@ -7,7 +7,8 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/type_environment.dart';
 
-import '../js_interop.dart' show getJSName, hasStaticInteropAnnotation;
+import '../js_interop.dart'
+    show getJSName, hasStaticInteropAnnotation, hasJSInteropAnnotation;
 
 /// Replaces:
 ///   1) Factory constructors in classes with `@staticInterop` annotations with
@@ -101,14 +102,31 @@
         if (nodeDescriptor != null) {
           if (!nodeDescriptor.isStatic) {
             if (nodeDescriptor.kind == ExtensionMemberKind.Getter) {
-              transformedBody = _getExternalGetterBody(node);
+              transformedBody = _getExternalExtensionGetterBody(node);
             } else if (nodeDescriptor.kind == ExtensionMemberKind.Setter) {
-              transformedBody = _getExternalSetterBody(node);
+              transformedBody = _getExternalExtensionSetterBody(node);
             } else if (nodeDescriptor.kind == ExtensionMemberKind.Method) {
-              transformedBody = _getExternalMethodBody(node);
+              transformedBody = _getExternalExtensionMethodBody(node);
             }
           }
         }
+      } else if (hasJSInteropAnnotation(node)) {
+        String selectorString = getJSName(node);
+        late Expression target;
+        if (selectorString.isEmpty) {
+          target = _globalThis;
+        } else {
+          List<String> selectors = selectorString.split('.');
+          target = getObjectOffGlobalThis(node, selectors);
+        }
+        if (node.isGetter) {
+          transformedBody = _getExternalTopLevelGetterBody(node, target);
+        } else if (node.isSetter) {
+          transformedBody = _getExternalTopLevelSetterBody(node, target);
+        } else {
+          assert(node.kind == ProcedureKind.Method);
+          transformedBody = _getExternalTopLevelMethodBody(node, target);
+        }
       }
     }
     if (transformedBody != null) {
@@ -146,6 +164,22 @@
   Expression _jsifyVariable(VariableDeclaration variable) =>
       StaticInvocation(_jsifyTarget, Arguments([VariableGet(variable)]));
 
+  StaticInvocation get _globalThis =>
+      StaticInvocation(_globalThisTarget, Arguments([]));
+
+  /// Takes a list of [selectors] and returns an object off of
+  /// `globalThis`. We could optimize this with a custom method built with
+  /// js_ast.
+  Expression getObjectOffGlobalThis(Procedure node, List<String> selectors) {
+    Expression currentTarget = _globalThis;
+    for (String selector in selectors) {
+      currentTarget = _dartify(StaticInvocation(_getPropertyTarget,
+          Arguments([currentTarget, StringLiteral(selector)])))
+        ..fileOffset = node.fileOffset;
+    }
+    return currentTarget;
+  }
+
   /// Returns a new function body for the given [node] external method.
   ///
   /// The new function body will call `js_util_wasm.callConstructorVarArgs`
@@ -156,7 +190,7 @@
     var callConstructorInvocation = StaticInvocation(
         _callConstructorTarget,
         Arguments([
-          StaticInvocation(_globalThisTarget, Arguments([])),
+          _globalThis,
           StringLiteral(constructorName),
           ListLiteral(
               function.positionalParameters.map(_jsifyVariable).toList(),
@@ -171,62 +205,80 @@
 
   /// Returns a new function body for the given [node] external getter.
   ///
-  /// The new function body will call `js_util_wasm.getProperty` for the
-  /// given external getter.
-  ReturnStatement _getExternalGetterBody(Procedure node) {
-    var function = node.function;
-    assert(function.positionalParameters.length == 1);
-    var getPropertyInvocation = _dartify(StaticInvocation(
-        _getPropertyTarget,
-        Arguments([
-          VariableGet(function.positionalParameters.first),
-          StringLiteral(_getExtensionMemberName(node))
-        ])))
+  /// The new function body is equivalent to:
+  /// `js_util_wasm.getProperty([object], [getterName])`.
+  ReturnStatement _getExternalGetterBody(
+      Procedure node, Expression object, String getterName) {
+    final getPropertyInvocation = _dartify(StaticInvocation(
+        _getPropertyTarget, Arguments([object, StringLiteral(getterName)])))
       ..fileOffset = node.fileOffset;
     return ReturnStatement(getPropertyInvocation);
   }
 
+  ReturnStatement _getExternalExtensionGetterBody(Procedure node) =>
+      _getExternalGetterBody(
+          node,
+          VariableGet(node.function.positionalParameters.single),
+          _getExtensionMemberName(node));
+
+  ReturnStatement _getExternalTopLevelGetterBody(
+          Procedure node, Expression target) =>
+      _getExternalGetterBody(node, target, node.name.text);
+
   /// Returns a new function body for the given [node] external setter.
   ///
-  /// The new function body will call `js_util_wasm.setProperty` for
-  /// the given external setter.
-  ReturnStatement _getExternalSetterBody(Procedure node) {
-    var function = node.function;
-    assert(function.positionalParameters.length == 2);
-    var value = function.positionalParameters.last;
-    var setPropertyInvocation = _dartify(StaticInvocation(
-        _setPropertyTarget,
-        Arguments([
-          VariableGet(function.positionalParameters.first),
-          StringLiteral(_getExtensionMemberName(node)),
-          _jsifyVariable(value)
-        ])))
+  /// The new function body is equivalent to:
+  /// `js_util_wasm.setProperty([object], [setterName], [value])`.
+  ReturnStatement _getExternalSetterBody(Procedure node, Expression object,
+      String setterName, VariableDeclaration value) {
+    final setPropertyInvocation = _dartify(StaticInvocation(_setPropertyTarget,
+        Arguments([object, StringLiteral(setterName), _jsifyVariable(value)])))
       ..fileOffset = node.fileOffset;
     return ReturnStatement(setPropertyInvocation);
   }
 
+  ReturnStatement _getExternalExtensionSetterBody(Procedure node) {
+    final parameters = node.function.positionalParameters;
+    assert(parameters.length == 2);
+    return _getExternalSetterBody(node, VariableGet(parameters.first),
+        _getExtensionMemberName(node), parameters.last);
+  }
+
+  ReturnStatement _getExternalTopLevelSetterBody(
+          Procedure node, Expression target) =>
+      _getExternalSetterBody(node, target, node.name.text,
+          node.function.positionalParameters.single);
+
   /// Returns a new function body for the given [node] external method.
   ///
-  /// The new function body will call `js_util_wasm.callMethodVarArgs` for
-  /// the given external method.
-  ReturnStatement _getExternalMethodBody(Procedure node) {
-    var function = node.function;
-    var callMethodInvocation = _dartify(StaticInvocation(
+  /// The new function body is equivalent to:
+  /// `js_util_wasm.callMethodVarArgs([object], [methodName], [values])`.
+  ReturnStatement _getExternalMethodBody(Procedure node, Expression object,
+      String methodName, List<VariableDeclaration> values) {
+    final callMethodInvocation = _dartify(StaticInvocation(
         _callMethodTarget,
         Arguments([
-          VariableGet(function.positionalParameters.first),
-          StringLiteral(_getExtensionMemberName(node)),
-          ListLiteral(
-              function.positionalParameters
-                  .sublist(1)
-                  .map(_jsifyVariable)
-                  .toList(),
+          object,
+          StringLiteral(methodName),
+          ListLiteral(values.map(_jsifyVariable).toList(),
               typeArgument: _nullableJSValueType)
         ])))
       ..fileOffset = node.fileOffset;
     return ReturnStatement(callMethodInvocation);
   }
 
+  ReturnStatement _getExternalExtensionMethodBody(Procedure node) {
+    final parameters = node.function.positionalParameters;
+    assert(parameters.length > 0);
+    return _getExternalMethodBody(node, VariableGet(parameters.first),
+        _getExtensionMemberName(node), parameters.sublist(1));
+  }
+
+  ReturnStatement _getExternalTopLevelMethodBody(
+          Procedure node, Expression target) =>
+      _getExternalMethodBody(
+          node, target, node.name.text, node.function.positionalParameters);
+
   /// Returns the extension member name.
   ///
   /// Returns either the name from the `@JS` annotation if non-empty, or the
diff --git a/pkg/analysis_server/test/analysis_server_base.dart b/pkg/analysis_server/test/analysis_server_base.dart
index bdbd4ea..69ddef5 100644
--- a/pkg/analysis_server/test/analysis_server_base.dart
+++ b/pkg/analysis_server/test/analysis_server_base.dart
@@ -91,6 +91,9 @@
         EnableString.super_parameters,
       ];
 
+  /// The path that is not in [workspaceRootPath], contains external packages.
+  String get packagesRootPath => '/packages';
+
   Folder get sdkRoot => newFolder('/sdk');
 
   File get testFile => getFile(testFilePath);
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 8705302..5b6ffbe 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -7,13 +7,13 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'analysis_abstract.dart';
 import 'analysis_server_base.dart';
 import 'mocks.dart';
 
@@ -1465,23 +1465,29 @@
 }
 
 @reflectiveTest
-class SetSubscriptionsTest extends AbstractAnalysisTest {
-  Map<String, List<HighlightRegion>> filesHighlights = {};
+class SetSubscriptionsTest extends PubPackageAnalysisServerTest {
+  Map<File, List<HighlightRegion>> filesHighlights = {};
 
   final Completer<void> _resultsAvailable = Completer();
 
   @override
   void processNotification(Notification notification) {
+    super.processNotification(notification);
     if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
       var params = AnalysisHighlightsParams.fromNotification(notification);
-      filesHighlights[params.file] = params.regions;
+      filesHighlights[getFile(params.file)] = params.regions;
       _resultsAvailable.complete();
     }
   }
 
+  @override
+  Future<void> setUp() async {
+    super.setUp();
+    await setRoots(included: [workspaceRootPath], excluded: []);
+  }
+
   Future<void> test_afterAnalysis() async {
     addTestFile('int V = 42;');
-    await createProject();
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[testFile], isNull);
@@ -1493,9 +1499,8 @@
   }
 
   Future<void> test_afterAnalysis_noSuchFile() async {
-    var file = convertPath('/no-such-file.dart');
+    var file = getFile('/no-such-file.dart');
     addTestFile('// no matter');
-    await createProject();
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[testFile], isNull);
@@ -1510,7 +1515,7 @@
     var pkgFile = newFile2('/packages/pkgA/lib/libA.dart', '''
 library lib_a;
 class A {}
-''').path;
+''');
     newPackageConfigJsonFile(
       '/project',
       (PackageConfigFileBuilder()
@@ -1524,7 +1529,6 @@
   new A();
 }
 ''');
-    await createProject();
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[pkgFile], isNull);
@@ -1541,7 +1545,7 @@
     var pkgFileA = newFile2('$pkgA/lib/libA.dart', '''
 library lib_a;
 class A {}
-''').path;
+''');
     newFile2('$pkgA/lib/libB.dart', '''
 import 'package:pkgA/libA.dart';
 main() {
@@ -1549,7 +1553,6 @@
 }
 ''');
     // add 'pkgA' and 'pkgB' as projects
-    newFolder(projectPath);
     await setRoots(included: [pkgA, pkgB], excluded: []);
     // wait for analysis, no results initially
     await waitForTasksFinished();
@@ -1565,7 +1568,7 @@
     var pkgFile = newFile2('/packages/pkgA/lib/libA.dart', '''
 library lib_a;
 class A {}
-''').path;
+''');
     newPackageConfigJsonFile(
       '/project',
       (PackageConfigFileBuilder()
@@ -1574,12 +1577,11 @@
     );
     //
     addTestFile('// no "pkgA" reference');
-    await createProject();
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[pkgFile], isNull);
     // make it a priority file, so make analyzable
-    server.setPriorityFiles('0', [pkgFile]);
+    server.setPriorityFiles('0', [pkgFile.path]);
     // subscribe
     await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile);
     await _resultsAvailable.future;
@@ -1588,9 +1590,8 @@
   }
 
   Future<void> test_afterAnalysis_sdkFile() async {
-    var file = convertPath('/sdk/lib/core/core.dart');
+    var file = getFile('/sdk/lib/core/core.dart');
     addTestFile('// no matter');
-    await createProject();
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[file], isNull);
@@ -1603,7 +1604,6 @@
 
   Future<void> test_beforeAnalysis() async {
     addTestFile('int V = 42;');
-    await createProject();
     // subscribe
     await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
     // wait for analysis
@@ -1613,7 +1613,6 @@
 
   Future<void> test_sentToPlugins() async {
     addTestFile('int V = 42;');
-    await createProject();
     // subscribe
     await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
     // wait for analysis
@@ -1622,7 +1621,7 @@
     var subscriptions = params.subscriptions;
     expect(subscriptions, hasLength(1));
     var files = subscriptions[plugin.AnalysisService.HIGHLIGHTS];
-    expect(files, [testFile]);
+    expect(files, [testFile.path]);
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index dd79a90..bffbea1 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -6,7 +6,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'analysis_abstract.dart';
+import 'analysis_server_base.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -15,23 +15,20 @@
 }
 
 @reflectiveTest
-class DiagnosticDomainTest extends AbstractAnalysisTest {
+class DiagnosticDomainTest extends PubPackageAnalysisServerTest {
   Future<void> test_getDiagnostics() async {
-    newPubspecYamlFile('/project', 'name: project');
-    newFile2('/project/bin/test.dart', 'main() {}');
+    newPubspecYamlFile(testPackageRootPath, 'name: project');
+    newFile2('$testPackageLibPath/test.dart', 'main() {}');
 
-    await server.setAnalysisRoots('0', [convertPath('/project')], []);
-
+    await setRoots(included: [workspaceRootPath], excluded: []);
     await server.onAnalysisComplete;
 
     var request = DiagnosticGetDiagnosticsParams().toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     var result = DiagnosticGetDiagnosticsResult.fromResponse(response);
 
-    expect(result.contexts, hasLength(1));
-
-    var context = result.contexts[0];
-    expect(context.name, convertPath('/project'));
+    var context = result.contexts
+        .singleWhere((context) => context.name == testPackageRoot.path);
     expect(context.explicitFileCount, 1); /* test.dart */
 
     expect(context.implicitFileCount, 5);
@@ -41,7 +38,7 @@
 
   Future<void> test_getDiagnostics_noRoot() async {
     var request = DiagnosticGetDiagnosticsParams().toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     var result = DiagnosticGetDiagnosticsResult.fromResponse(response);
     expect(result.contexts, isEmpty);
   }
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index e1ec249..ce4b54c 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -4,10 +4,11 @@
 
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'analysis_abstract.dart';
+import 'analysis_server_base.dart';
 import 'mocks.dart';
 
 void main() {
@@ -116,13 +117,13 @@
 }
 
 @reflectiveTest
-class ExecutionDomainTest extends AbstractAnalysisTest {
+class ExecutionDomainTest extends PubPackageAnalysisServerTest {
   late String contextId;
 
   @override
   Future<void> setUp() async {
     super.setUp();
-    await createProject();
+    await setRoots(included: [workspaceRootPath], excluded: []);
     await _createExecutionContext(testFile);
   }
 
@@ -134,13 +135,13 @@
 
   Future<void> test_createAndDeleteMultipleContexts() async {
     var request = ExecutionCreateContextParams('/a/b.dart').toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('0'));
     var result = ExecutionCreateContextResult.fromResponse(response);
     var id0 = result.id;
 
     request = ExecutionCreateContextParams('/c/d.dart').toRequest('1');
-    response = await waitResponse(request);
+    response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('1'));
     result = ExecutionCreateContextResult.fromResponse(response);
     var id1 = result.id;
@@ -148,17 +149,17 @@
     expect(id0 == id1, isFalse);
 
     request = ExecutionDeleteContextParams(id0).toRequest('2');
-    response = await waitResponse(request);
+    response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('2'));
 
     request = ExecutionDeleteContextParams(id1).toRequest('3');
-    response = await waitResponse(request);
+    response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('3'));
   }
 
   Future<void> test_deleteNonExistentContext() async {
     var request = ExecutionDeleteContextParams('13').toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     // TODO(brianwilkerson) It isn't currently specified to be an error if a
     // client attempts to delete a context that doesn't exist. Should it be?
 //        expect(response, isResponseFailure('0'));
@@ -186,7 +187,7 @@
         path,
         code.indexOf('// context line'),
         <RuntimeCompletionVariable>[]).toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
 
     var result = ExecutionGetSuggestionsResult.fromResponse(response);
 //    expect(result.suggestions, isNotEmpty);
@@ -225,9 +226,9 @@
     expect(result.uri, isNull);
   }
 
-  Future<void> _createExecutionContext(String path) async {
-    var request = ExecutionCreateContextParams(path).toRequest('0');
-    var response = await waitResponse(request);
+  Future<void> _createExecutionContext(File file) async {
+    var request = ExecutionCreateContextParams(file.path).toRequest('0');
+    var response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('0'));
     var result = ExecutionCreateContextResult.fromResponse(response);
     contextId = result.id;
@@ -235,14 +236,14 @@
 
   Future<void> _disposeExecutionContext() async {
     var request = ExecutionDeleteContextParams(contextId).toRequest('1');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('1'));
   }
 
   Future<ExecutionMapUriResult> _mapUri({String? file, String? uri}) async {
     var request =
         ExecutionMapUriParams(contextId, file: file, uri: uri).toRequest('2');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     expect(response, isResponseSuccess('2'));
     return ExecutionMapUriResult.fromResponse(response);
   }
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index 4184735..d0e219f 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -15,7 +15,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(FixesCodeActionsTest);
-    defineReflectiveTests(FixesCodeActionsWithNullSafetyTest);
   });
 }
 
@@ -158,6 +157,85 @@
     expect(await ofKind(CodeActionKind.Refactor), isEmpty);
   }
 
+  Future<void> test_fixAll_notWhenNoBatchFix() async {
+    // Some fixes (for example 'create function foo') are not available in the
+    // batch processor, so should not generate fix-all-in-file fixes even if there
+    // are multiple instances.
+    const content = '''
+var a = [[foo]]();
+var b = bar();
+    ''';
+
+    newFile2(mainFilePath, withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final allFixes = await getCodeActions(mainFileUri.toString(),
+        range: rangeFromMarkers(content));
+
+    // Expect only the single-fix, there should be no apply-all.
+    expect(allFixes, hasLength(1));
+    final fixTitle = allFixes.first.map((f) => f.title, (f) => f.title);
+    expect(fixTitle, equals("Create function 'foo'"));
+  }
+
+  Future<void> test_fixAll_notWhenSingle() async {
+    const content = '''
+void f(String a) {
+  [[print(a!)]];
+}
+    ''';
+
+    newFile2(mainFilePath, withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        range: rangeFromMarkers(content));
+    final fixAction = findEditAction(
+        codeActions, CodeActionKind('quickfix'), "Remove '!'s in file");
+
+    // Should not appear if there was only a single error.
+    expect(fixAction, isNull);
+  }
+
+  Future<void> test_fixAll_whenMultiple() async {
+    const content = '''
+void f(String a) {
+  [[print(a!!)]];
+  print(a!!);
+}
+    ''';
+
+    const expectedContent = '''
+void f(String a) {
+  print(a);
+  print(a);
+}
+    ''';
+    newFile2(mainFilePath, withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        range: rangeFromMarkers(content));
+    final fixAction = findEditAction(
+        codeActions, CodeActionKind('quickfix'), "Remove '!'s in file")!;
+
+    // Ensure applying the changes will give us the expected content.
+    final contents = {
+      mainFilePath: withoutMarkers(content),
+    };
+    applyChanges(contents, fixAction.edit!.changes!);
+    expect(contents[mainFilePath], equals(expectedContent));
+  }
+
   Future<void> test_ignoreDiagnosticForFile() async {
     const content = '''
 // Header comment
@@ -239,6 +317,42 @@
     expect(contents[mainFilePath], equals(expectedContent));
   }
 
+  Future<void> test_noDuplicates_differentFix() async {
+    // For convenience, quick-fixes are usually returned for the entire line,
+    // though this can lead to duplicate entries (by title) when multiple
+    // diagnostics have their own fixes of the same type.
+    //
+    // Expect only the only one nearest to the start of the range to be returned.
+    const content = '''
+    main() {
+      var a = [];
+      print(a!!);^
+    }
+    ''';
+
+    newFile2(mainFilePath, withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        position: positionFromMarker(content));
+    final removeNnaAction = findEditActions(codeActions,
+        CodeActionKind('quickfix.remove.nonNullAssertion'), "Remove the '!'");
+
+    // Expect only one of the fixes.
+    expect(removeNnaAction, hasLength(1));
+
+    // Ensure the action is for the diagnostic on the second bang which was
+    // closest to the range requested.
+    final secondBangPos =
+        positionFromOffset(withoutMarkers(content).indexOf('!);'), content);
+    expect(removeNnaAction.first.diagnostics, hasLength(1));
+    final diagStart = removeNnaAction.first.diagnostics!.first.range.start;
+    expect(diagStart, equals(secondBangPos));
+  }
+
   Future<void> test_noDuplicates_sameFix() async {
     const content = '''
     var a = [Test, Test, Te[[]]st];
@@ -554,124 +668,3 @@
     expect(contents[mainFilePath], equals(expectedContent));
   }
 }
-
-@reflectiveTest
-class FixesCodeActionsWithNullSafetyTest extends AbstractCodeActionsTest {
-  @override
-  String get testPackageLanguageVersion => latestLanguageVersion;
-
-  Future<void> test_fixAll_notWhenNoBatchFix() async {
-    // Some fixes (for example 'create function foo') are not available in the
-    // batch processor, so should not generate fix-all-in-file fixes even if there
-    // are multiple instances.
-    const content = '''
-var a = [[foo]]();
-var b = bar();
-    ''';
-
-    newFile2(mainFilePath, withoutMarkers(content));
-    await initialize(
-      textDocumentCapabilities: withCodeActionKinds(
-          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
-    );
-
-    final allFixes = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
-
-    // Expect only the single-fix, there should be no apply-all.
-    expect(allFixes, hasLength(1));
-    final fixTitle = allFixes.first.map((f) => f.title, (f) => f.title);
-    expect(fixTitle, equals("Create function 'foo'"));
-  }
-
-  Future<void> test_fixAll_notWhenSingle() async {
-    const content = '''
-void f(String a) {
-  [[print(a!)]];
-}
-    ''';
-
-    newFile2(mainFilePath, withoutMarkers(content));
-    await initialize(
-      textDocumentCapabilities: withCodeActionKinds(
-          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
-    );
-
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
-    final fixAction = findEditAction(
-        codeActions, CodeActionKind('quickfix'), "Remove '!'s in file");
-
-    // Should not appear if there was only a single error.
-    expect(fixAction, isNull);
-  }
-
-  Future<void> test_fixAll_whenMultiple() async {
-    const content = '''
-void f(String a) {
-  [[print(a!!)]];
-  print(a!!);
-}
-    ''';
-
-    const expectedContent = '''
-void f(String a) {
-  print(a);
-  print(a);
-}
-    ''';
-    newFile2(mainFilePath, withoutMarkers(content));
-    await initialize(
-      textDocumentCapabilities: withCodeActionKinds(
-          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
-    );
-
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
-    final fixAction = findEditAction(
-        codeActions, CodeActionKind('quickfix'), "Remove '!'s in file")!;
-
-    // Ensure applying the changes will give us the expected content.
-    final contents = {
-      mainFilePath: withoutMarkers(content),
-    };
-    applyChanges(contents, fixAction.edit!.changes!);
-    expect(contents[mainFilePath], equals(expectedContent));
-  }
-
-  Future<void> test_noDuplicates_differentFix() async {
-    // For convenience, quick-fixes are usually returned for the entire line,
-    // though this can lead to duplicate entries (by title) when multiple
-    // diagnostics have their own fixes of the same type.
-    //
-    // Expect only the only one nearest to the start of the range to be returned.
-    const content = '''
-    main() {
-      var a = [];
-      print(a!!);^
-    }
-    ''';
-
-    newFile2(mainFilePath, withoutMarkers(content));
-    await initialize(
-      textDocumentCapabilities: withCodeActionKinds(
-          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
-    );
-
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        position: positionFromMarker(content));
-    final removeNnaAction = findEditActions(codeActions,
-        CodeActionKind('quickfix.remove.nonNullAssertion'), "Remove the '!'");
-
-    // Expect only one of the fixes.
-    expect(removeNnaAction, hasLength(1));
-
-    // Ensure the action is for the diagnostic on the second bang which was
-    // closest to the range requested.
-    final secondBangPos =
-        positionFromOffset(withoutMarkers(content).indexOf('!);'), content);
-    expect(removeNnaAction.first.diagnostics, hasLength(1));
-    final diagStart = removeNnaAction.first.diagnostics!.first.range.start;
-    expect(diagStart, equals(secondBangPos));
-  }
-}
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index a175f49..d508645 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -18,6 +18,8 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtractMethodRefactorCodeActionsTest);
     defineReflectiveTests(ExtractWidgetRefactorCodeActionsTest);
+    defineReflectiveTests(
+        ExtractWidgetRefactorCodeActionsWithoutNullSafetyTest);
     defineReflectiveTests(ExtractVariableRefactorCodeActionsTest);
     defineReflectiveTests(InlineLocalVariableRefactorCodeActionsTest);
     defineReflectiveTests(InlineMethodRefactorCodeActionsTest);
@@ -579,6 +581,9 @@
 class ExtractWidgetRefactorCodeActionsTest extends AbstractCodeActionsTest {
   final extractWidgetTitle = 'Extract Widget';
 
+  /// Nullability suffix expected in this test class.
+  String get expectedNullableSuffix => '?';
+
   @override
   void setUp() {
     super.setUp();
@@ -610,7 +615,7 @@
   }
 }
     ''';
-    const expectedContent = '''
+    final expectedContent = '''
 import 'package:flutter/material.dart';
 
 class MyWidget extends StatelessWidget {
@@ -628,7 +633,7 @@
 
 class NewWidget extends StatelessWidget {
   const NewWidget({
-    Key key,
+    Key$expectedNullableSuffix key,
   }) : super(key: key);
 
   @override
@@ -671,6 +676,16 @@
 }
 
 @reflectiveTest
+class ExtractWidgetRefactorCodeActionsWithoutNullSafetyTest
+    extends ExtractWidgetRefactorCodeActionsTest {
+  @override
+  String get expectedNullableSuffix => '';
+
+  @override
+  String get testPackageLanguageVersion => '2.9';
+}
+
+@reflectiveTest
 class InlineLocalVariableRefactorCodeActionsTest
     extends AbstractCodeActionsTest {
   final inlineVariableTitle = 'Inline Local Variable';
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index b91f9e7..c593f01 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -23,9 +23,7 @@
     defineReflectiveTests(CompletionTest);
     defineReflectiveTests(DartSnippetCompletionTest);
     defineReflectiveTests(FlutterSnippetCompletionTest);
-    defineReflectiveTests(
-        FlutterSnippetCompletionWithLatestLanguageVersionTest);
-    defineReflectiveTests(CompletionTestWithNullSafetyTest);
+    defineReflectiveTests(FlutterSnippetCompletionWithoutNullSafetyTest);
   });
 }
 
@@ -421,6 +419,77 @@
     );
   }
 
+  Future<void> test_completeFunctionCalls_requiredNamed() async {
+    final content = '''
+    void myFunction(String a, int b, {required String c, String d = ''}) {}
+
+    void f() {
+      [[myFu^]]
+    }
+    ''';
+
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholders.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b}, c: ${3:c})'));
+    final textEdit = toTextEdit(item.textEdit!);
+    expect(textEdit.newText, equals(item.insertText));
+    expect(textEdit.range, equals(rangeFromMarkers(content)));
+  }
+
+  Future<void> test_completeFunctionCalls_requiredNamed_suggestionSet() async {
+    final otherFile = join(projectFolderPath, 'lib', 'other.dart');
+    newFile2(
+      otherFile,
+      "void myFunction(String a, int b, {required String c, String d = ''}) {}",
+    );
+    final content = '''
+    void f() {
+      [[myFu^]]
+    }
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities: withApplyEditSupport(
+            withConfigurationSupport(emptyWorkspaceClientCapabilities)),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholders.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b}, c: ${3:c})'));
+    expect(item.textEdit, isNull);
+
+    // Ensure the item can be resolved and gets a proper TextEdit.
+    final resolved = await resolveCompletion(item);
+    expect(resolved.textEdit, isNotNull);
+    final textEdit = toTextEdit(resolved.textEdit!);
+    expect(textEdit.newText, equals(item.insertText));
+    expect(textEdit.range, equals(rangeFromMarkers(content)));
+  }
+
   Future<void> test_completeFunctionCalls_show() async {
     final content = '''
     import 'dart:math' show mi^
@@ -1254,6 +1323,25 @@
     expect(res, isEmpty);
   }
 
+  Future<void> test_nullableTypes() async {
+    final content = '''
+    String? foo(int? a, [int b = 1]) {}
+
+    void f() {
+      fo^
+    }
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completion = res.singleWhere((c) => c.label.startsWith('foo'));
+    expect(completion.detail, '(int? a, [int b = 1]) → String?');
+  }
+
   Future<void> test_parensNotInFilterTextInsertText() async {
     final content = '''
     class MyClass {}
@@ -2359,102 +2447,6 @@
 }
 
 @reflectiveTest
-class CompletionTestWithNullSafetyTest extends AbstractLspAnalysisServerTest {
-  @override
-  String get testPackageLanguageVersion => latestLanguageVersion;
-
-  Future<void> test_completeFunctionCalls_requiredNamed() async {
-    final content = '''
-    void myFunction(String a, int b, {required String c, String d = ''}) {}
-
-    void f() {
-      [[myFu^]]
-    }
-    ''';
-
-    await provideConfig(
-      () => initialize(
-        textDocumentCapabilities: withCompletionItemSnippetSupport(
-            emptyTextDocumentClientCapabilities),
-        workspaceCapabilities:
-            withConfigurationSupport(emptyWorkspaceClientCapabilities),
-      ),
-      {'completeFunctionCalls': true},
-    );
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
-    // Ensure the snippet comes through in the expected format with the expected
-    // placeholders.
-    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
-    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b}, c: ${3:c})'));
-    final textEdit = toTextEdit(item.textEdit!);
-    expect(textEdit.newText, equals(item.insertText));
-    expect(textEdit.range, equals(rangeFromMarkers(content)));
-  }
-
-  Future<void> test_completeFunctionCalls_requiredNamed_suggestionSet() async {
-    final otherFile = join(projectFolderPath, 'lib', 'other.dart');
-    newFile2(
-      otherFile,
-      "void myFunction(String a, int b, {required String c, String d = ''}) {}",
-    );
-    final content = '''
-    void f() {
-      [[myFu^]]
-    }
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await provideConfig(
-      () => initialize(
-        textDocumentCapabilities: withCompletionItemSnippetSupport(
-            emptyTextDocumentClientCapabilities),
-        workspaceCapabilities: withApplyEditSupport(
-            withConfigurationSupport(emptyWorkspaceClientCapabilities)),
-      ),
-      {'completeFunctionCalls': true},
-    );
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
-    // Ensure the snippet comes through in the expected format with the expected
-    // placeholders.
-    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
-    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b}, c: ${3:c})'));
-    expect(item.textEdit, isNull);
-
-    // Ensure the item can be resolved and gets a proper TextEdit.
-    final resolved = await resolveCompletion(item);
-    expect(resolved.textEdit, isNotNull);
-    final textEdit = toTextEdit(resolved.textEdit!);
-    expect(textEdit.newText, equals(item.insertText));
-    expect(textEdit.range, equals(rangeFromMarkers(content)));
-  }
-
-  Future<void> test_nullableTypes() async {
-    final content = '''
-    String? foo(int? a, [int b = 1]) {}
-
-    void f() {
-      fo^
-    }
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completion = res.singleWhere((c) => c.label.startsWith('foo'));
-    expect(completion.detail, '(int? a, [int b = 1]) → String?');
-  }
-}
-
-@reflectiveTest
 class DartSnippetCompletionTest extends SnippetCompletionTest {
   Future<void> test_snippets_class() async {
     final content = '''
@@ -2796,18 +2788,17 @@
 class FlutterSnippetCompletionTest extends SnippetCompletionTest {
   /// Standard import statements expected for basic Widgets.
   String get expectedImports => '''
-import 'package:flutter/src/foundation/key.dart';
 import 'package:flutter/src/widgets/framework.dart';''';
 
   /// Nullability suffix expected in this test class.
   ///
   /// Used to allow all tests to be run in both modes without having to
-  /// duplicate all tests ([FlutterSnippetCompletionWithLatestLanguageVersionTest]
+  /// duplicate all tests ([FlutterSnippetCompletionWithoutNullSafetyTest]
   /// overrides this).
-  String get expectedNullableSuffix => '';
+  String get expectedNullableSuffix => '?';
 
   /// Constructor params expected on Widget classes.
-  String get expectedWidgetConstructorParams => '({Key key}) : super(key: key)';
+  String get expectedWidgetConstructorParams => '({super.key})';
 
   @override
   void setUp() {
@@ -3069,20 +3060,21 @@
 }
 
 @reflectiveTest
-class FlutterSnippetCompletionWithLatestLanguageVersionTest
+class FlutterSnippetCompletionWithoutNullSafetyTest
     extends FlutterSnippetCompletionTest {
   @override
   String get expectedImports => '''
+import 'package:flutter/src/foundation/key.dart';
 import 'package:flutter/src/widgets/framework.dart';''';
 
   @override
-  String get expectedNullableSuffix => '?';
+  String get expectedNullableSuffix => '';
 
   @override
-  String get expectedWidgetConstructorParams => '({super.key})';
+  String get expectedWidgetConstructorParams => '({Key key}) : super(key: key)';
 
   @override
-  String get testPackageLanguageVersion => latestLanguageVersion;
+  String get testPackageLanguageVersion => '2.9';
 }
 
 abstract class SnippetCompletionTest extends AbstractLspAnalysisServerTest
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 3a7f8e0..e93fe89d 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -128,7 +128,7 @@
     newFile2(mainFilePath, '''
 void f() {
   x = 0;
-  int x;
+  int? x;
   print(x);
 }
 ''');
@@ -174,7 +174,7 @@
   Future<void> test_diagnosticTag_deprecated() async {
     newFile2(mainFilePath, '''
     @deprecated
-    int dep;
+    int? dep;
 
     void main() => print(dep);
     ''');
@@ -193,7 +193,7 @@
   Future<void> test_diagnosticTag_notSupported() async {
     newFile2(mainFilePath, '''
     @deprecated
-    int dep;
+    int? dep;
 
     void main() => print(dep);
     ''');
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index 9ac1ce2..967e185 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -13,7 +13,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(HoverTest);
-    defineReflectiveTests(HoverWithNullSafetyTest);
   });
 }
 
@@ -139,6 +138,29 @@
     expect(hover, isNull);
   }
 
+  Future<void> test_nullableTypes() async {
+    final content = '''
+    String? [[a^bc]];
+    ''';
+
+    final expectedHoverContent = '''
+```dart
+String? abc
+```
+Type: `String?`
+*package:test/main.dart*
+    '''
+        .trim();
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover!.range, equals(rangeFromMarkers(content)));
+    expect(hover.contents, isNotNull);
+    expect(_getStringContents(hover), equals(expectedHoverContent));
+  }
+
   Future<void> test_plainText_simple() async {
     final content = '''
     /// This is a string.
@@ -340,32 +362,3 @@
     );
   }
 }
-
-@reflectiveTest
-class HoverWithNullSafetyTest extends HoverTest {
-  @override
-  String get testPackageLanguageVersion => latestLanguageVersion;
-
-  Future<void> test_nullableTypes() async {
-    final content = '''
-    String? [[a^bc]];
-    ''';
-
-    final expectedHoverContent = '''
-```dart
-String? abc
-```
-Type: `String?`
-*package:test/main.dart*
-    '''
-        .trim();
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final hover = await getHover(mainFileUri, positionFromMarker(content));
-    expect(hover, isNotNull);
-    expect(hover!.range, equals(rangeFromMarkers(content)));
-    expect(hover.contents, isNotNull);
-    expect(_getStringContents(hover), equals(expectedHoverContent));
-  }
-}
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 0873411..bb5e2d7 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -561,7 +561,7 @@
       '${ExperimentStatus.currentVersion.major}.'
       '${ExperimentStatus.currentVersion.minor}';
 
-  String get testPackageLanguageVersion => '2.9';
+  String get testPackageLanguageVersion => latestLanguageVersion;
 
   void writePackageConfig(
     String projectFolderPath, {
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index 17ffa43..9a59150 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -11,7 +11,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SignatureHelpTest);
-    defineReflectiveTests(SignatureHelpWithNullSafetyTest);
   });
 }
 
@@ -411,6 +410,34 @@
     );
   }
 
+  Future<void> test_params_requiredNamed() async {
+    // This test requires support for the "required" keyword.
+    final content = '''
+    /// Does foo.
+    foo(String s, {bool? b = true, required bool a}) {
+      foo(^);
+    }
+    ''';
+
+    final expectedLabel = 'foo(String s, {bool? b = true, required bool a})';
+    final expectedDoc = 'Does foo.';
+
+    await initialize(
+        textDocumentCapabilities: withSignatureHelpContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.Markdown]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await testSignature(
+      content,
+      expectedLabel,
+      expectedDoc,
+      [
+        ParameterInformation(label: 'String s'),
+        ParameterInformation(label: 'bool? b = true'),
+        ParameterInformation(label: 'required bool a'),
+      ],
+    );
+  }
+
   Future<void> test_simple() async {
     final content = '''
     /// Does foo.
@@ -597,38 +624,3 @@
     );
   }
 }
-
-@reflectiveTest
-class SignatureHelpWithNullSafetyTest extends AbstractLspAnalysisServerTest
-    with SignatureHelpMixin {
-  @override
-  String get testPackageLanguageVersion => latestLanguageVersion;
-
-  Future<void> test_params_requiredNamed() async {
-    // This test requires support for the "required" keyword.
-    final content = '''
-    /// Does foo.
-    foo(String s, {bool? b = true, required bool a}) {
-      foo(^);
-    }
-    ''';
-
-    final expectedLabel = 'foo(String s, {bool? b = true, required bool a})';
-    final expectedDoc = 'Does foo.';
-
-    await initialize(
-        textDocumentCapabilities: withSignatureHelpContentFormat(
-            emptyTextDocumentClientCapabilities, [MarkupKind.Markdown]));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await testSignature(
-      content,
-      expectedLabel,
-      expectedDoc,
-      [
-        ParameterInformation(label: 'String s'),
-        ParameterInformation(label: 'bool? b = true'),
-        ParameterInformation(label: 'required bool a'),
-      ],
-    );
-  }
-}
diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart
index 15cba77..85ffa59 100644
--- a/pkg/analysis_server/test/search/abstract_search_domain.dart
+++ b/pkg/analysis_server/test/search/abstract_search_domain.dart
@@ -5,13 +5,13 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/search/search_domain.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
 import '../analysis_abstract.dart';
+import '../analysis_server_base.dart';
 
-class AbstractSearchDomainTest extends AbstractAnalysisTest {
+class AbstractSearchDomainTest extends PubPackageAnalysisServerTest {
   final Map<String, _ResultSet> resultSets = {};
   String? searchId;
   List<SearchResult> results = <SearchResult>[];
@@ -20,13 +20,13 @@
   void assertHasResult(SearchResultKind kind, String search, [int? length]) {
     var offset = findOffset(search);
     length ??= findIdentifierLength(search);
-    findResult(kind, testFile, offset, length, true);
+    findResult(kind, testFile.path, offset, length, true);
   }
 
   void assertNoResult(SearchResultKind kind, String search, [int? length]) {
     var offset = findOffset(search);
     length ??= findIdentifierLength(search);
-    findResult(kind, testFile, offset, length, false);
+    findResult(kind, testFile.path, offset, length, false);
   }
 
   void findResult(SearchResultKind kind, String file, int offset, int length,
@@ -81,10 +81,7 @@
   @override
   Future<void> setUp() async {
     super.setUp();
-    await createProject();
-    server.handlers = [
-      SearchDomainHandler(server),
-    ];
+    await setRoots(included: [workspaceRootPath], excluded: []);
   }
 
   Future waitForSearchResults() {
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index c5f71ad..1fc44a1 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -22,7 +22,7 @@
   ElementDeclaration assertHas(String name, ElementKind kind,
       {String? className, String? mixinName}) {
     return declarationsResult.declarations.singleWhere((ElementDeclaration d) =>
-        declarationsResult.files[d.fileIndex] == testFile &&
+        declarationsResult.files[d.fileIndex] == testFile.path &&
         d.name == name &&
         d.kind == kind &&
         d.className == className &&
@@ -33,7 +33,7 @@
     expect(
         declarationsResult.declarations,
         isNot(contains(predicate((ElementDeclaration d) =>
-            declarationsResult.files[d.fileIndex] == testFile &&
+            declarationsResult.files[d.fileIndex] == testFile.path &&
             d.name == name))));
   }
 
@@ -83,11 +83,11 @@
   }
 
   Future<void> test_maxResults() async {
-    newFile2(join(testFolder, 'a.dart'), r'''
+    newFile2('$testPackageLibPath/a.dart', r'''
 class A {}
 class B {}
 ''').path;
-    newFile2(join(testFolder, 'b.dart'), r'''
+    newFile2('$testPackageLibPath/b.dart', r'''
 class C {}
 class D {}
 ''').path;
@@ -124,8 +124,8 @@
   }
 
   Future<void> test_multipleFiles() async {
-    var a = newFile2(join(testFolder, 'a.dart'), 'class A {}').path;
-    var b = newFile2(join(testFolder, 'b.dart'), 'class B {}').path;
+    var a = newFile2('$testPackageLibPath/a.dart', 'class A {}').path;
+    var b = newFile2('$testPackageLibPath/b.dart', 'class B {}').path;
 
     await _getDeclarations();
 
@@ -153,8 +153,8 @@
   }
 
   Future<void> test_onlyForFile() async {
-    var a = newFile2(join(testFolder, 'a.dart'), 'class A {}').path;
-    newFile2(join(testFolder, 'b.dart'), 'class B {}').path;
+    var a = newFile2('$testPackageLibPath/a.dart', 'class A {}').path;
+    newFile2('$testPackageLibPath/b.dart', 'class B {}').path;
 
     await _getDeclarations(file: a);
 
@@ -218,7 +218,7 @@
     var request = SearchGetElementDeclarationsParams(
             file: file, pattern: pattern, maxResults: maxResults)
         .toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
 
     declarationsResult =
         SearchGetElementDeclarationsResult.fromResponse(response);
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 2902a26..de8f23e 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -28,10 +28,10 @@
       String search, bool includePotential) async {
     var offset = findOffset(search);
     await waitForTasksFinished();
-    var request =
-        SearchFindElementReferencesParams(testFile, offset, includePotential)
-            .toRequest('0');
-    var response = await waitResponse(request);
+    var request = SearchFindElementReferencesParams(
+            testFile.path, offset, includePotential)
+        .toRequest('0');
+    var response = await handleSuccessfulRequest(request);
     var result = SearchFindElementReferencesResult.fromResponse(response);
     searchId = result.id;
     searchElement = result.element;
diff --git a/pkg/analysis_server/test/search/member_declarations_test.dart b/pkg/analysis_server/test/search/member_declarations_test.dart
index 42be69a..9d4a783 100644
--- a/pkg/analysis_server/test/search/member_declarations_test.dart
+++ b/pkg/analysis_server/test/search/member_declarations_test.dart
@@ -28,7 +28,7 @@
   Future findMemberDeclarations(String name) async {
     await waitForTasksFinished();
     var request = SearchFindMemberDeclarationsParams(name).toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     var result = SearchFindMemberDeclarationsResult.fromResponse(response);
     searchId = result.id;
     return waitForSearchResults();
diff --git a/pkg/analysis_server/test/search/member_references_test.dart b/pkg/analysis_server/test/search/member_references_test.dart
index b5df9ae..a3a5d94 100644
--- a/pkg/analysis_server/test/search/member_references_test.dart
+++ b/pkg/analysis_server/test/search/member_references_test.dart
@@ -24,7 +24,7 @@
   Future findMemberReferences(String name) async {
     await waitForTasksFinished();
     var request = SearchFindMemberReferencesParams(name).toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleSuccessfulRequest(request);
     searchId = SearchFindMemberReferencesResult.fromResponse(response).id;
     return waitForSearchResults();
   }
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 6fd2959..c6d28b3 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -35,7 +35,7 @@
   Future findTopLevelDeclarations(String pattern) async {
     await waitForTasksFinished();
     var request = SearchFindTopLevelDeclarationsParams(pattern).toRequest('0');
-    var response = await waitResponse(request);
+    var response = await handleRequest(request);
     if (response.error != null) {
       return response.error;
     }
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 589e9a5..296fb20 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -4,13 +4,11 @@
 
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/domain_analysis.dart';
-import 'package:analysis_server/src/search/search_domain.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../analysis_abstract.dart';
+import '../analysis_server_base.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -19,17 +17,13 @@
 }
 
 @reflectiveTest
-class GetTypeHierarchyTest extends AbstractAnalysisTest {
+class GetTypeHierarchyTest extends PubPackageAnalysisServerTest {
   static const String requestId = 'test-getTypeHierarchy';
 
   @override
   Future<void> setUp() async {
     super.setUp();
-    await createProject();
-    server.handlers = [
-      AnalysisDomainHandler(server),
-      SearchDomainHandler(server),
-    ];
+    await setRoots(included: [workspaceRootPath], excluded: []);
   }
 
   Future<void> test_bad_function() async {
@@ -164,22 +158,22 @@
 
   Future<void> test_class_extends_fileAndPackageUris() async {
     // prepare packages
-    newFile2('/packages/pkgA/lib/libA.dart', '''
+    newFile2('$packagesRootPath/pkgA/lib/libA.dart', '''
 library lib_a;
 class A {}
 class B extends A {}
 ''');
     newPackageConfigJsonFile(
-      '/packages/pkgA',
+      '$packagesRootPath/pkgA',
       (PackageConfigFileBuilder()
-            ..add(name: 'pkgA', rootPath: '/packages/pkgA'))
+            ..add(name: 'pkgA', rootPath: '$packagesRootPath/pkgA'))
           .toContent(toUriStr: toUriStr),
     );
     // reference the package from a project
     newPackageConfigJsonFile(
-      projectPath,
+      testPackageRootPath,
       (PackageConfigFileBuilder()
-            ..add(name: 'pkgA', rootPath: '/packages/pkgA'))
+            ..add(name: 'pkgA', rootPath: '$packagesRootPath/pkgA'))
           .toContent(toUriStr: toUriStr),
     );
     addTestFile('''
@@ -189,7 +183,9 @@
     await waitForTasksFinished();
     // configure roots
     await setRoots(
-        included: [projectPath, convertPath('/packages/pkgA')], excluded: []);
+      included: [workspaceRootPath, '$packagesRootPath/pkgA'],
+      excluded: [],
+    );
     // test A type hierarchy
     var items = await _getTypeHierarchy('A {}');
     var names = _toClassNames(items);
@@ -652,7 +648,7 @@
   }
 
   Future<void> test_class_member_method_private_differentLib() async {
-    newFile2(join(testFolder, 'lib.dart'), r'''
+    newFile2('$testPackageLibPath/lib.dart', r'''
 import 'test.dart';
 class A {
   void _m() {}
@@ -1473,7 +1469,7 @@
   }
 
   Request _createGetTypeHierarchyRequest(String search, {bool? superOnly}) {
-    return SearchGetTypeHierarchyParams(testFile, findOffset(search),
+    return SearchGetTypeHierarchyParams(testFile.path, findOffset(search),
             superOnly: superOnly)
         .toRequest(requestId);
   }
diff --git a/pkg/analysis_server/test/src/domains/flutter/base.dart b/pkg/analysis_server/test/src/domains/flutter/base.dart
index 39d724f..ab24425 100644
--- a/pkg/analysis_server/test/src/domains/flutter/base.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/base.dart
@@ -2,17 +2,16 @@
 // 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.
 
-import 'package:analysis_server/src/flutter/flutter_domain.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../analysis_abstract.dart';
+import '../../../analysis_server_base.dart';
 import '../../utilities/mock_packages.dart';
 
 @reflectiveTest
-class FlutterBase extends AbstractAnalysisTest {
+class FlutterBase extends PubPackageAnalysisServerTest {
   FlutterWidgetProperty getProperty(
     FlutterGetWidgetDescriptionResult result,
     String name,
@@ -32,32 +31,29 @@
 
   Future<Response> getWidgetDescriptionResponse(String search) async {
     var request = FlutterGetWidgetDescriptionParams(
-      testFile,
+      testFile.path,
       findOffset(search),
     ).toRequest('0');
-    return await waitResponse(request);
+    return await handleRequest(request);
   }
 
   @override
   Future<void> setUp() async {
     super.setUp();
-    projectPath = convertPath('/home');
-    testFile = convertPath('/home/test/lib/test.dart');
 
-    newPubspecYamlFile('/home/test', '');
+    newPubspecYamlFile(testPackageRootPath, '');
 
     var metaLib = MockPackages.instance.addMeta(resourceProvider);
     var flutterLib = MockPackages.instance.addFlutter(resourceProvider);
     newPackageConfigJsonFile(
       '/home/test',
       (PackageConfigFileBuilder()
-            ..add(name: 'test', rootPath: '/home/test')
+            ..add(name: 'test', rootPath: testPackageRootPath)
             ..add(name: 'meta', rootPath: metaLib.parent.path)
             ..add(name: 'flutter', rootPath: flutterLib.parent.path))
           .toContent(toUriStr: toUriStr),
     );
 
-    await createProject();
-    handler = server.handlers.whereType<FlutterDomainHandler>().single;
+    await setRoots(included: [workspaceRootPath], excluded: []);
   }
 }
diff --git a/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart b/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart
index 39baacd..b926395 100644
--- a/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart
@@ -43,9 +43,10 @@
 ''');
 
     var response = await getWidgetDescriptionResponse('42');
-    expect(
-      response.error!.code,
-      RequestErrorCode.FLUTTER_GET_WIDGET_DESCRIPTION_NO_WIDGET,
+    assertResponseFailure(
+      response,
+      requestId: '0',
+      errorCode: RequestErrorCode.FLUTTER_GET_WIDGET_DESCRIPTION_NO_WIDGET,
     );
   }
 
@@ -57,9 +58,10 @@
 ''');
 
     var response = await getWidgetDescriptionResponse('new Foo');
-    expect(
-      response.error!.code,
-      RequestErrorCode.FLUTTER_GET_WIDGET_DESCRIPTION_NO_WIDGET,
+    assertResponseFailure(
+      response,
+      requestId: '0',
+      errorCode: RequestErrorCode.FLUTTER_GET_WIDGET_DESCRIPTION_NO_WIDGET,
     );
   }
 }
diff --git a/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart b/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart
index 56a8c90..af74a41 100644
--- a/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart
@@ -125,10 +125,10 @@
     expect(fileEdits, hasLength(1));
 
     var fileEdit = fileEdits[0];
-    expect(fileEdit.file, testFile);
+    expect(fileEdit.file, testFile.path);
 
     var edits = fileEdit.edits;
-    expect(SourceEdit.applySequence(testCode, edits), expected);
+    expect(SourceEdit.applySequence(testFileContent, edits), expected);
   }
 
   Future<FlutterSetWidgetPropertyValueResult> _setValue(
@@ -148,6 +148,6 @@
       property.id,
       value: value,
     ).toRequest('0');
-    return await waitResponse(request);
+    return await handleSuccessfulRequest(request);
   }
 }
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart
index 96c2b66..cd23e2a 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart
@@ -7,13 +7,12 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/flutter/flutter_domain.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../analysis_abstract.dart';
+import '../../analysis_server_base.dart';
 import '../utilities/mock_packages.dart';
 
 void main() {
@@ -23,42 +22,31 @@
 }
 
 @reflectiveTest
-class FlutterNotificationOutlineTest extends AbstractAnalysisTest {
+class FlutterNotificationOutlineTest extends PubPackageAnalysisServerTest {
   late Folder flutterFolder;
 
-  final Map<FlutterService, List<String>> flutterSubscriptions = {};
-
   final Completer<void> _outlineReceived = Completer();
   late FlutterOutline outline;
 
-  FlutterDomainHandler get flutterHandler =>
-      server.handlers.singleWhere((handler) => handler is FlutterDomainHandler)
-          as FlutterDomainHandler;
-
-  void addFlutterSubscription(FlutterService service, String file) {
-    // add file to subscription
-    var files = analysisSubscriptions[service];
-    if (files == null) {
-      files = <String>[];
-      flutterSubscriptions[service] = files;
-    }
-    files.add(file);
-    // set subscriptions
-    var request =
-        FlutterSetSubscriptionsParams(flutterSubscriptions).toRequest('0');
-    handleSuccessfulRequest(request, handler: flutterHandler);
+  Future<void> addFlutterSubscription(FlutterService service, File file) async {
+    await handleSuccessfulRequest(
+      FlutterSetSubscriptionsParams({
+        service: [file.path],
+      }).toRequest('0'),
+    );
   }
 
-  Future prepareOutline() {
-    addFlutterSubscription(FlutterService.OUTLINE, testFile);
+  Future<void> prepareOutline() async {
+    await addFlutterSubscription(FlutterService.OUTLINE, testFile);
     return _outlineReceived.future;
   }
 
   @override
   void processNotification(Notification notification) {
+    super.processNotification(notification);
     if (notification.event == FLUTTER_NOTIFICATION_OUTLINE) {
       var params = FlutterOutlineParams.fromNotification(notification);
-      if (params.file == testFile) {
+      if (params.file == testFile.path) {
         outline = params.outline;
         _outlineReceived.complete();
       }
@@ -68,18 +56,18 @@
   @override
   Future<void> setUp() async {
     super.setUp();
-    await createProject();
+    await setRoots(included: [workspaceRootPath], excluded: []);
     flutterFolder = MockPackages.instance.addFlutter(resourceProvider);
   }
 
   Future<void> test_children() async {
     newPackageConfigJsonFile(
-      projectPath,
+      testPackageRootPath,
       (PackageConfigFileBuilder()
             ..add(name: 'flutter', rootPath: flutterFolder.parent.path))
           .toContent(toUriStr: toUriStr),
     );
-    newAnalysisOptionsYamlFile2(projectPath, '''
+    newAnalysisOptionsYamlFile2(testPackageRootPath, '''
 analyzer:
   strong-mode: true
 ''');
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
index 8b99bb3..1edef57 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -318,8 +318,7 @@
   }
   Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset);
   _createTearOffBody(tearOff, target, arguments);
-  return new DelayedDefaultValueCloner(
-      substitutionMap, target.function!, tearOff.function,
+  return new DelayedDefaultValueCloner(target, tearOff, substitutionMap,
       identicalSignatures: false, libraryBuilder: libraryBuilder);
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
index 42c969f..75a94cf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
@@ -26,11 +26,11 @@
   //  variable types in default values be a compile time error?
   final Map<TypeParameter, DartType> _typeSubstitution;
 
-  /// The original function node.
-  final FunctionNode _original;
+  /// The original constructor or procedure.
+  final Member original;
 
-  /// The synthesized function node.
-  final FunctionNode _synthesized;
+  /// The synthesized constructor or procedure.
+  final Member synthesized;
 
   /// If `true`, the [_synthesized] is guaranteed to have the same parameters in
   /// the same order as [_original]. Otherwise [_original] is only guaranteed to
@@ -49,8 +49,12 @@
 
   CloneVisitorNotMembers? _cloner;
 
+  /// Set to `true` we default values have been cloned, ensuring that cloning
+  /// isn't performed twice.
+  bool _hasCloned = false;
+
   DelayedDefaultValueCloner(
-      this._typeSubstitution, this._original, this._synthesized,
+      this.original, this.synthesized, this._typeSubstitution,
       {this.identicalSignatures: true,
       List<int?>? positionalSuperParameters: null,
       List<String>? namedSuperParameters: null,
@@ -88,10 +92,12 @@
               // same order as the named parameters of [_synthesized].
               int superParameterIndex = 0;
               for (int namedParameterIndex = 0;
-                  namedParameterIndex < _synthesized.namedParameters.length &&
+                  namedParameterIndex <
+                          synthesized.function!.namedParameters.length &&
                       superParameterIndex < namedSuperParameters.length;
                   namedParameterIndex++) {
-                if (_synthesized.namedParameters[namedParameterIndex].name ==
+                if (synthesized
+                        .function!.namedParameters[namedParameterIndex].name ==
                     namedSuperParameters[superParameterIndex]) {
                   ++superParameterIndex;
                 }
@@ -100,6 +106,8 @@
             }());
 
   void cloneDefaultValues(TypeEnvironment typeEnvironment) {
+    if (_hasCloned) return;
+
     // TODO(ahe): It is unclear if it is legal to use type variables in
     // default values, but Fasta is currently allowing it, and the VM
     // accepts it. If it isn't legal, the we can speed this up by using a
@@ -110,6 +118,9 @@
     // can be less than that of the redirection target or, in errors cases, be
     // unrelated.
 
+    FunctionNode _original = original.function!;
+    FunctionNode _synthesized = synthesized.function!;
+
     if (identicalSignatures) {
       assert(_positionalSuperParameters != null ||
           _synthesized.positionalParameters.length ==
@@ -199,6 +210,7 @@
         }
       }
     }
+    _hasCloned = true;
   }
 
   void _cloneInitializer(VariableDeclaration originalParameter,
@@ -215,10 +227,9 @@
       VariableDeclaration originalParameter,
       VariableDeclaration synthesizedParameter,
       TypeEnvironment typeEnvironment) {
-    Member member = _synthesized.parent as Member;
     Expression? originalParameterInitializer = originalParameter.initializer;
     DartType? originalParameterInitializerType = originalParameterInitializer
-        ?.getStaticType(new StaticTypeContext(member, typeEnvironment));
+        ?.getStaticType(new StaticTypeContext(synthesized, typeEnvironment));
     DartType synthesizedParameterType = synthesizedParameter.type;
     if (originalParameterInitializerType != null &&
         typeEnvironment.isSubtypeOf(originalParameterInitializerType,
@@ -241,8 +252,8 @@
 
   @override
   String toString() {
-    return "DelayedDefaultValueCloner(original=${_original.parent}, "
-        "synthesized=${_synthesized.parent})";
+    return "DelayedDefaultValueCloner(original=${original}, "
+        "synthesized=${synthesized})";
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 0e6687b..c8f0d25 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -139,8 +139,7 @@
   final bool errorOnUnevaluatedConstant =
       CompilerContext.current.options.errorOnUnevaluatedConstant;
 
-  final List<DelayedDefaultValueCloner> _delayedDefaultValueCloners =
-      <DelayedDefaultValueCloner>[];
+  final Map<Member, DelayedDefaultValueCloner> _delayedDefaultValueCloners = {};
 
   final UriTranslator uriTranslator;
 
@@ -544,8 +543,11 @@
       loader.checkMixins(sourceClassBuilders);
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_buildOutlineExpressions);
+      // TODO(johnniwinther): Add an interface for registering delayed actions.
+      List<DelayedDefaultValueCloner> delayedDefaultValueCloners = [];
       loader.buildOutlineExpressions(
-          loader.hierarchy, _delayedDefaultValueCloners);
+          loader.hierarchy, delayedDefaultValueCloners);
+      delayedDefaultValueCloners.forEach(registerDelayedDefaultValueCloner);
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_checkTypes);
       loader.checkTypes();
@@ -1048,19 +1050,6 @@
         returnType: makeConstructorReturnType(cls));
     SuperInitializer initializer = new SuperInitializer(
         superConstructor, new Arguments(positional, named: named));
-    DelayedDefaultValueCloner delayedDefaultValueCloner =
-        new DelayedDefaultValueCloner(
-            substitutionMap, superConstructor.function, function,
-            libraryBuilder: classBuilder.libraryBuilder);
-    if (!isConst) {
-      // For constant constructors default values are computed and cloned part
-      // of the outline expression and therefore passed to the
-      // [SyntheticConstructorBuilder] below.
-      //
-      // For non-constant constructors default values are cloned as part of the
-      // full compilation using [_delayedDefaultValueCloners].
-      _delayedDefaultValueCloners.add(delayedDefaultValueCloner);
-    }
     Constructor constructor = new Constructor(function,
         name: superConstructor.name,
         initializers: <Initializer>[initializer],
@@ -1073,6 +1062,19 @@
       //..fileOffset = cls.fileOffset
       //..fileEndOffset = cls.fileOffset
       ..isNonNullableByDefault = cls.enclosingLibrary.isNonNullableByDefault;
+    DelayedDefaultValueCloner delayedDefaultValueCloner =
+        new DelayedDefaultValueCloner(
+            superConstructor, constructor, substitutionMap,
+            libraryBuilder: classBuilder.libraryBuilder);
+    if (!isConst) {
+      // For constant constructors default values are computed and cloned part
+      // of the outline expression and therefore passed to the
+      // [SyntheticConstructorBuilder] below.
+      //
+      // For non-constant constructors default values are cloned as part of the
+      // full compilation using [_delayedDefaultValueCloners].
+      registerDelayedDefaultValueCloner(delayedDefaultValueCloner);
+    }
 
     TypeDependency? typeDependency;
     if (hasTypeDependency) {
@@ -1109,11 +1111,30 @@
     return constructorBuilder;
   }
 
+  void registerDelayedDefaultValueCloner(DelayedDefaultValueCloner cloner) {
+    // TODO(johnniwinther): Avoid re-registration of cloners.
+    assert(
+        !_delayedDefaultValueCloners.containsKey(cloner.synthesized) ||
+            _delayedDefaultValueCloners[cloner.synthesized] == cloner,
+        "Default cloner already registered for ${cloner.synthesized}.");
+    _delayedDefaultValueCloners[cloner.synthesized] = cloner;
+  }
+
   void finishSynthesizedParameters({bool forOutline = false}) {
+    void cloneDefaultValues(
+        DelayedDefaultValueCloner delayedDefaultValueCloner) {
+      DelayedDefaultValueCloner? originalCloner =
+          _delayedDefaultValueCloners[delayedDefaultValueCloner.original];
+      if (originalCloner != null) {
+        cloneDefaultValues(originalCloner);
+      }
+      delayedDefaultValueCloner.cloneDefaultValues(loader.typeEnvironment);
+    }
+
     for (DelayedDefaultValueCloner delayedDefaultValueCloner
-        in _delayedDefaultValueCloners) {
+        in _delayedDefaultValueCloners.values) {
       if (!forOutline || delayedDefaultValueCloner.isOutlineNode) {
-        delayedDefaultValueCloner.cloneDefaultValues(loader.typeEnvironment);
+        cloneDefaultValues(delayedDefaultValueCloner);
       }
     }
     if (!forOutline) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 7f77622..3aa7702 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -426,7 +426,7 @@
 
     if (positionalSuperParameters != null || namedSuperParameters != null) {
       delayedDefaultValueCloners.add(new DelayedDefaultValueCloner(
-          substitution, superTarget.function, constructor.function,
+          superTarget, constructor, substitution,
           positionalSuperParameters: positionalSuperParameters ?? const <int>[],
           namedSuperParameters: namedSuperParameters ?? const <String>[],
           isOutlineNode: true,
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index b7ab94d..cef67f3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -503,7 +503,7 @@
                 (int index) => const DynamicType()));
       }
       delayedDefaultValueCloners.add(new DelayedDefaultValueCloner(
-          substitutionMap, target!.function!, function,
+          target!, _procedure, substitutionMap,
           libraryBuilder: libraryBuilder, identicalSignatures: false));
     }
     if (isConst && isPatch) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index f6fd8b7..720a1b4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -251,10 +251,10 @@
     _tearOffDependencies?.forEach((Procedure tearOff, Member target) {
       InterfaceType targetType = typedef.type as InterfaceType;
       delayedDefaultValueCloners.add(new DelayedDefaultValueCloner(
+          target,
+          tearOff,
           new Map<TypeParameter, DartType>.fromIterables(
               target.enclosingClass!.typeParameters, targetType.typeArguments),
-          target.function!,
-          tearOff.function,
           libraryBuilder: libraryBuilder));
     });
   }
diff --git a/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.expect b/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.expect
index 05ade25..bbbaeed 100644
--- a/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.expect
+++ b/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.expect
@@ -19,7 +19,7 @@
     ;
 }
 abstract class _C&B&Mixin = self::B<self::A> with self::Mixin /*isAnonymousMixin*/  {
-  synthetic constructor •({self::A field = #C1}) → self::_C&B&Mixin
+  synthetic constructor •({self::A field}) → self::_C&B&Mixin
     : super self::B::•(field: field)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.transformed.expect
index f71d862..1acdeb6 100644
--- a/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/issue48708.dart.strong.transformed.expect
@@ -19,7 +19,7 @@
     ;
 }
 abstract class _C&B&Mixin extends self::B<self::A> implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
-  synthetic constructor •({self::A field = #C1}) → self::_C&B&Mixin
+  synthetic constructor •({self::A field}) → self::_C&B&Mixin
     : super self::B::•(field: field)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.expect b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.expect
index 05ade25..bbbaeed 100644
--- a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.expect
+++ b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.expect
@@ -19,7 +19,7 @@
     ;
 }
 abstract class _C&B&Mixin = self::B<self::A> with self::Mixin /*isAnonymousMixin*/  {
-  synthetic constructor •({self::A field = #C1}) → self::_C&B&Mixin
+  synthetic constructor •({self::A field}) → self::_C&B&Mixin
     : super self::B::•(field: field)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.modular.expect
index 05ade25..bbbaeed 100644
--- a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.modular.expect
@@ -19,7 +19,7 @@
     ;
 }
 abstract class _C&B&Mixin = self::B<self::A> with self::Mixin /*isAnonymousMixin*/  {
-  synthetic constructor •({self::A field = #C1}) → self::_C&B&Mixin
+  synthetic constructor •({self::A field}) → self::_C&B&Mixin
     : super self::B::•(field: field)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.transformed.expect
index f71d862..1acdeb6 100644
--- a/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/issue48708.dart.weak.transformed.expect
@@ -19,7 +19,7 @@
     ;
 }
 abstract class _C&B&Mixin extends self::B<self::A> implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
-  synthetic constructor •({self::A field = #C1}) → self::_C&B&Mixin
+  synthetic constructor •({self::A field}) → self::_C&B&Mixin
     : super self::B::•(field: field)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart b/pkg/front_end/testcases/super_parameters/issue48769.dart
new file mode 100644
index 0000000..8ebe2e2
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart
@@ -0,0 +1,31 @@
+class NumProperty extends DiagnosticsProperty {
+  NumProperty({
+    super.showName,
+  });
+
+  NumProperty.lazy({
+    super.showName,
+  }) : super.lazy();
+}
+
+class DiagnosticsProperty extends DiagnosticsNode {
+  DiagnosticsProperty({
+    super.showName,
+  });
+
+  DiagnosticsProperty.lazy({
+    super.showName,
+  });
+}
+
+abstract class DiagnosticsNode {
+  DiagnosticsNode({
+    this.showName = true,
+  });
+
+  final bool showName;
+}
+
+void main() {
+  print('hello');
+}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.expect
new file mode 100644
index 0000000..f151327
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::lazy(showName: showName)
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsNode
+    : self::DiagnosticsNode::showName = showName, super core::Object::•()
+    ;
+}
+static method main() → void {
+  core::print("hello");
+}
+
+constants  {
+  #C1 = true
+}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.transformed.expect
new file mode 100644
index 0000000..f151327
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::lazy(showName: showName)
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsNode
+    : self::DiagnosticsNode::showName = showName, super core::Object::•()
+    ;
+}
+static method main() → void {
+  core::print("hello");
+}
+
+constants  {
+  #C1 = true
+}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline.expect
new file mode 100644
index 0000000..3392cd2
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class NumProperty extends DiagnosticsProperty {
+  NumProperty({
+    super.showName,
+  });
+  NumProperty.lazy({
+    super.showName,
+  }) : super.lazy();
+}
+
+class DiagnosticsProperty extends DiagnosticsNode {
+  DiagnosticsProperty({
+    super.showName,
+  });
+  DiagnosticsProperty.lazy({
+    super.showName,
+  });
+}
+
+abstract class DiagnosticsNode {
+  DiagnosticsNode({
+    this.showName = true,
+  });
+  final bool showName;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b4d826
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+abstract class DiagnosticsNode {
+  DiagnosticsNode({
+    this.showName = true,
+  });
+  final bool showName;
+}
+
+class DiagnosticsProperty extends DiagnosticsNode {
+  DiagnosticsProperty({
+    super.showName,
+  });
+  DiagnosticsProperty.lazy({
+    super.showName,
+  });
+}
+
+class NumProperty extends DiagnosticsProperty {
+  NumProperty({
+    super.showName,
+  });
+  NumProperty.lazy({
+    super.showName,
+  }) : super.lazy();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.expect
new file mode 100644
index 0000000..f151327
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::lazy(showName: showName)
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsNode
+    : self::DiagnosticsNode::showName = showName, super core::Object::•()
+    ;
+}
+static method main() → void {
+  core::print("hello");
+}
+
+constants  {
+  #C1 = true
+}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.modular.expect
new file mode 100644
index 0000000..f151327
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.modular.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::lazy(showName: showName)
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsNode
+    : self::DiagnosticsNode::showName = showName, super core::Object::•()
+    ;
+}
+static method main() → void {
+  core::print("hello");
+}
+
+constants  {
+  #C1 = true
+}
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.outline.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.outline.expect
new file mode 100644
index 0000000..f8249a7
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = true}) → self::NumProperty
+    ;
+  constructor lazy({core::bool showName = true}) → self::NumProperty
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = true}) → self::DiagnosticsProperty
+    ;
+  constructor lazy({core::bool showName = true}) → self::DiagnosticsProperty
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = true}) → self::DiagnosticsNode
+    ;
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.transformed.expect
new file mode 100644
index 0000000..f151327
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/issue48769.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class NumProperty extends self::DiagnosticsProperty {
+  constructor •({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::NumProperty
+    : super self::DiagnosticsProperty::lazy(showName: showName)
+    ;
+}
+class DiagnosticsProperty extends self::DiagnosticsNode {
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+  constructor lazy({core::bool showName = #C1}) → self::DiagnosticsProperty
+    : super self::DiagnosticsNode::•(showName: showName)
+    ;
+}
+abstract class DiagnosticsNode extends core::Object {
+  final field core::bool showName;
+  constructor •({core::bool showName = #C1}) → self::DiagnosticsNode
+    : self::DiagnosticsNode::showName = showName, super core::Object::•()
+    ;
+}
+static method main() → void {
+  core::print("hello");
+}
+
+constants  {
+  #C1 = true
+}
diff --git a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.expect b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.expect
index 1d3e740..c1a5b49 100644
--- a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.expect
+++ b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.expect
@@ -161,7 +161,7 @@
     ;
 }
 class C9 = syn::A9 with self::B9 {
-  synthetic constructor •([core::int? a = #C3]) → self::C9
+  synthetic constructor •([core::int? a]) → self::C9
     : super syn::A9::•(a)
     ;
 }
@@ -210,7 +210,7 @@
     ;
 }
 class C8 = syn::A8 with syn::B8 {
-  synthetic constructor •({core::int? a = #C3}) → syn::C8
+  synthetic constructor •({core::int? a}) → syn::C8
     : super syn::A8::•(a: a)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.transformed.expect
index 8995764..782b4ee 100644
--- a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.strong.transformed.expect
@@ -161,7 +161,7 @@
     ;
 }
 class C9 extends syn::A9 implements self::B9 /*isEliminatedMixin*/  {
-  synthetic constructor •([core::int? a = #C3]) → self::C9
+  synthetic constructor •([core::int? a]) → self::C9
     : super syn::A9::•(a)
     ;
 }
@@ -210,7 +210,7 @@
     ;
 }
 class C8 extends syn::A8 implements syn::B8 /*isEliminatedMixin*/  {
-  synthetic constructor •({core::int? a = #C3}) → syn::C8
+  synthetic constructor •({core::int? a}) → syn::C8
     : super syn::A8::•(a: a)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.expect b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.expect
index 1d3e740..c1a5b49 100644
--- a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.expect
+++ b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.expect
@@ -161,7 +161,7 @@
     ;
 }
 class C9 = syn::A9 with self::B9 {
-  synthetic constructor •([core::int? a = #C3]) → self::C9
+  synthetic constructor •([core::int? a]) → self::C9
     : super syn::A9::•(a)
     ;
 }
@@ -210,7 +210,7 @@
     ;
 }
 class C8 = syn::A8 with syn::B8 {
-  synthetic constructor •({core::int? a = #C3}) → syn::C8
+  synthetic constructor •({core::int? a}) → syn::C8
     : super syn::A8::•(a: a)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.modular.expect
index 1d3e740..c1a5b49 100644
--- a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.modular.expect
@@ -161,7 +161,7 @@
     ;
 }
 class C9 = syn::A9 with self::B9 {
-  synthetic constructor •([core::int? a = #C3]) → self::C9
+  synthetic constructor •([core::int? a]) → self::C9
     : super syn::A9::•(a)
     ;
 }
@@ -210,7 +210,7 @@
     ;
 }
 class C8 = syn::A8 with syn::B8 {
-  synthetic constructor •({core::int? a = #C3}) → syn::C8
+  synthetic constructor •({core::int? a}) → syn::C8
     : super syn::A8::•(a: a)
     ;
 }
diff --git a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.transformed.expect
index 8995764..782b4ee 100644
--- a/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/synthesized_super_constructor_with_parameters.dart.weak.transformed.expect
@@ -161,7 +161,7 @@
     ;
 }
 class C9 extends syn::A9 implements self::B9 /*isEliminatedMixin*/  {
-  synthetic constructor •([core::int? a = #C3]) → self::C9
+  synthetic constructor •([core::int? a]) → self::C9
     : super syn::A9::•(a)
     ;
 }
@@ -210,7 +210,7 @@
     ;
 }
 class C8 extends syn::A8 implements syn::B8 /*isEliminatedMixin*/  {
-  synthetic constructor •({core::int? a = #C3}) → syn::C8
+  synthetic constructor •({core::int? a}) → syn::C8
     : super syn::A8::•(a: a)
     ;
 }
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index 5dca72d..9af9ea6 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -64,6 +64,9 @@
   return _convert(data)!;
 }
 
+@pragma('dart2js:tryInline')
+Object get globalThis => JS('', 'globalThis');
+
 T newObject<T>() => JS('=Object', '{}');
 
 bool hasProperty(Object o, Object name) => JS('bool', '# in #', name, o);
diff --git a/tests/language/inference_update_1/horizontal_inference_invocation_types_test.dart b/tests/language/inference_update_1/horizontal_inference_invocation_types_test.dart
new file mode 100644
index 0000000..c6a1b8b
--- /dev/null
+++ b/tests/language/inference_update_1/horizontal_inference_invocation_types_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2022, 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.
+
+// Tests horizontal inference for a variety of types of invocations.
+
+// SharedOptions=--enable-experiment=inference-update-1
+
+import '../static_type_helper.dart';
+
+testFunctionExpressionInvocation() {
+  (<T>(T t, void Function(T) f) => t)(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<int>>();
+}
+
+testInstanceCreation() {
+  C(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<C<int>>>();
+}
+
+testInstanceMethodInvocation(B b) {
+  b.instanceMethod(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<int>>();
+}
+
+testStaticMethodInvocation() {
+  B.staticMethod(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<int>>();
+}
+
+testTopLevelFunctionInvocation() {
+  topLevelFunction(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<int>>();
+}
+
+testLocalFunctionInvocation() {
+  T localFunction<T>(T t, void Function(T) f) => throw '';
+  localFunction(0, (x) {
+    x.expectStaticType<Exactly<int>>();
+  }).expectStaticType<Exactly<int>>();
+}
+
+abstract class B {
+  T instanceMethod<T>(T t, void Function(T) f);
+  static T staticMethod<T>(T t, void Function(T) f) => throw '';
+}
+
+T topLevelFunction<T>(T t, void Function(T) f) => throw '';
+
+class C<T> {
+  C(T t, void Function(T) f);
+}
+
+main() {}
diff --git a/tests/lib/js/js_util/properties_test.dart b/tests/lib/js/js_util/properties_test.dart
index 84a09c8..5f718a6 100644
--- a/tests/lib/js/js_util/properties_test.dart
+++ b/tests/lib/js/js_util/properties_test.dart
@@ -189,8 +189,21 @@
     function Five(a, b, c, d, e) {
       this.count = 5;
     }
+
+    globalThis.globalKey = 'foo';
     """);
 
+  group('globalThis', () {
+    test('create', () {
+      expect(identical(js_util.globalThis, js_util.globalThis), isTrue);
+    });
+
+    test('isGlobalThis', () {
+      expect(js_util.hasProperty(js_util.globalThis, 'One'), isTrue);
+      expect(js_util.getProperty(js_util.globalThis, 'globalKey'), 'foo');
+    });
+  });
+
   group('newObject', () {
     test('create', () {
       expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
diff --git a/tests/lib_2/js/js_util/properties_test.dart b/tests/lib_2/js/js_util/properties_test.dart
index c19fe14..2b0af10 100644
--- a/tests/lib_2/js/js_util/properties_test.dart
+++ b/tests/lib_2/js/js_util/properties_test.dart
@@ -191,8 +191,21 @@
     function Five(a, b, c, d, e) {
       this.count = 5;
     }
+
+    globalThis.globalKey = 'foo';
     """);
 
+  group('globalThis', () {
+    test('create', () {
+      expect(identical(js_util.globalThis, js_util.globalThis), isTrue);
+    });
+
+    test('isGlobalThis', () {
+      expect(js_util.hasProperty(js_util.globalThis, 'One'), isTrue);
+      expect(js_util.getProperty(js_util.globalThis, 'globalKey'), 'foo');
+    });
+  });
+
   group('newObject', () {
     test('create', () {
       expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
diff --git a/tests/web/wasm/static_interop_test.dart b/tests/web/wasm/static_interop_test.dart
index 3df1c84..c1be1eb 100644
--- a/tests/web/wasm/static_interop_test.dart
+++ b/tests/web/wasm/static_interop_test.dart
@@ -104,8 +104,43 @@
   Expect.equals(traveler, holder.foo);
 }
 
+@JS()
+external String get foo;
+
+@JS('')
+external void set baz(String);
+
+@JS('boo.bar')
+external String get bam;
+
+@JS('bar')
+external String fooBar(String);
+
+void topLevelMethodsTest() {
+  eval(r'''
+    globalThis.foo = 'bar';
+    globalThis.baz = null;
+    globalThis.boo = {
+      'bar': {
+        'bam': 'jam'
+      }
+    }
+    globalThis.bar = {
+      'fooBar': function(string) {
+        return string + ' ' + globalThis.baz;
+      }
+    }
+  ''');
+
+  Expect.equals(foo, 'bar');
+  Expect.equals(bam, 'jam');
+  baz = 'world!';
+  Expect.equals(fooBar('hello'), 'hello world!');
+}
+
 void main() {
   createClassTest();
   setInteropPropertyTest();
   setDartObjectPropertyTest();
+  topLevelMethodsTest();
 }
diff --git a/tools/VERSION b/tools/VERSION
index 3a75f2e..822343f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 16
+PRERELEASE 17
 PRERELEASE_PATCH 0
\ No newline at end of file