Version 2.18.0-39.0.dev

Merge commit 'f26c0e205654e1a97d1a7fc0b048b2100088bebf' into 'dev'
diff --git a/compile_output.txt b/compile_output.txt
deleted file mode 100644
index c3420dd..0000000
--- a/compile_output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Info: The --categories flag is deprecated, see the usage for details.
-Info: Compiling with sound null safety
-Error: Error when reading 'benchmarks-internal/DeltaBlueBase/dart2/deltablue.dart': Error reading 'benchmarks-internal/DeltaBlueBase/dart2/deltablue.dart'  (No such file or directory)
-Error: No 'main' method found.
-Error: Compilation failed.
-real 1.14
-user 0.59
-sys 0.84
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index 4a20a40..57b3a31 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -179,7 +179,7 @@
           StringLiteral(_getExtensionMemberName(node)),
           ListLiteral(function.positionalParameters
               .sublist(1)
-              .map((argument) => VariableGet(argument))
+              .map<Expression>((argument) => VariableGet(argument))
               .toList())
         ], types: [
           function.returnType
@@ -294,8 +294,8 @@
     }
 
     // Lower arguments in other kinds of Lists.
-    var callUncheckedArguments;
-    var entryType;
+    List<Expression> callUncheckedArguments;
+    DartType entryType;
     if (argumentsList is ListLiteral) {
       if (argumentsList.expressions.length >= callUncheckedTargets.length) {
         return node;
@@ -309,7 +309,7 @@
         return node;
       }
       callUncheckedArguments = argumentsListConstant.entries
-          .map((constant) => ConstantExpression(
+          .map<Expression>((constant) => ConstantExpression(
               constant, constant.getType(_staticTypeContext)))
           .toList();
       entryType = argumentsListConstant.typeArgument;
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 8f6c48b..8c638be 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -6,30 +6,15 @@
 
 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/domain_abstract.dart';
-import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/handler/legacy/completion_get_suggestion_details.dart';
 import 'package:analysis_server/src/handler/legacy/completion_get_suggestion_details2.dart';
-import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions2.dart';
+import 'package:analysis_server/src/handler/legacy/completion_set_subscriptions.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/util/file_paths.dart' as file_paths;
-import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer/src/utilities/cancellation.dart';
-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:collection/collection.dart';
 
 /// Instances of the class [CompletionDomainHandler] implement a
 /// [RequestHandler] that handles requests in the completion domain.
@@ -37,223 +22,6 @@
   /// Initialize a new request handler for the given [server].
   CompletionDomainHandler(super.server);
 
-  /// Compute completion results for the given request and append them to the
-  /// stream. Clients should not call this method directly as it is
-  /// automatically called when a client listens to the stream returned by
-  /// [results]. Subclasses should override this method, append at least one
-  /// result to the [controller], and close the controller stream once complete.
-  Future<List<CompletionSuggestionBuilder>> computeSuggestions({
-    required CompletionBudget budget,
-    required OperationPerformanceImpl performance,
-    required DartCompletionRequest request,
-    Set<ElementKind>? includedElementKinds,
-    Set<String>? includedElementNames,
-    List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
-    NotImportedSuggestions? notImportedSuggestions,
-  }) async {
-    //
-    // Allow plugins to start computing fixes.
-    //
-    var requestToPlugins = performance.run('askPlugins', (_) {
-      return _sendRequestToPlugins(request);
-    });
-
-    //
-    // Compute completions generated by server.
-    //
-    var suggestions = <CompletionSuggestionBuilder>[];
-    await performance.runAsync('computeSuggestions', (performance) async {
-      var manager = DartCompletionManager(
-        budget: budget,
-        includedElementKinds: includedElementKinds,
-        includedElementNames: includedElementNames,
-        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-        notImportedSuggestions: notImportedSuggestions,
-      );
-
-      suggestions.addAll(
-        await manager.computeSuggestions(request, performance),
-      );
-    });
-    // TODO (danrubel) if request is obsolete (processAnalysisRequest returns
-    // false) then send empty results
-
-    //
-    // Add the completions produced by plugins to the server-generated list.
-    //
-    if (requestToPlugins != null) {
-      await performance.runAsync('waitForPlugins', (_) async {
-        await _addPluginSuggestions(budget, requestToPlugins, suggestions);
-      });
-    }
-
-    return suggestions;
-  }
-
-  /// Return the suggestions that should be presented in the YAML [file] at the
-  /// given [offset].
-  YamlCompletionResults computeYamlSuggestions(String file, int offset) {
-    var provider = server.resourceProvider;
-    var pathContext = provider.pathContext;
-    if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
-      var generator = AnalysisOptionsGenerator(provider);
-      return generator.getSuggestions(file, offset);
-    } else if (file_paths.isFixDataYaml(pathContext, file)) {
-      var generator = FixDataGenerator(provider);
-      return generator.getSuggestions(file, offset);
-    } else if (file_paths.isPubspecYaml(pathContext, file)) {
-      var generator = PubspecGenerator(provider, server.pubPackageService);
-      return generator.getSuggestions(file, offset);
-    }
-    return const YamlCompletionResults.empty();
-  }
-
-  /// Implement the 'completion.getSuggestions2' request.
-  void getSuggestions2(Request request) async {
-    var params = CompletionGetSuggestions2Params.fromRequest(request);
-    var file = params.file;
-    var offset = params.offset;
-
-    var timeoutMilliseconds = params.timeout;
-    var budget = CompletionBudget(
-      timeoutMilliseconds != null
-          ? Duration(milliseconds: timeoutMilliseconds)
-          : server.completionState.budgetDuration,
-    );
-
-    var provider = server.resourceProvider;
-    var pathContext = provider.pathContext;
-
-    if (file.endsWith('.yaml')) {
-      final suggestions = computeYamlSuggestions(file, offset);
-      server.sendResponse(
-        CompletionGetSuggestions2Result(
-          suggestions.replacementOffset,
-          suggestions.replacementLength,
-          suggestions.suggestions,
-          false,
-        ).toResponse(request.id),
-      );
-      return;
-    }
-
-    if (!file_paths.isDart(pathContext, file)) {
-      server.sendResponse(
-        CompletionGetSuggestions2Result(offset, 0, [], false)
-            .toResponse(request.id),
-      );
-      return;
-    }
-
-    var performance = OperationPerformanceImpl('<root>');
-    performance.runAsync(
-      'request',
-      (performance) async {
-        var resolvedUnit = await performance.runAsync(
-          'resolveForCompletion',
-          (performance) {
-            return server.resolveForCompletion(
-              path: file,
-              offset: offset,
-              performance: performance,
-            );
-          },
-        );
-        if (resolvedUnit == null) {
-          server.sendResponse(Response.fileNotAnalyzed(request, file));
-          return;
-        }
-
-        if (offset < 0 || offset > resolvedUnit.content.length) {
-          server.sendResponse(Response.invalidParameter(
-              request,
-              'params.offset',
-              'Expected offset between 0 and source length inclusive,'
-                  ' but found $offset'));
-          return;
-        }
-
-        final completionPerformance = CompletionPerformance(
-          operation: performance,
-          path: file,
-          content: resolvedUnit.content,
-          offset: offset,
-        );
-        server.completionState.performanceList.add(completionPerformance);
-
-        var analysisSession = resolvedUnit.analysisSession;
-        var enclosingNode =
-            resolvedUnit.resolvedNodes.lastOrNull ?? resolvedUnit.parsedUnit;
-
-        var completionRequest = DartCompletionRequest(
-          analysisSession: analysisSession,
-          filePath: resolvedUnit.path,
-          fileContent: resolvedUnit.content,
-          unitElement: resolvedUnit.unitElement,
-          enclosingNode: enclosingNode,
-          offset: offset,
-          dartdocDirectiveInfo:
-              server.getDartdocDirectiveInfoForSession(analysisSession),
-          documentationCache:
-              server.getDocumentationCacheForSession(analysisSession),
-        );
-        setNewRequest(completionRequest);
-
-        var notImportedSuggestions = NotImportedSuggestions();
-        var suggestionBuilders = <CompletionSuggestionBuilder>[];
-        try {
-          suggestionBuilders = await computeSuggestions(
-            budget: budget,
-            performance: performance,
-            request: completionRequest,
-            notImportedSuggestions: notImportedSuggestions,
-          );
-        } on AbortCompletion {
-          return server.sendResponse(
-            CompletionGetSuggestions2Result(
-              completionRequest.replacementOffset,
-              completionRequest.replacementLength,
-              [],
-              true,
-            ).toResponse(request.id),
-          );
-        }
-
-        performance.run('filter', (performance) {
-          performance.getDataInt('count').add(suggestionBuilders.length);
-          suggestionBuilders = fuzzyFilterSort(
-            pattern: completionRequest.targetPrefix,
-            suggestions: suggestionBuilders,
-          );
-          performance.getDataInt('matchCount').add(suggestionBuilders.length);
-        });
-
-        var lengthRestricted =
-            suggestionBuilders.take(params.maxResults).toList();
-        completionPerformance.computedSuggestionCount =
-            suggestionBuilders.length;
-        completionPerformance.transmittedSuggestionCount =
-            lengthRestricted.length;
-
-        var suggestions = lengthRestricted.map((e) => e.build()).toList();
-
-        var isIncomplete = notImportedSuggestions.isIncomplete ||
-            lengthRestricted.length < suggestionBuilders.length;
-
-        performance.run('sendResponse', (_) {
-          server.sendResponse(
-            CompletionGetSuggestions2Result(
-              completionRequest.replacementOffset,
-              completionRequest.replacementLength,
-              suggestions,
-              isIncomplete,
-            ).toResponse(request.id),
-          );
-        });
-      },
-    );
-  }
-
   @override
   Response? handleRequest(
       Request request, CancellationToken cancellationToken) {
@@ -279,13 +47,17 @@
             .handle();
         return Response.DELAYED_RESPONSE;
       } else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
-        processRequest(request);
+        CompletionGetSuggestionsHandler(server, request, cancellationToken)
+            .handle();
         return Response.DELAYED_RESPONSE;
       } else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS2) {
-        getSuggestions2(request);
+        CompletionGetSuggestions2Handler(server, request, cancellationToken)
+            .handle();
         return Response.DELAYED_RESPONSE;
       } else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
