Version 2.18.0-274.0.dev

Merge commit 'bf19cfc8fe480308b1df8cdabecc5154298a935f' into 'dev'
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index cad822d..5cd9ec2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -51,7 +51,7 @@
   CompletionHandler(super.server, LspInitializationOptions options)
       : suggestFromUnimportedLibraries = options.suggestFromUnimportedLibraries,
         previewNotImportedCompletions = options.previewNotImportedCompletions {
-    final budgetMs = options.notImportedCompletionBudgetMilliseconds;
+    final budgetMs = options.completionBudgetMilliseconds;
     completionBudget = CompletionBudget(budgetMs != null
         ? Duration(milliseconds: budgetMs)
         : CompletionBudget.defaultDuration);
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 6a1cc96..fd36e21 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -892,7 +892,7 @@
   final bool closingLabels;
   final bool outline;
   final bool flutterOutline;
-  final int? notImportedCompletionBudgetMilliseconds;
+  final int? completionBudgetMilliseconds;
 
   LspInitializationOptions(dynamic options)
       : onlyAnalyzeProjectsWithOpenFiles = options != null &&
@@ -908,8 +908,8 @@
         closingLabels = options != null && options['closingLabels'] == true,
         outline = options != null && options['outline'] == true,
         flutterOutline = options != null && options['flutterOutline'] == true,
-        notImportedCompletionBudgetMilliseconds = options != null
-            ? options['notImportedCompletionBudgetMilliseconds'] as int?
+        completionBudgetMilliseconds = options != null
+            ? options['completionBudgetMilliseconds'] as int?
             : null;
 }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 44e901d..5a7c1e9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -1089,6 +1089,12 @@
     }
     super.visitForStatement(node);
   }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // Don't look inside function expressions as the presence of `await` inside
+    // a function expression does not mean the overall function is async.
+  }
 }
 
 class _HasReturnStatementVisitor extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 6eb8824..86f2b06 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -36,7 +36,7 @@
       'previewNotImportedCompletions': previewNotImportedCompletions,
       // Default to a high budget for tests because everything is cold and
       // may take longer to return.
-      'notImportedCompletionBudgetMilliseconds': 50000
+      'completionBudgetMilliseconds': 50000
     };
   }
 