-        return setSubscriptions(request);
+        CompletionSetSubscriptionsHandler(server, request, cancellationToken)
+            .handle();
+        return Response.DELAYED_RESPONSE;
       }
       return null;
     }, (exception, stackTrace) {
@@ -296,330 +68,4 @@
               stackTrace));
     });
   }
-
-  void ifMatchesRequestClear(DartCompletionRequest request) {
-    if (server.completionState.currentRequest == request) {
-      server.completionState.currentRequest = null;
-    }
-  }
-
-  /// Process a `completion.getSuggestions` request.
-  Future<void> processRequest(Request request) async {
-    var budget = CompletionBudget(server.completionState.budgetDuration);
-
-    // extract and validate params
-    var params = CompletionGetSuggestionsParams.fromRequest(request);
-    var file = params.file;
-    var offset = params.offset;
-
-    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
-      return;
-    }
-
-    var performance = OperationPerformanceImpl('<root>');
-    performance.runAsync(
-      'request',
-      (performance) async {
-        if (file.endsWith('.yaml')) {
-          // Return the response without results.
-          var completionId =
-              (server.completionState.nextCompletionId++).toString();
-          server.sendResponse(CompletionGetSuggestionsResult(completionId)
-              .toResponse(request.id));
-          // Send a notification with results.
-          final suggestions = computeYamlSuggestions(file, offset);
-          sendCompletionNotification(
-            completionId,
-            suggestions.replacementOffset,
-            suggestions.replacementLength,
-            suggestions.suggestions,
-            null,
-            null,
-            null,
-            null,
-          );
-          return;
-        } else if (!file.endsWith('.dart')) {
-          // Return the response without results.
-          var completionId =
-              (server.completionState.nextCompletionId++).toString();
-          server.sendResponse(CompletionGetSuggestionsResult(completionId)
-              .toResponse(request.id));
-          // Send a notification with results.
-          sendCompletionNotification(
-              completionId, offset, 0, [], null, null, null, null);
-          return;
-        }
-
-        var resolvedUnit = await server.getResolvedUnit(file);
-        if (resolvedUnit == null) {
-          server.sendResponse(Response.fileNotAnalyzed(request, file));
-          return;
-        }
-
-        server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
-
-        if (offset < 0 || offset > resolvedUnit.content.length) {
-          server.sendResponse(Response.invalidParameter(
-              request,
-              'params.offset',
-              'Expected offset between 0 and source length inclusive,'
-                  ' but found $offset'));
-          return;
-        }
-
-        final completionPerformance = CompletionPerformance(
-          operation: performance,
-          path: file,
-          content: resolvedUnit.content,
-          offset: offset,
-        );
-        server.completionState.performanceList.add(completionPerformance);
-
-        var declarationsTracker = server.declarationsTracker;
-        if (declarationsTracker == null) {
-          server.sendResponse(Response.unsupportedFeature(
-              request.id, 'Completion is not enabled.'));
-          return;
-        }
-
-        var completionRequest = DartCompletionRequest.forResolvedUnit(
-          resolvedUnit: resolvedUnit,
-          offset: offset,
-          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
-            resolvedUnit,
-          ),
-          documentationCache: server.getDocumentationCacheFor(resolvedUnit),
-        );
-
-        var completionId =
-            (server.completionState.nextCompletionId++).toString();
-
-        setNewRequest(completionRequest);
-
-        // initial response without results
-        server.sendResponse(CompletionGetSuggestionsResult(completionId)
-            .toResponse(request.id));
-
-        // If the client opted into using available suggestion sets,
-        // create the kinds set, so signal the completion manager about opt-in.
-        Set<ElementKind>? includedElementKinds;
-        Set<String>? includedElementNames;
-        List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
-        if (server.completionState.subscriptions
-            .contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
-          includedElementKinds = <ElementKind>{};
-          includedElementNames = <String>{};
-          includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
-        }
-
-        // Compute suggestions in the background
-        try {
-          var suggestionBuilders = <CompletionSuggestionBuilder>[];
-          try {
-            suggestionBuilders = await computeSuggestions(
-              budget: budget,
-              performance: performance,
-              request: completionRequest,
-              includedElementKinds: includedElementKinds,
-              includedElementNames: includedElementNames,
-              includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-            );
-          } on AbortCompletion {
-            // Continue with empty suggestions list.
-          }
-          String? libraryFile;
-          var includedSuggestionSets = <IncludedSuggestionSet>[];
-          if (includedElementKinds != null && includedElementNames != null) {
-            libraryFile = resolvedUnit.libraryElement.source.fullName;
-            server.sendNotification(
-              createExistingImportsNotification(resolvedUnit),
-            );
-            computeIncludedSetList(
-              declarationsTracker,
-              completionRequest,
-              includedSuggestionSets,
-              includedElementNames,
-            );
-          }
-
-          const SEND_NOTIFICATION_TAG = 'send notification';
-          performance.run(SEND_NOTIFICATION_TAG, (_) {
-            sendCompletionNotification(
-              completionId,
-              completionRequest.replacementOffset,
-              completionRequest.replacementLength,
-              suggestionBuilders.map((e) => e.build()).toList(),
-              libraryFile,
-              includedSuggestionSets,
-              includedElementKinds?.toList(),
-              includedSuggestionRelevanceTags,
-            );
-          });
-
-          completionPerformance.computedSuggestionCount =
-              suggestionBuilders.length;
-          completionPerformance.transmittedSuggestionCount =
-              suggestionBuilders.length;
-        } finally {
-          ifMatchesRequestClear(completionRequest);
-        }
-      },
-    );
-  }
-
-  /// Send completion notification results.
-  void sendCompletionNotification(
-    String completionId,
-    int replacementOffset,
-    int replacementLength,
-    List<CompletionSuggestion> results,
-    String? libraryFile,
-    List<IncludedSuggestionSet>? includedSuggestionSets,
-    List<ElementKind>? includedElementKinds,
-    List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
-  ) {
-    server.sendNotification(
-      CompletionResultsParams(
-        completionId,
-        replacementOffset,
-        replacementLength,
-        results,
-        true,
-        libraryFile: libraryFile,
-        includedSuggestionSets: includedSuggestionSets,
-        includedElementKinds: includedElementKinds,
-        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-      ).toNotification(),
-    );
-  }
-
-  void setNewRequest(DartCompletionRequest request) {
-    _abortCurrentRequest();
-    server.completionState.currentRequest = request;
-  }
-
-  /// Implement the 'completion.setSubscriptions' request.
-  Response setSubscriptions(Request request) {
-    var params = CompletionSetSubscriptionsParams.fromRequest(request);
-
-    var subscriptions = server.completionState.subscriptions;
-    subscriptions.clear();
-    subscriptions.addAll(params.subscriptions);
-
-    var data = server.declarationsTrackerData;
-    if (data != null) {
-      if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
-        var soFarLibraries = data.startListening((change) {
-          server.sendNotification(
-            createCompletionAvailableSuggestionsNotification(
-              change.changed,
-              change.removed,
-            ),
-          );
-        });
-        server.sendNotification(
-          createCompletionAvailableSuggestionsNotification(
-            soFarLibraries,
-            [],
-          ),
-        );
-      } else {
-        data.stopListening();
-      }
-    }
-    return CompletionSetSubscriptionsResult().toResponse(request.id);
-  }
-
-  /// Abort the current completion request, if any.
-  void _abortCurrentRequest() {
-    var currentRequest = server.completionState.currentRequest;
-    if (currentRequest != null) {
-      currentRequest.abort();
-      server.completionState.currentRequest = null;
-    }
-  }
-
-  /// Add the completions produced by plugins to the server-generated list.
-  Future<void> _addPluginSuggestions(
-    CompletionBudget budget,
-    _RequestToPlugins requestToPlugins,
-    List<CompletionSuggestionBuilder> suggestionBuilders,
-  ) async {
-    var responses = await waitForResponses(
-      requestToPlugins.futures,
-      requestParameters: requestToPlugins.parameters,
-      timeout: budget.left,
-    );
-    for (var response in responses) {
-      var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
-      if (result.results.isNotEmpty) {
-        var completionRequest = requestToPlugins.completionRequest;
-        if (completionRequest.replacementOffset != result.replacementOffset &&
-            completionRequest.replacementLength != result.replacementLength) {
-          server.instrumentationService
-              .logError('Plugin completion-results dropped due to conflicting'
-                  ' replacement offset/length: ${result.toJson()}');
-          continue;
-        }
-        suggestionBuilders.addAll(
-          result.results.map(
-            (suggestion) => ValueCompletionSuggestionBuilder(suggestion),
-          ),
-        );
-      }
-    }
-  }
-
-  /// Send the completion request to plugins, so that they work in other
-  /// isolates in parallel with the server isolate.
-  _RequestToPlugins? _sendRequestToPlugins(
-    DartCompletionRequest completionRequest,
-  ) {
-    var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
-      completionRequest.path,
-      completionRequest.offset,
-    );
-
-    return _RequestToPlugins(
-      completionRequest: completionRequest,
-      parameters: pluginRequestParameters,
-      futures: server.pluginManager.broadcastRequest(
-        pluginRequestParameters,
-        contextRoot: completionRequest.analysisContext.contextRoot,
-      ),
-    );
-  }
-}
-
-/// The result of computing suggestions for code completion.
-class CompletionResult {
-  /// The length of the text to be replaced if the remainder of the identifier
-  /// containing the cursor is to be replaced when the suggestion is applied
-  /// (that is, the number of characters in the existing identifier).
-  final int replacementLength;
-
-  /// The offset of the start of the text to be replaced. This will be different
-  /// than the offset used to request the completion suggestions if there was a
-  /// portion of an identifier before the original offset. In particular, the
-  /// replacementOffset will be the offset of the beginning of said identifier.
-  final int replacementOffset;
-
-  /// The suggested completions.
-  final List<CompletionSuggestion> suggestions;
-
-  CompletionResult(
-      this.replacementOffset, this.replacementLength, this.suggestions);
-}
-
-class _RequestToPlugins {
-  final DartCompletionRequest completionRequest;
-  final plugin.CompletionGetSuggestionsParams parameters;
-  final Map<PluginInfo, Future<plugin.Response>> futures;
-
-  _RequestToPlugins({
-    required this.completionRequest,
-    required this.parameters,
-    required this.futures,
-  });
 }
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart
new file mode 100644
index 0000000..459c089
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart
@@ -0,0 +1,195 @@
+// 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.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions2.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+/// The handler for the `completion.getSuggestions` request.
+class CompletionGetSuggestionsHandler extends CompletionGetSuggestions2Handler {
+  /// Initialize a newly created handler to be able to service requests for the
+  /// [server].
+  CompletionGetSuggestionsHandler(
+      super.server, super.request, super.cancellationToken);
+
+  @override
+  Future<void> handle() async {
+    var budget = CompletionBudget(server.completionState.budgetDuration);
+
+    // extract and validate params
+    var params = CompletionGetSuggestionsParams.fromRequest(request);
+    var file = params.file;
+    var offset = params.offset;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
+    var performance = OperationPerformanceImpl('<root>');
+    performance.runAsync(
+      'request',
+      (performance) async {
+        if (file.endsWith('.yaml')) {
+          // Return the response without results.
+          var completionId =
+              (server.completionState.nextCompletionId++).toString();
+          server.sendResponse(CompletionGetSuggestionsResult(completionId)
+              .toResponse(request.id));
+          // Send a notification with results.
+          final suggestions = computeYamlSuggestions(file, offset);
+          sendCompletionNotification(
+            completionId,
+            suggestions.replacementOffset,
+            suggestions.replacementLength,
+            suggestions.suggestions,
+            null,
+            null,
+            null,
+            null,
+          );
+          return;
+        } else if (!file.endsWith('.dart')) {
+          // Return the response without results.
+          var completionId =
+              (server.completionState.nextCompletionId++).toString();
+          server.sendResponse(CompletionGetSuggestionsResult(completionId)
+              .toResponse(request.id));
+          // Send a notification with results.
+          sendCompletionNotification(
+              completionId, offset, 0, [], null, null, null, null);
+          return;
+        }
+
+        var resolvedUnit = await server.getResolvedUnit(file);
+        if (resolvedUnit == null) {
+          server.sendResponse(Response.fileNotAnalyzed(request, file));
+          return;
+        }
+
+        server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
+
+        if (offset < 0 || offset > resolvedUnit.content.length) {
+          server.sendResponse(Response.invalidParameter(
+              request,
+              'params.offset',
+              'Expected offset between 0 and source length inclusive,'
+                  ' but found $offset'));
+          return;
+        }
+
+        final completionPerformance = CompletionPerformance(
+          operation: performance,
+          path: file,
+          content: resolvedUnit.content,
+          offset: offset,
+        );
+        server.completionState.performanceList.add(completionPerformance);
+
+        var declarationsTracker = server.declarationsTracker;
+        if (declarationsTracker == null) {
+          server.sendResponse(Response.unsupportedFeature(
+              request.id, 'Completion is not enabled.'));
+          return;
+        }
+
+        var completionRequest = DartCompletionRequest.forResolvedUnit(
+          resolvedUnit: resolvedUnit,
+          offset: offset,
+          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
+            resolvedUnit,
+          ),
+          documentationCache: server.getDocumentationCacheFor(resolvedUnit),
+        );
+
+        var completionId =
+            (server.completionState.nextCompletionId++).toString();
+
+        setNewRequest(completionRequest);
+
+        // initial response without results
+        server.sendResponse(CompletionGetSuggestionsResult(completionId)
+            .toResponse(request.id));
+
+        // If the client opted into using available suggestion sets,
+        // create the kinds set, so signal the completion manager about opt-in.
+        Set<ElementKind>? includedElementKinds;
+        Set<String>? includedElementNames;
+        List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
+        if (server.completionState.subscriptions
+            .contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+          includedElementKinds = <ElementKind>{};
+          includedElementNames = <String>{};
+          includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+        }
+
+        // Compute suggestions in the background
+        try {
+          var suggestionBuilders = <CompletionSuggestionBuilder>[];
+          try {
+            suggestionBuilders = await computeSuggestions(
+              budget: budget,
+              performance: performance,
+              request: completionRequest,
+              includedElementKinds: includedElementKinds,
+              includedElementNames: includedElementNames,
+              includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+            );
+          } on AbortCompletion {
+            // Continue with empty suggestions list.
+          }
+          String? libraryFile;
+          var includedSuggestionSets = <IncludedSuggestionSet>[];
+          if (includedElementKinds != null && includedElementNames != null) {
+            libraryFile = resolvedUnit.libraryElement.source.fullName;
+            server.sendNotification(
+              createExistingImportsNotification(resolvedUnit),
+            );
+            computeIncludedSetList(
+              declarationsTracker,
+              completionRequest,
+              includedSuggestionSets,
+              includedElementNames,
+            );
+          }
+
+          const SEND_NOTIFICATION_TAG = 'send notification';
+          performance.run(SEND_NOTIFICATION_TAG, (_) {
+            sendCompletionNotification(
+              completionId,
+              completionRequest.replacementOffset,
+              completionRequest.replacementLength,
+              suggestionBuilders.map((e) => e.build()).toList(),
+              libraryFile,
+              includedSuggestionSets,
+              includedElementKinds?.toList(),
+              includedSuggestionRelevanceTags,
+            );
+          });
+
+          completionPerformance.computedSuggestionCount =
+              suggestionBuilders.length;
+          completionPerformance.transmittedSuggestionCount =
+              suggestionBuilders.length;
+        } finally {
+          _ifMatchesRequestClear(completionRequest);
+        }
+      },
+    );
+  }
+
+  void _ifMatchesRequestClear(DartCompletionRequest request) {
+    if (server.completionState.currentRequest == request) {
+      server.completionState.currentRequest = null;
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
new file mode 100644
index 0000000..1d17711
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
@@ -0,0 +1,354 @@
+// 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.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_abstract.dart';
+import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:collection/collection.dart';
+
+/// The handler for the `completion.getSuggestions2` request.
+class CompletionGetSuggestions2Handler extends LegacyHandler
+    with RequestHandlerMixin<AnalysisServer> {
+  /// Initialize a newly created handler to be able to service requests for the
+  /// [server].
+  CompletionGetSuggestions2Handler(
+      super.server, super.request, super.cancellationToken);
+
+  /// Compute completion results for the given request and append them to the
+  /// stream. Clients should not call this method directly as it is
+  /// automatically called when a client listens to the stream returned by
+  /// [results]. Subclasses should override this method, append at least one
+  /// result to the [controller], and close the controller stream once complete.
+  Future<List<CompletionSuggestionBuilder>> computeSuggestions({
+    required CompletionBudget budget,
+    required OperationPerformanceImpl performance,
+    required DartCompletionRequest request,
+    Set<ElementKind>? includedElementKinds,
+    Set<String>? includedElementNames,
+    List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
+    NotImportedSuggestions? notImportedSuggestions,
+  }) async {
+    //
+    // Allow plugins to start computing fixes.
+    //
+    var requestToPlugins = performance.run('askPlugins', (_) {
+      return _sendRequestToPlugins(request);
+    });
+
+    //
+    // Compute completions generated by server.
+    //
+    var suggestions = <CompletionSuggestionBuilder>[];
+    await performance.runAsync('computeSuggestions', (performance) async {
+      var manager = DartCompletionManager(
+        budget: budget,
+        includedElementKinds: includedElementKinds,
+        includedElementNames: includedElementNames,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+        notImportedSuggestions: notImportedSuggestions,
+      );
+
+      suggestions.addAll(
+        await manager.computeSuggestions(request, performance),
+      );
+    });
+    // TODO (danrubel) if request is obsolete (processAnalysisRequest returns
+    // false) then send empty results
+
+    //
+    // Add the completions produced by plugins to the server-generated list.
+    //
+    if (requestToPlugins != null) {
+      await performance.runAsync('waitForPlugins', (_) async {
+        await _addPluginSuggestions(budget, requestToPlugins, suggestions);
+      });
+    }
+
+    return suggestions;
+  }
+
+  /// Return the suggestions that should be presented in the YAML [file] at the
+  /// given [offset].
+  YamlCompletionResults computeYamlSuggestions(String file, int offset) {
+    var provider = server.resourceProvider;
+    var pathContext = provider.pathContext;
+    if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
+      var generator = AnalysisOptionsGenerator(provider);
+      return generator.getSuggestions(file, offset);
+    } else if (file_paths.isFixDataYaml(pathContext, file)) {
+      var generator = FixDataGenerator(provider);
+      return generator.getSuggestions(file, offset);
+    } else if (file_paths.isPubspecYaml(pathContext, file)) {
+      var generator = PubspecGenerator(provider, server.pubPackageService);
+      return generator.getSuggestions(file, offset);
+    }
+    return const YamlCompletionResults.empty();
+  }
+
+  @override
+  Future<void> handle() async {
+    var params = CompletionGetSuggestions2Params.fromRequest(request);
+    var file = params.file;
+    var offset = params.offset;
+
+    var timeoutMilliseconds = params.timeout;
+    var budget = CompletionBudget(
+      timeoutMilliseconds != null
+          ? Duration(milliseconds: timeoutMilliseconds)
+          : server.completionState.budgetDuration,
+    );
+
+    var provider = server.resourceProvider;
+    var pathContext = provider.pathContext;
+
+    if (file.endsWith('.yaml')) {
+      final suggestions = computeYamlSuggestions(file, offset);
+      server.sendResponse(
+        CompletionGetSuggestions2Result(
+          suggestions.replacementOffset,
+          suggestions.replacementLength,
+          suggestions.suggestions,
+          false,
+        ).toResponse(request.id),
+      );
+      return;
+    }
+
+    if (!file_paths.isDart(pathContext, file)) {
+      server.sendResponse(
+        CompletionGetSuggestions2Result(offset, 0, [], false)
+            .toResponse(request.id),
+      );
+      return;
+    }
+
+    var performance = OperationPerformanceImpl('<root>');
+    performance.runAsync(
+      'request',
+      (performance) async {
+        var resolvedUnit = await performance.runAsync(
+          'resolveForCompletion',
+          (performance) {
+            return server.resolveForCompletion(
+              path: file,
+              offset: offset,
+              performance: performance,
+            );
+          },
+        );
+        if (resolvedUnit == null) {
+          server.sendResponse(Response.fileNotAnalyzed(request, file));
+          return;
+        }
+
+        if (offset < 0 || offset > resolvedUnit.content.length) {
+          server.sendResponse(Response.invalidParameter(
+              request,
+              'params.offset',
+              'Expected offset between 0 and source length inclusive,'
+                  ' but found $offset'));
+          return;
+        }
+
+        final completionPerformance = CompletionPerformance(
+          operation: performance,
+          path: file,
+          content: resolvedUnit.content,
+          offset: offset,
+        );
+        server.completionState.performanceList.add(completionPerformance);
+
+        var analysisSession = resolvedUnit.analysisSession;
+        var enclosingNode =
+            resolvedUnit.resolvedNodes.lastOrNull ?? resolvedUnit.parsedUnit;
+
+        var completionRequest = DartCompletionRequest(
+          analysisSession: analysisSession,
+          filePath: resolvedUnit.path,
+          fileContent: resolvedUnit.content,
+          unitElement: resolvedUnit.unitElement,
+          enclosingNode: enclosingNode,
+          offset: offset,
+          dartdocDirectiveInfo:
+              server.getDartdocDirectiveInfoForSession(analysisSession),
+          documentationCache:
+              server.getDocumentationCacheForSession(analysisSession),
+        );
+        setNewRequest(completionRequest);
+
+        var notImportedSuggestions = NotImportedSuggestions();
+        var suggestionBuilders = <CompletionSuggestionBuilder>[];
+        try {
+          suggestionBuilders = await computeSuggestions(
+            budget: budget,
+            performance: performance,
+            request: completionRequest,
+            notImportedSuggestions: notImportedSuggestions,
+          );
+        } on AbortCompletion {
+          return server.sendResponse(
+            CompletionGetSuggestions2Result(
+              completionRequest.replacementOffset,
+              completionRequest.replacementLength,
+              [],
+              true,
+            ).toResponse(request.id),
+          );
+        }
+
+        performance.run('filter', (performance) {
+          performance.getDataInt('count').add(suggestionBuilders.length);
+          suggestionBuilders = fuzzyFilterSort(
+            pattern: completionRequest.targetPrefix,
+            suggestions: suggestionBuilders,
+          );
+          performance.getDataInt('matchCount').add(suggestionBuilders.length);
+        });
+
+        var lengthRestricted =
+            suggestionBuilders.take(params.maxResults).toList();
+        completionPerformance.computedSuggestionCount =
+            suggestionBuilders.length;
+        completionPerformance.transmittedSuggestionCount =
+            lengthRestricted.length;
+
+        var suggestions = lengthRestricted.map((e) => e.build()).toList();
+
+        var isIncomplete = notImportedSuggestions.isIncomplete ||
+            lengthRestricted.length < suggestionBuilders.length;
+
+        performance.run('sendResponse', (_) {
+          sendResult(CompletionGetSuggestions2Result(
+            completionRequest.replacementOffset,
+            completionRequest.replacementLength,
+            suggestions,
+            isIncomplete,
+          ));
+        });
+      },
+    );
+  }
+
+  /// Send completion notification results.
+  void sendCompletionNotification(
+    String completionId,
+    int replacementOffset,
+    int replacementLength,
+    List<CompletionSuggestion> results,
+    String? libraryFile,
+    List<IncludedSuggestionSet>? includedSuggestionSets,
+    List<ElementKind>? includedElementKinds,
+    List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
+  ) {
+    server.sendNotification(
+      CompletionResultsParams(
+        completionId,
+        replacementOffset,
+        replacementLength,
+        results,
+        true,
+        libraryFile: libraryFile,
+        includedSuggestionSets: includedSuggestionSets,
+        includedElementKinds: includedElementKinds,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      ).toNotification(),
+    );
+  }
+
+  void setNewRequest(DartCompletionRequest request) {
+    _abortCurrentRequest();
+    server.completionState.currentRequest = request;
+  }
+
+  /// Abort the current completion request, if any.
+  void _abortCurrentRequest() {
+    var currentRequest = server.completionState.currentRequest;
+    if (currentRequest != null) {
+      currentRequest.abort();
+      server.completionState.currentRequest = null;
+    }
+  }
+
+  /// Add the completions produced by plugins to the server-generated list.
+  Future<void> _addPluginSuggestions(
+    CompletionBudget budget,
+    _RequestToPlugins requestToPlugins,
+    List<CompletionSuggestionBuilder> suggestionBuilders,
+  ) async {
+    var responses = await waitForResponses(
+      requestToPlugins.futures,
+      requestParameters: requestToPlugins.parameters,
+      timeout: budget.left,
+    );
+    for (var response in responses) {
+      var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
+      if (result.results.isNotEmpty) {
+        var completionRequest = requestToPlugins.completionRequest;
+        if (completionRequest.replacementOffset != result.replacementOffset &&
+            completionRequest.replacementLength != result.replacementLength) {
+          server.instrumentationService
+              .logError('Plugin completion-results dropped due to conflicting'
+                  ' replacement offset/length: ${result.toJson()}');
+          continue;
+        }
+        suggestionBuilders.addAll(
+          result.results.map(
+            (suggestion) => ValueCompletionSuggestionBuilder(suggestion),
+          ),
+        );
+      }
+    }
+  }
+
+  /// Send the completion request to plugins, so that they work in other
+  /// isolates in parallel with the server isolate.
+  _RequestToPlugins? _sendRequestToPlugins(
+    DartCompletionRequest completionRequest,
+  ) {
+    var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
+      completionRequest.path,
+      completionRequest.offset,
+    );
+
+    return _RequestToPlugins(
+      completionRequest: completionRequest,
+      parameters: pluginRequestParameters,
+      futures: server.pluginManager.broadcastRequest(
+        pluginRequestParameters,
+        contextRoot: completionRequest.analysisContext.contextRoot,
+      ),
+    );
+  }
+}
+
+class _RequestToPlugins {
+  final DartCompletionRequest completionRequest;
+  final plugin.CompletionGetSuggestionsParams parameters;
+  final Map<PluginInfo, Future<plugin.Response>> futures;
+
+  _RequestToPlugins({
+    required this.completionRequest,
+    required this.parameters,
+    required this.futures,
+  });
+}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart
new file mode 100644
index 0000000..14dbe993
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart
@@ -0,0 +1,49 @@
+// 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.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+
+/// The handler for the `completion.setSubscriptions` request.
+class CompletionSetSubscriptionsHandler extends LegacyHandler {
+  /// Initialize a newly created handler to be able to service requests for the
+  /// [server].
+  CompletionSetSubscriptionsHandler(
+      super.server, super.request, super.cancellationToken);
+
+  @override
+  Future<void> handle() async {
+    var params = CompletionSetSubscriptionsParams.fromRequest(request);
+
+    var subscriptions = server.completionState.subscriptions;
+    subscriptions.clear();
+    subscriptions.addAll(params.subscriptions);
+
+    var data = server.declarationsTrackerData;
+    if (data != null) {
+      if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+        var soFarLibraries = data.startListening((change) {
+          server.sendNotification(
+            createCompletionAvailableSuggestionsNotification(
+              change.changed,
+              change.removed,
+            ),
+          );
+        });
+        server.sendNotification(
+          createCompletionAvailableSuggestionsNotification(
+            soFarLibraries,
+            [],
+          ),
+        );
+      } else {
+        data.stopListening();
+      }
+    }
+    sendResult(CompletionSetSubscriptionsResult());
+  }
+}
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 788a702..f4fc4e2 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -2,27 +2,166 @@
 // 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.
 
-// @dart = 2.10
-
 library entities;
 
-import '../serialization/serialization.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../util/util.dart';
-import 'types.dart';
+import 'package:front_end/src/api_unstable/dart2js.dart' show AsyncModifier;
 
-import 'entities_migrated.dart';
-export 'entities_migrated.dart';
+// TODO(48820): Spannable was imported from `../common.dart`.
+import '../diagnostics/spannable.dart' show Spannable;
+import '../util/util.dart';
+import 'names.dart';
+
+/// Abstract interface for entities.
+///
+/// Implement this directly if the entity is not a Dart language entity.
+/// Entities defined within the Dart language should implement [Element].
+///
+/// For instance, the JavaScript backend need to create synthetic variables for
+/// calling intercepted classes and such variables do not correspond to an
+/// entity in the Dart source code nor in the terminology of the Dart language
+/// and should therefore implement [Entity] directly.
+abstract class Entity implements Spannable {
+  // Not all entities have names. Imports with no prefix and some local
+  // variables are unnamed. Some entities have a name that is the empty string
+  // (e.g. the default constructor).
+  String? get name;
+}
+
+/// Stripped down super interface for library like entities.
+///
+/// Currently only [LibraryElement] but later also kernel based Dart classes
+/// and/or Dart-in-JS classes.
+abstract class LibraryEntity extends Entity {
+  /// Return the canonical uri that identifies this library.
+  Uri get canonicalUri;
+
+  /// Returns whether or not this library has opted into null safety.
+  bool get isNonNullableByDefault;
+}
+
+/// Stripped down super interface for import entities.
+///
+/// The [name] property corresponds to the prefix name, if any.
+class ImportEntity {
+  final String? name;
+
+  /// The canonical URI of the library where this import occurs
+  /// (where the import is declared).
+  final Uri enclosingLibraryUri;
+
+  /// Whether the import is a deferred import.
+  final bool isDeferred;
+
+  /// The target import URI.
+  final Uri uri;
+
+  ImportEntity(this.isDeferred, this.name, this.uri, this.enclosingLibraryUri);
+
+  @override
+  String toString() => 'import($name:${isDeferred ? ' deferred' : ''})';
+}
+
+/// Stripped down super interface for class like entities.
+///
+/// Currently only [ClassElement] but later also kernel based Dart classes
+/// and/or Dart-in-JS classes.
+abstract class ClassEntity extends Entity {
+  /// If this is a normal class, the enclosing library for this class. If this
+  /// is a closure class, the enclosing class of the closure for which it was
+  /// created.
+  LibraryEntity get library;
+
+  /// Whether this is a synthesized class for a closurized method or local
+  /// function.
+  bool get isClosure;
+
+  /// Whether this is an abstract class.
+  bool get isAbstract;
+}
 
 abstract class TypeVariableEntity extends Entity {
   /// The class or generic method that declared this type variable.
-  Entity get typeDeclaration;
+  /// Is `null` for some generic functions and closures.
+  // TODO(sra): Figure out how to always have a [typeDeclaration].
+  Entity? get typeDeclaration;
 
   /// The index of this type variable in the type variables of its
   /// [typeDeclaration].
   int get index;
 }
 