@@ -2305,7 +2305,7 @@
         initializationOptions: {
           ...?defaultInitializationOptions,
           // Set budget high to ensure it completes.
-          'notImportedCompletionBudgetMilliseconds': 100000,
+          'completionBudgetMilliseconds': 100000,
         },
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -2330,7 +2330,7 @@
         initializationOptions: {
           ...?defaultInitializationOptions,
           // Set budget low to ensure we don't complete.
-          'notImportedCompletionBudgetMilliseconds': 0,
+          'completionBudgetMilliseconds': 0,
         },
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index b6ae4c4..35cf422 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -2561,6 +2561,37 @@
 ''');
   }
 
+  /// `await` in a nested function should not result in `await` at the call to
+  /// the new function.
+  Future<void> test_statements_hasAwait_functionExpression() async {
+    await indexTestUnit('''
+void g(Future<void> Function() func) {}
+void f() {
+// start
+  g(() async {
+    await null;
+  });
+// end
+}
+''');
+    _createRefactoringForStartEndComments();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+void g(Future<void> Function() func) {}
+void f() {
+// start
+  res();
+// end
+}
+
+void res() {
+  g(() async {
+    await null;
+  });
+}
+''');
+  }
+
   Future<void> test_statements_hasAwait_voidReturnType() async {
     await indexTestUnit('''
 import 'dart:async';
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index ed10dc8..fbfd6cd 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -453,7 +453,7 @@
       Object allocationNode,
       MemberEntity allocationElement,
       AbstractValue elementType,
-      int length);
+      int? length);
 
   /// Returns the element type of [value] if it represents a container value
   /// at runtime. Returns [dynamicType] otherwise.
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
index 80bb03c..6eb60d8 100644
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ b/pkg/compiler/lib/src/inferrer/builder.dart
@@ -287,8 +287,7 @@
       } else {
         type = _types.nullType;
       }
-      _inferrer.setDefaultTypeOfParameter(local, type,
-          isInstanceMember: _analyzedMember.isInstanceMember);
+      _inferrer.setDefaultTypeOfParameter(local, type);
     }
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/engine.dart b/pkg/compiler/lib/src/inferrer/engine.dart
index 9e9a8d9..6cae1c6 100644
--- a/pkg/compiler/lib/src/inferrer/engine.dart
+++ b/pkg/compiler/lib/src/inferrer/engine.dart
@@ -33,6 +33,7 @@
 import 'builder.dart';
 import 'closure_tracer.dart';
 import 'debug.dart' as debug;
+import 'engine_interfaces.dart' as interfaces;
 import 'locals_handler.dart';
 import 'list_tracer.dart';
 import 'map_tracer.dart';
@@ -46,7 +47,7 @@
 /// An inferencing engine that computes a call graph of [TypeInformation] nodes
 /// by visiting the AST of the application, and then does the inferencing on the
 /// graph.
-class InferrerEngine {
+class InferrerEngine implements interfaces.InferrerEngine {
   /// A set of selector names that [List] implements, that we know return their
   /// element type.
   final Set<Selector> returnsListElementTypeSet = Set<Selector>.from(<Selector>[
@@ -61,13 +62,16 @@
   ]);
 
   /// The [JClosedWorld] on which inference reasoning is based.
+  @override
   final JsClosedWorld closedWorld;
 
   final TypeSystem types;
   final Map<ir.TreeNode, TypeInformation> concreteTypes = {};
   final GlobalLocalsMap globalLocalsMap;
+  @override
   final InferredDataBuilder inferredDataBuilder;
 
+  @override
   final FunctionEntity mainElement;
 
   final Map<Local, TypeInformation> _defaultTypeOfParameter = {};
@@ -101,12 +105,15 @@
 
   ElementEnvironment get _elementEnvironment => closedWorld.elementEnvironment;
 
+  @override
   AbstractValueDomain get abstractValueDomain =>
       closedWorld.abstractValueDomain;
+  @override
   CommonElements get commonElements => closedWorld.commonElements;
 
   // TODO(johnniwinther): This should be part of [ClosedWorld] or
   // [ClosureWorldRefiner].
+  @override
   NoSuchMethodData get noSuchMethodData => closedWorld.noSuchMethodData;
 
   InferrerEngine(
@@ -241,14 +248,17 @@
     }
   }
 
+  @override
   bool returnsListElementType(Selector selector, AbstractValue mask) {
-    return mask != null &&
-        abstractValueDomain.isContainer(mask) &&
+    assert(mask != null);
+    return abstractValueDomain.isContainer(mask) &&
         returnsListElementTypeSet.contains(selector);
   }
 
+  @override
   bool returnsMapValueType(Selector selector, AbstractValue mask) {
-    return mask != null && abstractValueDomain.isMap(mask) && selector.isIndex;
+    assert(mask != null);
+    return abstractValueDomain.isMap(mask) && selector.isIndex;
   }
 
   void analyzeListAndEnqueue(ListTypeInformation info) {
@@ -813,8 +823,7 @@
   /// mapping in `_defaultTypeOfParameter` already contains a type, it must be
   /// a [PlaceholderTypeInformation], which will be replaced. All its uses are
   /// updated.
-  void setDefaultTypeOfParameter(Local parameter, TypeInformation type,
-      {bool isInstanceMember}) {
+  void setDefaultTypeOfParameter(Local parameter, TypeInformation type) {
     assert(
         type != null, failedAt(parameter, "No default type for $parameter."));
     TypeInformation existing = _defaultTypeOfParameter[parameter];
@@ -822,17 +831,7 @@
     TypeInformation info = types.getInferredTypeOfParameter(parameter);
     if (existing != null && existing is PlaceholderTypeInformation) {
       // Replace references to [existing] to use [type] instead.
-      if (isInstanceMember) {
-        ParameterInputs inputs = info.inputs;
-        inputs.replace(existing, type);
-      } else {
-        List<TypeInformation> inputs = info.inputs;
-        for (int i = 0; i < inputs.length; i++) {
-          if (inputs[i] == existing) {
-            inputs[i] = type;
-          }
-        }
-      }
+      info.inputs.replace(existing, type);
       // Also forward all users.
       type.addUsersOf(existing);
     } else {
@@ -1290,8 +1289,13 @@
       return ParameterTypeInformation.localFunction(
           abstractValueDomain, memberTypeInformation, parameter, type, member);
     } else if (member.isInstanceMember) {
-      return ParameterTypeInformation.instanceMember(abstractValueDomain,
-          memberTypeInformation, parameter, type, member, ParameterInputs());
+      return ParameterTypeInformation.instanceMember(
+          abstractValueDomain,
+          memberTypeInformation,
+          parameter,
+          type,
+          member,
+          ParameterInputs.instanceMember());
     } else {
       return ParameterTypeInformation.static(
           abstractValueDomain, memberTypeInformation, parameter, type, member);
diff --git a/pkg/compiler/lib/src/inferrer/engine_interfaces.dart b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
new file mode 100644
index 0000000..80c7d3e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
@@ -0,0 +1,23 @@
+// 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 '../common/elements.dart';
+import '../elements/entities.dart';
+import '../js_backend/inferred_data.dart';
+import '../js_backend/no_such_method_registry_interfaces.dart';
+import '../universe/selector.dart';
+import '../world_interfaces.dart';
+import 'abstract_value_domain.dart';
+
+abstract class InferrerEngine {
+  AbstractValueDomain get abstractValueDomain;
+  JClosedWorld get closedWorld;
+  CommonElements get commonElements;
+  InferredDataBuilder get inferredDataBuilder;
+  FunctionEntity get mainElement;
+  NoSuchMethodData get noSuchMethodData;
+
+  bool returnsListElementType(Selector selector, AbstractValue mask);
+  bool returnsMapValueType(Selector selector, AbstractValue mask);
+}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index ea0f69f..8f28c04 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -39,7 +39,7 @@
 /// changes.
 abstract class TypeInformation {
   Set<TypeInformation> users;
-  var /* List|ParameterInputs */ _inputs;
+  ParameterInputs _inputs;
 
   /// The type the inferrer has found for this [TypeInformation].
   /// Initially empty.
@@ -51,7 +51,7 @@
   /// The element this [TypeInformation] node belongs to.
   MemberEntity get contextMember => context?.member;
 
-  Iterable<TypeInformation> get inputs => _inputs;
+  ParameterInputs get inputs => _inputs;
 
   /// We abandon inference in certain cases (complex cyclic flow, native
   /// behaviours, etc.). In some case, we might resume inference in the
@@ -86,15 +86,15 @@
   bool get isConcrete => false;
 
   TypeInformation(this.type, this.context)
-      : _inputs = <TypeInformation>[],
+      : _inputs = _BasicParameterInputs([]),
         users = Setlet<TypeInformation>();
 
   TypeInformation.noInputs(this.type, this.context)
-      : _inputs = const <TypeInformation>[],
+      : _inputs = const _BasicParameterInputs([]),
         users = Setlet<TypeInformation>();
 
   TypeInformation.untracked(this.type)
-      : _inputs = const <TypeInformation>[],
+      : _inputs = const _BasicParameterInputs([]),
         users = const {},
         context = null;
 
@@ -118,7 +118,7 @@
   // The below is not a compile time constant to make it differentiable
   // from other empty lists of [TypeInformation].
   static final STOP_TRACKING_INPUTS_MARKER =
-      List<TypeInformation>.filled(0, null);
+      _BasicParameterInputs(List.empty());
 
   bool areInputsTracked() {
     return inputs != STOP_TRACKING_INPUTS_MARKER;
@@ -220,8 +220,8 @@
 
   /// Destroys information not needed after type inference.
   void cleanup() {
-    users = null;
-    _inputs = null;
+    users = const {};
+    _inputs = const _BasicParameterInputs([]);
   }
 
   String toStructuredText(String indent) {
@@ -265,16 +265,50 @@
   toString() => "Placeholder [$hashCode]";
 }
 
+abstract class ParameterInputs implements Iterable<TypeInformation> {
+  factory ParameterInputs.instanceMember() => _InstanceMemberParameterInputs();
+  void add(TypeInformation input);
+  void remove(TypeInformation input);
+  void replace(TypeInformation old, TypeInformation replacement);
+}
+
+class _BasicParameterInputs extends IterableBase<TypeInformation>
+    implements ParameterInputs {
+  final List<TypeInformation> _baseList;
+
+  const _BasicParameterInputs(this._baseList);
+
+  @override
+  void replace(TypeInformation old, TypeInformation replacement) {
+    for (int i = 0; i < length; i++) {
+      if (_baseList[i] == old) {
+        _baseList[i] = replacement;
+      }
+    }
+  }
+
+  @override
+  void add(TypeInformation input) => _baseList.add(input);
+
+  @override
+  Iterator<TypeInformation> get iterator => _baseList.iterator;
+
+  @override
+  void remove(TypeInformation input) => _baseList.remove(input);
+}
+
 /// Parameters of instance functions behave differently than other
 /// elements because the inferrer may remove inputs. This happens
 /// when the receiver of a dynamic call site can be refined
 /// to a type where we know more about which instance method is being
 /// called.
-class ParameterInputs extends IterableBase<TypeInformation> {
+class _InstanceMemberParameterInputs extends IterableBase<TypeInformation>
+    implements ParameterInputs {
   final Map<TypeInformation, int> _inputs = Map<TypeInformation, int>();
 
+  @override
   void remove(TypeInformation info) {
-    int existing = _inputs[info];
+    final existing = _inputs[info];
     if (existing == null) return;
     if (existing == 1) {
       _inputs.remove(info);
@@ -283,8 +317,9 @@
     }
   }
 
+  @override
   void add(TypeInformation info) {
-    int existing = _inputs[info];
+    final existing = _inputs[info];
     if (existing == null) {
       _inputs[info] = 1;
     } else {
@@ -292,10 +327,11 @@
     }
   }
 
+  @override
   void replace(TypeInformation old, TypeInformation replacement) {
-    int existing = _inputs[old];
+    var existing = _inputs[old];
     if (existing != null) {
-      int other = _inputs[replacement];
+      final other = _inputs[replacement];
       if (other != null) existing += other;
       _inputs[replacement] = existing;
       _inputs.remove(old);
@@ -383,13 +419,11 @@
   /// This map contains the callers of [element]. It stores all unique call
   /// sites to enable counting the global number of call sites of [element].
   ///
-  /// A call site is either an AST [ast.Node], an [Element] (see uses of
-  /// [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]) or an IR
-  /// [ir.Node].
+  /// A call site is an [ir.Node].
   ///
   /// The global information is summarized in [cleanup], after which [_callers]
   /// is set to `null`.
-  Map<MemberEntity, Setlet<Object>> _callers;
+  Map<MemberEntity, Setlet<ir.Node /*?*/ >> _callers;
 
   MemberTypeInformation._internal(
       AbstractValueDomain abstractValueDomain, this._member)
@@ -400,12 +434,12 @@
   @override
   String get debugName => '$member';
 
-  void addCall(MemberEntity caller, Object node) {
-    _callers ??= <MemberEntity, Setlet<Object>>{};
+  void addCall(MemberEntity caller, ir.Node /*?*/ node) {
+    _callers ??= <MemberEntity, Setlet<ir.Node /*?*/ >>{};
     _callers.putIfAbsent(caller, () => Setlet()).add(node);
   }
 
-  void removeCall(MemberEntity caller, Object node) {
+  void removeCall(MemberEntity caller, ir.Node /*?*/ node) {
     if (_callers == null) return;
     Setlet calls = _callers[caller];
     if (calls == null) return;
@@ -919,7 +953,7 @@
   forIn,
 }
 
-bool validCallType(CallType callType, Object call, Selector selector) {
+bool validCallType(CallType callType, ir.Node /*?*/ call, Selector selector) {
   switch (callType) {
     case CallType.access:
       return call is ir.Node;
@@ -941,7 +975,7 @@
 /// and [selector] and [receiver] fields for dynamic calls.
 abstract class CallSiteTypeInformation extends TypeInformation
     with ApplyableTypeInformation {
-  final Object _call;
+  final ir.Node /*?*/ _call;
   final MemberEntity caller;
   final Selector selector;
   final ArgumentsTypes arguments;
@@ -977,7 +1011,7 @@
   StaticCallSiteTypeInformation(
       AbstractValueDomain abstractValueDomain,
       MemberTypeInformation context,
-      Object call,
+      ir.Node /*?*/ call,
       MemberEntity enclosing,
       this.calledElement,
       Selector selector,
@@ -1073,7 +1107,7 @@
   IndirectDynamicCallSiteTypeInformation(
       AbstractValueDomain abstractValueDomain,
       MemberTypeInformation context,
-      Object call,
+      ir.Node /*?*/ call,
       this.dynamicCall,
       MemberEntity enclosing,
       Selector selector,
@@ -1157,7 +1191,8 @@
   }
 }
 
-class DynamicCallSiteTypeInformation<T> extends CallSiteTypeInformation {
+class DynamicCallSiteTypeInformation<T extends ir.Node>
+    extends CallSiteTypeInformation {
   final CallType _callType;
   final TypeInformation receiver;
   final AbstractValue mask;
@@ -1407,9 +1442,11 @@
     } else {
       result = inferrer.types
           .joinTypeMasks(_concreteTargets.map((MemberEntity element) {
-        if (inferrer.returnsListElementType(selector, typeMask)) {
+        if (typeMask != null &&
+            inferrer.returnsListElementType(selector, typeMask)) {
           return abstractValueDomain.getContainerElementType(receiver.type);
-        } else if (inferrer.returnsMapValueType(selector, typeMask)) {
+        } else if (typeMask != null &&
+            inferrer.returnsMapValueType(selector, typeMask)) {
           if (abstractValueDomain.isDictionary(typeMask)) {
             AbstractValue arg = arguments.positional[0].type;
             ConstantValue value = abstractValueDomain.getPrimitiveValue(arg);
@@ -1513,7 +1550,7 @@
   ClosureCallSiteTypeInformation(
       AbstractValueDomain abstractValueDomain,
       MemberTypeInformation context,
-      Object call,
+      ir.Node /*?*/ call,
       MemberEntity enclosing,
       Selector selector,
       this.closure,
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 88afdee..26e081e 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -11,6 +11,7 @@
 import '../inferrer/types.dart' show GlobalTypeInferenceResults;
 import '../kernel/no_such_method_resolver.dart';
 import '../serialization/serialization.dart';
+import 'no_such_method_registry_interfaces.dart' as interfaces;
 
 /// [NoSuchMethodRegistry] and [NoSuchMethodData] categorizes `noSuchMethod`
 /// implementations.
@@ -169,7 +170,7 @@
 ///
 /// Post inference collected category `D` methods are into subcategories `D1`
 /// and `D2`.
-class NoSuchMethodData {
+class NoSuchMethodData implements interfaces.NoSuchMethodData {
   /// Tag used for identifying serialized [NoSuchMethodData] objects in a
   /// debugging data stream.
   static const String tag = 'no-such-method-data';
@@ -266,6 +267,7 @@
   /// Returns [true] if the given element is a complex [noSuchMethod]
   /// implementation. An implementation is complex if it falls into
   /// category D, as described above.
+  @override
   bool isComplex(FunctionEntity element) {
     assert(element.name == Identifiers.noSuchMethod_);
     return _otherImpls.contains(element);
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart
new file mode 100644
index 0000000..30e7dc3
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart
@@ -0,0 +1,9 @@
+// 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 '../elements/entities.dart';
+
+abstract class NoSuchMethodData {
+  bool isComplex(FunctionEntity element);
+}
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index afdce46..6d039aa 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -485,14 +485,14 @@
 
   @override
   Iterable<MemberEntity> locateMembersInDomain(Selector selector,
-      AbstractValue receiver, AbstractValueDomain abstractValueDomain) {
+      AbstractValue /*?*/ receiver, AbstractValueDomain abstractValueDomain) {
     _ensureFunctionSet();
     return _allFunctions.filter(selector, receiver, abstractValueDomain);
   }
 
   @override
   Iterable<MemberEntity> locateMembers(
-      Selector selector, AbstractValue receiver) {
+      Selector selector, AbstractValue /*?*/ receiver) {
     return locateMembersInDomain(selector, receiver, abstractValueDomain);
   }
 
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 2c723a3..17b39ec 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -40,7 +40,7 @@
   /// noSuchMethod handlers that are potential targets indirectly through the
   /// noSuchMethod mechanism.
   Iterable<MemberEntity> filter(
-      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+      Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
     return query(selector, receiver, domain).functions;
   }
 
@@ -66,7 +66,7 @@
   /// [selector] on a receiver constrained by [constraint] including
   /// 'noSuchMethod' methods where applicable.
   FunctionSetQuery query(
-      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+      Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
     String name = selector.name;
     SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
     SelectorMask noSuchMethodMask =
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 01cd61c..884cef6 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -43,17 +43,21 @@
 
   BackendUsage get backendUsage;
 
+  @override
   NativeData get nativeData;
 
   InterceptorData get interceptorData;
 
   JElementEnvironment get elementEnvironment;
 
+  @override
   DartTypes get dartTypes;
 
+  @override
   JCommonElements get commonElements;
 
   /// Returns the [AbstractValueDomain] used in the global type inference.
+  @override
   AbstractValueDomain get abstractValueDomain;
 
   RuntimeTypesNeed get rtiNeed;
@@ -68,8 +72,10 @@
   /// `extractTypeArguments` function.
   Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
 
+  @override
   ClassHierarchy get classHierarchy;
 
+  @override
   AnnotationsData get annotationsData;
 
   ClosureData get closureDataLookup;
diff --git a/pkg/compiler/lib/src/world_interfaces.dart b/pkg/compiler/lib/src/world_interfaces.dart
index 86535bf..84c1a9d 100644
--- a/pkg/compiler/lib/src/world_interfaces.dart
+++ b/pkg/compiler/lib/src/world_interfaces.dart
@@ -2,16 +2,27 @@
 // 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 'common/elements.dart';
 import 'elements/entities.dart';
+import 'elements/types.dart';
 import 'inferrer/abstract_value_domain.dart';
+import 'js_backend/annotations.dart';
+import 'js_backend/native_data.dart';
+import 'universe/class_hierarchy.dart';
 import 'universe/selector.dart';
 
 /// Common superinterface for [OpenWorld] and [JClosedWorld].
 abstract class World {}
 
 abstract class JClosedWorld implements World {
-  bool includesClosureCall(Selector selector, AbstractValue receiver);
+  AbstractValueDomain get abstractValueDomain;
+  JCommonElements get commonElements;
+  ClassHierarchy get classHierarchy;
+  DartTypes get dartTypes;
+  NativeData get nativeData;
+  AnnotationsData get annotationsData;
+  bool includesClosureCall(Selector selector, AbstractValue? receiver);
   Iterable<MemberEntity> locateMembers(
-      Selector selector, AbstractValue receiver);
+      Selector selector, AbstractValue? receiver);
   bool fieldNeverChanges(MemberEntity element);
 }
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 5d8fd47..107ef15 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -34,9 +34,7 @@
     "Dynamic invocation of '[]'.": 2
   },
   "pkg/compiler/lib/src/inferrer/type_graph_nodes.dart": {
-    "Dynamic access of 'type'.": 4,
-    "Dynamic invocation of 'add'.": 1,
-    "Dynamic invocation of 'remove'.": 1
+    "Dynamic access of 'type'.": 4
   },
   "pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart": {
     "Dynamic access of 'forwardTo'.": 1,
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index 2d8e15c..043138d 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -15,8 +15,9 @@
 /// {@category Core}
 library dart.developer;
 
-import "dart:_internal" show checkNotNullable;
+import 'dart:_internal' show checkNotNullable;
 import 'dart:async';
+import 'dart:collection';
 import 'dart:convert';
 import 'dart:isolate' show Isolate, RawReceivePort, SendPort;
 
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
index f238ae8..54bfd25 100644
--- a/sdk/lib/developer/profiler.dart
+++ b/sdk/lib/developer/profiler.dart
@@ -109,6 +109,9 @@
 }
 
 class Metrics {
+  /// The current set of registered [Metric]s.
+  static UnmodifiableMapView<String, Metric> get current =>
+      UnmodifiableMapView<String, Metric>(_metrics);
   static final Map<String, Metric> _metrics = new Map<String, Metric>();
 
   /// Register [Metric]s to make them visible to Observatory.
diff --git a/tests/lib/developer/metrics_test.dart b/tests/lib/developer/metrics_test.dart
index c836e96..9e5f80a 100644
--- a/tests/lib/developer/metrics_test.dart
+++ b/tests/lib/developer/metrics_test.dart
@@ -93,6 +93,8 @@
   Metrics.register(counter);
   var counter3 = new Counter('a.b.c.d', '');
   Metrics.register(counter3);
+  Expect.isTrue(Metrics.current.containsKey('a.b.c.d'));
+  Expect.isTrue(Metrics.current.containsKey('a.b.c'));
 }
 
 testBadName() {
diff --git a/tests/lib_2/developer/metrics_test.dart b/tests/lib_2/developer/metrics_test.dart
index e91d3c2..8c529ea 100644
--- a/tests/lib_2/developer/metrics_test.dart
+++ b/tests/lib_2/developer/metrics_test.dart
@@ -95,6 +95,8 @@
   Metrics.register(counter);
   var counter3 = new Counter('a.b.c.d', '');
   Metrics.register(counter3);
+  Expect.isTrue(Metrics.current.containsKey('a.b.c.d'));
+  Expect.isTrue(Metrics.current.containsKey('a.b.c'));
 }
 
 testBadName() {
diff --git a/tools/VERSION b/tools/VERSION
index e0bb2d6..2c1d3fb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 273
+PRERELEASE 274
 PRERELEASE_PATCH 0
\ No newline at end of file