+/// Stripped down super interface for member like entities, that is,
+/// constructors, methods, fields etc.
+///
+/// Currently only [MemberElement] but later also kernel based Dart members
+/// and/or Dart-in-JS properties.
+abstract class MemberEntity extends Entity {
+  /// The [Name] of member which takes privacy and getter/setter naming into
+  /// account.
+  Name get memberName;
+
+  /// Whether this is a member of a library.
+  bool get isTopLevel;
+
+  /// Whether this is a static member of a class.
+  bool get isStatic;
+
+  /// Whether this is an instance member of a class.
+  bool get isInstanceMember;
+
+  /// Whether this is a constructor.
+  bool get isConstructor;
+
+  /// Whether this is a field.
+  bool get isField;
+
+  /// Whether this is a normal method (neither constructor, getter or setter)
+  /// or operator method.
+  bool get isFunction;
+
+  /// Whether this is a getter.
+  bool get isGetter;
+
+  /// Whether this is a setter.
+  bool get isSetter;
+
+  /// Whether this member is assignable, i.e. a non-final, non-const field.
+  bool get isAssignable;
+
+  /// Whether this member is constant, i.e. a constant field or constructor.
+  bool get isConst;
+
+  /// Whether this member is abstract, i.e. an abstract method, getter or
+  /// setter.
+  bool get isAbstract;
+
+  /// The enclosing class if this is a constructor, instance member or
+  /// static member of a class.
+  ClassEntity? get enclosingClass;
+
+  /// The enclosing library if this is a library member, otherwise the
+  /// enclosing library of the [enclosingClass].
+  LibraryEntity get library;
+}
+
+/// Stripped down super interface for field like entities.
+///
+/// Currently only [FieldElement] but later also kernel based Dart fields
+/// and/or Dart-in-JS field-like properties.
+abstract class FieldEntity extends MemberEntity {}
+
+/// An entity that defines a local entity (memory slot) in generated code.
+///
+/// Parameters, local variables and local functions (can) define local entity
+/// and thus implement [Local] through [LocalElement]. For non-element locals,
+/// like `this` and boxes, specialized [Local] classes are created.
+///
+/// Type variables can introduce locals in factories and constructors
+/// but since one type variable can introduce different locals in different
+/// factories and constructors it is not itself a [Local] but instead
+/// a non-element [Local] is created through a specialized class.
+abstract class Local extends Entity {}
+
 /// Stripped down super interface for function like entities.
 ///
 /// Currently only [MethodElement] but later also kernel based Dart constructors
@@ -30,7 +169,7 @@
 abstract class FunctionEntity extends MemberEntity {
   /// Whether this function is external, i.e. the body is not defined in terms
   /// of Dart code.
-  bool /*!*/ get isExternal;
+  bool get isExternal;
 
   /// The structure of the function parameters.
   ParameterStructure get parameterStructure;
@@ -39,6 +178,61 @@
   AsyncMarker get asyncMarker;
 }
 
+/// Enum for the synchronous/asynchronous function body modifiers.
+class AsyncMarker {
+  /// The default function body marker.
+  static const AsyncMarker SYNC = AsyncMarker._(AsyncModifier.Sync);
+
+  /// The `sync*` function body marker.
+  static const AsyncMarker SYNC_STAR =
+      AsyncMarker._(AsyncModifier.SyncStar, isYielding: true);
+
+  /// The `async` function body marker.
+  static const AsyncMarker ASYNC =
+      AsyncMarker._(AsyncModifier.Async, isAsync: true);
+
+  /// The `async*` function body marker.
+  static const AsyncMarker ASYNC_STAR =
+      AsyncMarker._(AsyncModifier.AsyncStar, isAsync: true, isYielding: true);
+
+  /// Is `true` if this marker defines the function body to have an
+  /// asynchronous result, that is, either a [Future] or a [Stream].
+  final bool isAsync;
+
+  /// Is `true` if this marker defines the function body to have a plural
+  /// result, that is, either an [Iterable] or a [Stream].
+  final bool isYielding;
+
+  final AsyncModifier asyncParserState;
+
+  const AsyncMarker._(this.asyncParserState,
+      {this.isAsync = false, this.isYielding = false});
+
+  @override
+  String toString() {
+    return '${isAsync ? 'async' : 'sync'}${isYielding ? '*' : ''}';
+  }
+
+  /// Canonical list of marker values.
+  ///
+  /// Added to make [AsyncMarker] enum-like.
+  static const List<AsyncMarker> values = <AsyncMarker>[
+    SYNC,
+    SYNC_STAR,
+    ASYNC,
+    ASYNC_STAR
+  ];
+
+  /// Index to this marker within [values].
+  ///
+  /// Added to make [AsyncMarker] enum-like.
+  int get index => values.indexOf(this);
+}
+
+/// Values for variance annotations.
+/// This needs to be kept in sync with values of `Variance` in `dart:_rti`.
+enum Variance { legacyCovariant, covariant, contravariant, invariant }
+
 /// Stripped down super interface for constructor like entities.
 ///
 /// Currently only [ConstructorElement] but later also kernel based Dart
@@ -123,8 +317,8 @@
   factory ParameterStructure(
       int requiredPositionalParameters,
       int positionalParameters,
-      List<String /*!*/ > namedParameters,
-      Set<String /*!*/ > requiredNamedParameters,
+      List<String> namedParameters,
+      Set<String> requiredNamedParameters,
       int typeParameters) {
     // This simple canonicalization reduces the number of ParameterStructure
     // objects by over 90%.
@@ -149,44 +343,6 @@
     );
   }
 
-  factory ParameterStructure.fromType(FunctionType type) {
-    return ParameterStructure(
-        type.parameterTypes.length,
-        type.parameterTypes.length + type.optionalParameterTypes.length,
-        type.namedParameters,
-        type.requiredNamedParameters,
-        type.typeVariables.length);
-  }
-
-  /// Deserializes a [ParameterStructure] object from [source].
-  factory ParameterStructure.readFromDataSource(DataSourceReader source) {
-    source.begin(tag);
-    int requiredPositionalParameters = source.readInt();
-    int positionalParameters = source.readInt();
-    List<String> namedParameters = source.readStrings() /*!*/;
-    Set<String> requiredNamedParameters =
-        source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
-    int typeParameters = source.readInt();
-    source.end(tag);
-    return ParameterStructure(
-        requiredPositionalParameters,
-        positionalParameters,
-        namedParameters,
-        requiredNamedParameters,
-        typeParameters);
-  }
-
-  /// Serializes this [ParameterStructure] to [sink].
-  void writeToDataSink(DataSinkWriter sink) {
-    sink.begin(tag);
-    sink.writeInt(requiredPositionalParameters);
-    sink.writeInt(positionalParameters);
-    sink.writeStrings(namedParameters);
-    sink.writeStrings(requiredNamedParameters);
-    sink.writeInt(typeParameters);
-    sink.end(tag);
-  }
-
   /// The number of optional parameters (positional or named).
   int get optionalParameters =>
       (positionalParameters - requiredPositionalParameters) +
@@ -195,11 +351,8 @@
   /// The total number of parameters (required or optional).
   int get totalParameters => positionalParameters + namedParameters.length;
 
-  /// Returns the [CallStructure] corresponding to a call site passing all
-  /// parameters both required and optional.
-  CallStructure get callStructure {
-    return CallStructure(totalParameters, namedParameters, typeParameters);
-  }
+  // TODO(48820): Move definition back here:
+  // CallStructure get callStructure;
 
   @override
   int get hashCode => Hashing.listHash(
diff --git a/pkg/compiler/lib/src/elements/entities_migrated.dart b/pkg/compiler/lib/src/elements/entities_migrated.dart
deleted file mode 100644
index 7e7a26f..0000000
--- a/pkg/compiler/lib/src/elements/entities_migrated.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library entities.migrated;
-
-import 'package:front_end/src/api_unstable/dart2js.dart' show AsyncModifier;
-
-// TODO(48820): This was imported from `common.dart`.
-import '../diagnostics/spannable.dart' show Spannable;
-
-import 'names.dart';
-
-/// Abstract interface for entities.
-///
-/// Implement this directly if the entity is not a Dart language entity.
-/// Entities defined within the Dart language should implement [Element].
-///
-/// For instance, the JavaScript backend need to create synthetic variables for
-/// calling intercepted classes and such variables do not correspond to an
-/// entity in the Dart source code nor in the terminology of the Dart language
-/// and should therefore implement [Entity] directly.
-abstract class Entity implements Spannable {
-  // Not all entities have names. Imports with no prefix and some local
-  // variables are unnamed. Some entities have a name that is the empty string
-  // (e.g. the default constructor).
-  String? get name;
-}
-
-/// Stripped down super interface for library like entities.
-///
-/// Currently only [LibraryElement] but later also kernel based Dart classes
-/// and/or Dart-in-JS classes.
-abstract class LibraryEntity extends Entity {
-  /// Return the canonical uri that identifies this library.
-  Uri get canonicalUri;
-
-  /// Returns whether or not this library has opted into null safety.
-  bool get isNonNullableByDefault;
-}
-
-/// Stripped down super interface for import entities.
-///
-/// The [name] property corresponds to the prefix name, if any.
-class ImportEntity {
-  final String? name;
-
-  /// The canonical URI of the library where this import occurs
-  /// (where the import is declared).
-  final Uri enclosingLibraryUri;
-
-  /// Whether the import is a deferred import.
-  final bool isDeferred;
-
-  /// The target import URI.
-  final Uri uri;
-
-  ImportEntity(this.isDeferred, this.name, this.uri, this.enclosingLibraryUri);
-
-  @override
-  String toString() => 'import($name:${isDeferred ? ' deferred' : ''})';
-}
-
-/// Stripped down super interface for class like entities.
-///
-/// Currently only [ClassElement] but later also kernel based Dart classes
-/// and/or Dart-in-JS classes.
-abstract class ClassEntity extends Entity {
-  /// If this is a normal class, the enclosing library for this class. If this
-  /// is a closure class, the enclosing class of the closure for which it was
-  /// created.
-  LibraryEntity get library;
-
-  /// Whether this is a synthesized class for a closurized method or local
-  /// function.
-  bool get isClosure;
-
-  /// Whether this is an abstract class.
-  bool get isAbstract;
-}
-
-/// Stripped down super interface for member like entities, that is,
-/// constructors, methods, fields etc.
-///
-/// Currently only [MemberElement] but later also kernel based Dart members
-/// and/or Dart-in-JS properties.
-abstract class MemberEntity extends Entity {
-  /// The [Name] of member which takes privacy and getter/setter naming into
-  /// account.
-  Name get memberName;
-
-  /// Whether this is a member of a library.
-  bool get isTopLevel;
-
-  /// Whether this is a static member of a class.
-  bool get isStatic;
-
-  /// Whether this is an instance member of a class.
-  bool get isInstanceMember;
-
-  /// Whether this is a constructor.
-  bool get isConstructor;
-
-  /// Whether this is a field.
-  bool get isField;
-
-  /// Whether this is a normal method (neither constructor, getter or setter)
-  /// or operator method.
-  bool get isFunction;
-
-  /// Whether this is a getter.
-  bool get isGetter;
-
-  /// Whether this is a setter.
-  bool get isSetter;
-
-  /// Whether this member is assignable, i.e. a non-final, non-const field.
-  bool get isAssignable;
-
-  /// Whether this member is constant, i.e. a constant field or constructor.
-  bool get isConst;
-
-  /// Whether this member is abstract, i.e. an abstract method, getter or
-  /// setter.
-  bool get isAbstract;
-
-  /// The enclosing class if this is a constructor, instance member or
-  /// static member of a class.
-  ClassEntity? get enclosingClass;
-
-  /// The enclosing library if this is a library member, otherwise the
-  /// enclosing library of the [enclosingClass].
-  LibraryEntity get library;
-}
-
-/// Stripped down super interface for field like entities.
-///
-/// Currently only [FieldElement] but later also kernel based Dart fields
-/// and/or Dart-in-JS field-like properties.
-abstract class FieldEntity extends MemberEntity {}
-
-/// An entity that defines a local entity (memory slot) in generated code.
-///
-/// Parameters, local variables and local functions (can) define local entity
-/// and thus implement [Local] through [LocalElement]. For non-element locals,
-/// like `this` and boxes, specialized [Local] classes are created.
-///
-/// Type variables can introduce locals in factories and constructors
-/// but since one type variable can introduce different locals in different
-/// factories and constructors it is not itself a [Local] but instead
-/// a non-element [Local] is created through a specialized class.
-abstract class Local extends Entity {}
-
-/// Enum for the synchronous/asynchronous function body modifiers.
-class AsyncMarker {
-  /// The default function body marker.
-  static const AsyncMarker SYNC = AsyncMarker._(AsyncModifier.Sync);
-
-  /// The `sync*` function body marker.
-  static const AsyncMarker SYNC_STAR =
-      AsyncMarker._(AsyncModifier.SyncStar, isYielding: true);
-
-  /// The `async` function body marker.
-  static const AsyncMarker ASYNC =
-      AsyncMarker._(AsyncModifier.Async, isAsync: true);
-
-  /// The `async*` function body marker.
-  static const AsyncMarker ASYNC_STAR =
-      AsyncMarker._(AsyncModifier.AsyncStar, isAsync: true, isYielding: true);
-
-  /// Is `true` if this marker defines the function body to have an
-  /// asynchronous result, that is, either a [Future] or a [Stream].
-  final bool isAsync;
-
-  /// Is `true` if this marker defines the function body to have a plural
-  /// result, that is, either an [Iterable] or a [Stream].
-  final bool isYielding;
-
-  final AsyncModifier asyncParserState;
-
-  const AsyncMarker._(this.asyncParserState,
-      {this.isAsync = false, this.isYielding = false});
-
-  @override
-  String toString() {
-    return '${isAsync ? 'async' : 'sync'}${isYielding ? '*' : ''}';
-  }
-
-  /// Canonical list of marker values.
-  ///
-  /// Added to make [AsyncMarker] enum-like.
-  static const List<AsyncMarker> values = <AsyncMarker>[
-    SYNC,
-    SYNC_STAR,
-    ASYNC,
-    ASYNC_STAR
-  ];
-
-  /// Index to this marker within [values].
-  ///
-  /// Added to make [AsyncMarker] enum-like.
-  int get index => values.indexOf(this);
-}
-
-/// Values for variance annotations.
-/// This needs to be kept in sync with values of `Variance` in `dart:_rti`.
-enum Variance { legacyCovariant, covariant, contravariant, invariant }
diff --git a/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart b/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
new file mode 100644
index 0000000..a7f4702
--- /dev/null
+++ b/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2016, 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.
+
+// @dart = 2.10
+
+/// Methods for [ParameterStructure] that have not yet been migrated to null
+/// safety.
+// TODO(48820): Move these methods back to [ParameterStructure].
+library entities.parameter_structure_methods;
+
+import '../serialization/serialization.dart';
+import '../universe/call_structure.dart' show CallStructure;
+import 'entities.dart';
+import 'types.dart' show FunctionType;
+
+extension UnmigratedParameterStructureInstanceMethods on ParameterStructure {
+  /// Returns the [CallStructure] corresponding to a call site passing all
+  /// parameters both required and optional.
+  CallStructure get callStructure {
+    return CallStructure(totalParameters, namedParameters, typeParameters);
+  }
+
+  /// Serializes this [ParameterStructure] to [sink].
+  void writeToDataSink(DataSinkWriter sink) {
+    final tag = ParameterStructure.tag;
+    sink.begin(tag);
+    sink.writeInt(requiredPositionalParameters);
+    sink.writeInt(positionalParameters);
+    sink.writeStrings(namedParameters);
+    sink.writeStrings(requiredNamedParameters);
+    sink.writeInt(typeParameters);
+    sink.end(tag);
+  }
+}
+
+class ParameterStructureMethods {
+  static ParameterStructure fromType(FunctionType type) {
+    return ParameterStructure(
+        type.parameterTypes.length,
+        type.parameterTypes.length + type.optionalParameterTypes.length,
+        type.namedParameters,
+        type.requiredNamedParameters,
+        type.typeVariables.length);
+  }
+
+  /// Deserializes a [ParameterStructure] object from [source].
+  static readFromDataSource(DataSourceReader source) {
+    final tag = ParameterStructure.tag;
+    source.begin(tag);
+    int requiredPositionalParameters = source.readInt();
+    int positionalParameters = source.readInt();
+    List<String> namedParameters = source.readStrings() /*!*/;
+    Set<String> requiredNamedParameters =
+        source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
+    int typeParameters = source.readInt();
+    source.end(tag);
+    return ParameterStructure(
+        requiredPositionalParameters,
+        positionalParameters,
+        namedParameters,
+        requiredNamedParameters,
+        typeParameters);
+  }
+}
diff --git a/pkg/compiler/lib/src/elements/jumps.dart b/pkg/compiler/lib/src/elements/jumps.dart
index f6080e2..de1cf48 100644
--- a/pkg/compiler/lib/src/elements/jumps.dart
+++ b/pkg/compiler/lib/src/elements/jumps.dart
@@ -4,7 +4,7 @@
 
 library elements.jumps;
 
-import 'entities_migrated.dart' show Entity, Local;
+import 'entities.dart' show Entity, Local;
 
 /// The label entity defined by a labeled statement.
 abstract class LabelDefinition extends Entity {
diff --git a/pkg/compiler/lib/src/elements/names.dart b/pkg/compiler/lib/src/elements/names.dart
index 90f5e15..f4ec96f 100644
--- a/pkg/compiler/lib/src/elements/names.dart
+++ b/pkg/compiler/lib/src/elements/names.dart
@@ -6,7 +6,7 @@
 
 import 'package:front_end/src/api_unstable/dart2js.dart' show $_;
 
-import 'entities_migrated.dart' show LibraryEntity;
+import 'entities.dart' show LibraryEntity;
 
 /// A [Name] represents the abstraction of a Dart identifier which takes privacy
 /// and setter into account.
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index e0f1ff5..e8d244f 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -6,8 +6,7 @@
 
 // TODO(48820): revert to '../common.dart':
 import '../diagnostics/source_span.dart';
-import '../elements/entities_migrated.dart'
-    show AsyncMarker, MemberEntity, Variance;
+import '../elements/entities.dart' show AsyncMarker, MemberEntity, Variance;
 
 /// Returns a textual representation of [node] that include the runtime type and
 /// hash code of the node and a one line prefix of the node toString text.
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 6682b3e..d2d4aa2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -12,6 +12,7 @@
 import '../common/names.dart' show Identifiers;
 import '../constants/values.dart';
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/types.dart';
 import '../enqueue.dart' show Enqueuer, EnqueuerListener;
 import '../native/enqueue.dart';
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 12113ce..c6b8b41 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -11,6 +11,7 @@
 import '../constants/values.dart';
 import '../deferred_load/deferred_load.dart';
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/types.dart';
 import '../enqueue.dart' show Enqueuer, EnqueuerListener;
 import '../native/enqueue.dart';
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index ce85047..5e14de3 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -10,6 +10,7 @@
 import '../common/elements.dart' show CommonElements, ElementEnvironment;
 import '../common/names.dart' show Identifiers;
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../ir/runtime_type_analysis.dart';
@@ -141,7 +142,8 @@
     if (property.memberName != selector.memberName) return false;
     if (type is FunctionType &&
         !selector.callStructure
-            .signatureApplies(ParameterStructure.fromType(type))) return false;
+            .signatureApplies(ParameterStructureMethods.fromType(type)))
+      return false;
     return true;
   }
 
@@ -288,8 +290,9 @@
             instanceName: instanceName,
             isNoSuchMethod: isNoSuchMethod);
       } else {
-        ParameterStructure parameterStructure = ParameterStructure.fromType(
-            _elementEnvironment.getLocalFunctionType(function));
+        ParameterStructure parameterStructure =
+            ParameterStructureMethods.fromType(
+                _elementEnvironment.getLocalFunctionType(function));
         node = MethodNode(function, parameterStructure, isCallTarget: true);
       }
       return node;
@@ -446,7 +449,7 @@
 
     for (GenericInstantiation instantiation in _genericInstantiations) {
       ParameterStructure instantiationParameterStructure =
-          ParameterStructure.fromType(instantiation.functionType);
+          ParameterStructureMethods.fromType(instantiation.functionType);
       ClassEntity implementationClass = _commonElements
           .getInstantiationClass(instantiation.typeArguments.length);
 
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index c9df01d..1cb41cc 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -204,7 +204,7 @@
         ParameterStructure parameterStructure =
             annotations.hasNoElision(constructor)
                 ? constructor.parameterStructure
-                : memberUsage.invokedParameters;
+                : memberUsage.invokedParameters /*!*/;
         if (constructor.isFactoryConstructor) {
           // TODO(redemption): This should be a JFunction.
           newMember = JFactoryConstructor(
@@ -236,7 +236,7 @@
         ParameterStructure parameterStructure =
             annotations.hasNoElision(function)
                 ? function.parameterStructure
-                : memberUsage.invokedParameters;
+                : memberUsage.invokedParameters /*!*/;
         newMember = JMethod(newLibrary, newClass, memberName,
             parameterStructure, function.asyncMarker,
             isStatic: function.isStatic,
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 6a6d47c..9d3517e 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -10,6 +10,7 @@
 import '../elements/entities.dart';
 import '../elements/indexed.dart';
 import '../elements/names.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/types.dart';
 import '../serialization/serialization.dart';
 import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
@@ -279,7 +280,7 @@
     JClass enclosingClass = source.readClass();
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructure.readFromDataSource(source);
+        ParameterStructureMethods.readFromDataSource(source);
     bool isExternal = source.readBool();
     bool isConst = source.readBool();
     source.end(tag);
@@ -317,7 +318,9 @@
 
   JFactoryConstructor(
       JClass enclosingClass, Name name, ParameterStructure parameterStructure,
-      {bool isExternal, bool isConst, this.isFromEnvironmentConstructor})
+      {bool isExternal,
+      bool isConst,
+      /*required*/ this.isFromEnvironmentConstructor})
       : super(enclosingClass, name, parameterStructure,
             isExternal: isExternal, isConst: isConst);
 
@@ -326,7 +329,7 @@
     JClass enclosingClass = source.readClass();
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructure.readFromDataSource(source);
+        ParameterStructureMethods.readFromDataSource(source);
     bool isExternal = source.readBool();
     bool isConst = source.readBool();
     bool isFromEnvironmentConstructor = source.readBool();
@@ -375,7 +378,7 @@
     source.begin(tag);
     JConstructor constructor = source.readMember();
     ParameterStructure parameterStructure =
-        ParameterStructure.readFromDataSource(source);
+        ParameterStructureMethods.readFromDataSource(source);
     source.end(tag);
     return JConstructorBody(constructor, parameterStructure);
   }
@@ -423,7 +426,7 @@
     }
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructure.readFromDataSource(source);
+        ParameterStructureMethods.readFromDataSource(source);
     AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
     bool isStatic = source.readBool();
     bool isExternal = source.readBool();
@@ -705,7 +708,7 @@
     source.begin(tag);
     JClass enclosingClass = source.readClass();
     ParameterStructure parameterStructure =
-        ParameterStructure.readFromDataSource(source);
+        ParameterStructureMethods.readFromDataSource(source);
     AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
     source.end(tag);
     return JClosureCallMethod(enclosingClass, parameterStructure, asyncMarker);
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 76086f5..9d05fc1 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -191,8 +191,9 @@
             .getTopLevelProcedure('dart:core', '_createInvocationMirror'),
         ir.Arguments(<ir.Expression>[
           ir.StringLiteral(name)..fileOffset = offset,
-          ir.ListLiteral(
-              arguments.types.map((t) => ir.TypeLiteral(t)).toList()),
+          ir.ListLiteral(arguments.types
+              .map<ir.Expression>((t) => ir.TypeLiteral(t))
+              .toList()),
           ir.ListLiteral(arguments.positional)..fileOffset = offset,
           ir.MapLiteral(List<ir.MapLiteralEntry>.from(
               arguments.named.map((ir.NamedExpression arg) {
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index a0ab430..75f9512 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -12,6 +12,7 @@
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/types.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index cdafadd..26ac29a 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -9,6 +9,7 @@
 import '../common.dart';
 import '../common/names.dart' show Names;
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/entity_utils.dart' as utils;
 import '../elements/names.dart';
 import '../elements/operators.dart';
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 9ddd60d..f8861b1 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -22,6 +22,7 @@
 import '../constants/values.dart';
 import '../elements/types.dart';
 import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../serialization/serialization.dart';
 import '../js_model/closure.dart';
diff --git a/pkg/compiler/test/generic_methods/generic_method_type_test.dart b/pkg/compiler/test/generic_methods/generic_method_type_test.dart
index 6b2708d..0d30632 100644
--- a/pkg/compiler/test/generic_methods/generic_method_type_test.dart
+++ b/pkg/compiler/test/generic_methods/generic_method_type_test.dart
@@ -7,6 +7,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/entities_parameter_structure_methods.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/universe/call_structure.dart';
 import 'package:expect/expect.dart';
diff --git a/pkg/compiler/test/model/enqueuer_test.dart b/pkg/compiler/test/model/enqueuer_test.dart
index ac2f0c3..c3a7b5f 100644
--- a/pkg/compiler/test/model/enqueuer_test.dart
+++ b/pkg/compiler/test/model/enqueuer_test.dart
@@ -12,6 +12,7 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common/elements.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/entities_parameter_structure_methods.dart';
 import 'package:compiler/src/elements/names.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/enqueue.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index c363409..17d5d77 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -92,7 +92,7 @@
   static Expression _makeForwardingCall(
       Member target, List<DartType> typeArguments, FunctionNode function) {
     final List<Expression> positional = function.positionalParameters
-        .map((v) => new VariableGet(v)..fileOffset = v.fileOffset)
+        .map<Expression>((v) => new VariableGet(v)..fileOffset = v.fileOffset)
         .toList();
     final List<NamedExpression> named = function.namedParameters
         .map((v) => new NamedExpression(
diff --git a/pkg/front_end/testcases/general/infer_map.dart b/pkg/front_end/testcases/general/infer_map.dart
new file mode 100644
index 0000000..af8b81d
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart
@@ -0,0 +1,34 @@
+// 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.
+
+class A {}
+
+class B extends A {}
+
+List<int> intList = [1, 2];
+
+List<A> list1 = intList.map((i) => new B()).toList();
+
+test(List<A> list) {
+  try {
+    list.add(new A());
+    list.removeLast();
+  } catch (e) {
+    return;
+  }
+  throw 'Expected subtype error';
+}
+
+main() {
+  test(list1);
+  list1 = intList.map((i) => new B()).toList();
+  test(list1);
+
+  List<A> list2 = intList.map((i) => new B()).toList();
+  test(list2);
+  list2 = intList.map((i) => new B()).toList();
+  test(list2);
+
+  test(intList.map((i) => new B()).toList());
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect
new file mode 100644
index 0000000..d62af11
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {}
+
+class B extends A {}
+
+List<int> intList = [1, 2];
+List<A> list1 = intList.map((i) => new B()).toList();
+test(List<A> list) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3683c37
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+List<A> list1 = intList.map((i) => new B()).toList();
+List<int> intList = [1, 2];
+
+class A {}
+
+class B extends A {}
+
+main() {}
+test(List<A> list) {}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.expect
new file mode 100644
index 0000000..d1501d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+static field core::List<core::int> intList = <core::int>[1, 2];
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+  try {
+    list.{core::List::add}(new self::A::•()){(self::A) → void};
+    list.{core::List::removeLast}(){() → self::A};
+  }
+  on core::Object catch(final core::Object e) {
+    return;
+  }
+  throw "Expected subtype error";
+}
+static method main() → dynamic {
+  self::test(self::list1);
+  self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(self::list1);
+  core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect
new file mode 100644
index 0000000..d1501d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+static field core::List<core::int> intList = <core::int>[1, 2];
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+  try {
+    list.{core::List::add}(new self::A::•()){(self::A) → void};
+    list.{core::List::removeLast}(){() → self::A};
+  }
+  on core::Object catch(final core::Object e) {
+    return;
+  }
+  throw "Expected subtype error";
+}
+static method main() → dynamic {
+  self::test(self::list1);
+  self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(self::list1);
+  core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect
new file mode 100644
index 0000000..f7b42fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+}
+static field core::List<core::int> intList;
+static field core::List<self::A> list1;
+static method test(core::List<self::A> list) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect
new file mode 100644
index 0000000..8d6c8ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+static field core::List<core::int> intList = core::_GrowableList::_literal2<core::int>(1, 2);
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+  try {
+    list.{core::List::add}(new self::A::•()){(self::A) → void};
+    list.{core::List::removeLast}(){() → self::A};
+  }
+  on core::Object catch(final core::Object e) {
+    return;
+  }
+  throw "Expected subtype error";
+}
+static method main() → dynamic {
+  self::test(self::list1);
+  self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(self::list1);
+  core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+  self::test(list2);
+  self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index f69a386..67fada2 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -141,8 +141,10 @@
             ..parent = syntheticConstructor)
       .toList();
 
-  initializersConstructor.add(SuperInitializer(superConstructor,
-      Arguments(superParameters.map((f) => VariableGet(f)).toList()))
+  initializersConstructor.add(SuperInitializer(
+      superConstructor,
+      Arguments(
+          superParameters.map<Expression>((f) => VariableGet(f)).toList()))
     ..parent = syntheticConstructor);
 
   syntheticConstructor.function.namedParameters
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 7a67f89..487d337 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -231,7 +231,9 @@
           _fixedLengthList(
               coreTypes,
               coreTypes.typeLegacyRawType,
-              arguments.types.map((t) => new TypeLiteral(t)).toList(),
+              arguments.types
+                  .map<Expression>((t) => new TypeLiteral(t))
+                  .toList(),
               arguments.fileOffset),
           _fixedLengthList(coreTypes, const DynamicType(), arguments.positional,
               arguments.fileOffset),
diff --git a/tools/VERSION b/tools/VERSION
index 543ed1f..710b49e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 38
+PRERELEASE 39
 PRERELEASE_PATCH 0
\ No newline at end of file