Version 2.14.0-212.0.dev

Merge commit '8157e3a147ccf0fa87e0a70f26a84be7ced8d975' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 93ba1d7..baa2b14 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-05-24T09:58:37.618570",
+  "generated": "2021-06-07T10:25:46.125579",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
diff --git a/DEPS b/DEPS
index 1c57415..9e9e23d 100644
--- a/DEPS
+++ b/DEPS
@@ -156,7 +156,7 @@
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
   "source_span_rev": "1be3c44045a06dff840d2ed3a13e6082d7a03a23",
-  "sse_tag": "adc3ac8027784ed9783d066dccadad44458788e4",
+  "sse_tag": "d505b383768889a1e3e90097684e929a9e6d6b8f",
   "stack_trace_tag": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
   "stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
   "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 2da1246..4882359 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -5,133 +5,14 @@
 import 'dart:collection';
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 
 /// Callback used by [ReferenceFinder] to report that a dependency was found.
 typedef ReferenceFinderCallback = void Function(
     ConstantEvaluationTarget dependency);
 
-/// An [AstCloner] that copies the necessary information from the AST to allow
-/// constants to be evaluated.
-class ConstantAstCloner extends AstCloner {
-  ConstantAstCloner() : super(true);
-
-  @override
-  AnnotationImpl visitAnnotation(Annotation node) {
-    var annotation = super.visitAnnotation(node);
-    annotation.element = node.element;
-    return annotation;
-  }
-
-  @override
-  ConstructorNameImpl visitConstructorName(ConstructorName node) {
-    var name = super.visitConstructorName(node);
-    name.staticElement = node.staticElement;
-    return name;
-  }
-
-  @override
-  FunctionExpression visitFunctionExpression(FunctionExpression node) {
-    var expression =
-        super.visitFunctionExpression(node) as FunctionExpressionImpl;
-    expression.declaredElement = node.declaredElement;
-    return expression;
-  }
-
-  @override
-  InstanceCreationExpressionImpl visitInstanceCreationExpression(
-      InstanceCreationExpression node) {
-    var expression = super.visitInstanceCreationExpression(node);
-    if (node.keyword == null) {
-      if (node.isConst) {
-        expression.keyword = KeywordToken(Keyword.CONST, node.offset);
-      } else {
-        expression.keyword = KeywordToken(Keyword.NEW, node.offset);
-      }
-    }
-    return expression;
-  }
-
-  @override
-  IntegerLiteralImpl visitIntegerLiteral(IntegerLiteral node) {
-    var integer = super.visitIntegerLiteral(node);
-    integer.staticType = node.staticType;
-    return integer;
-  }
-
-  @override
-  ListLiteralImpl visitListLiteral(ListLiteral node) {
-    var literal = super.visitListLiteral(node);
-    literal.staticType = node.staticType;
-    if (node.constKeyword == null && node.isConst) {
-      literal.constKeyword = KeywordToken(Keyword.CONST, node.offset);
-    }
-    return literal;
-  }
-
-  @override
-  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
-    var copy = super.visitPrefixedIdentifier(node) as PrefixedIdentifierImpl;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  PropertyAccess visitPropertyAccess(PropertyAccess node) {
-    var copy = super.visitPropertyAccess(node) as PropertyAccessImpl;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  RedirectingConstructorInvocationImpl visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var invocation = super.visitRedirectingConstructorInvocation(node);
-    invocation.staticElement = node.staticElement;
-    return invocation;
-  }
-
-  @override
-  SetOrMapLiteralImpl visitSetOrMapLiteral(SetOrMapLiteral node) {
-    var literal = super.visitSetOrMapLiteral(node);
-    literal.staticType = node.staticType;
-    if (node.constKeyword == null && node.isConst) {
-      literal.constKeyword = KeywordToken(Keyword.CONST, node.offset);
-    }
-    return literal;
-  }
-
-  @override
-  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
-    var copy = super.visitSimpleIdentifier(node) as SimpleIdentifierImpl;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    copy.tearOffTypeArgumentTypes = node.tearOffTypeArgumentTypes;
-    return copy;
-  }
-
-  @override
-  SuperConstructorInvocationImpl visitSuperConstructorInvocation(
-      SuperConstructorInvocation node) {
-    var invocation = super.visitSuperConstructorInvocation(node);
-    invocation.staticElement = node.staticElement;
-    return invocation;
-  }
-
-  @override
-  TypeNameImpl visitTypeName(TypeName node) {
-    var typeName = super.visitTypeName(node);
-    typeName.type = node.type;
-    return typeName;
-  }
-}
-
 /// A visitor used to traverse the AST structures of all of the compilation
 /// units being resolved and build the full set of dependencies for all constant
 /// expressions.
diff --git a/pkg/compiler/lib/src/js/size_estimator.dart b/pkg/compiler/lib/src/js/size_estimator.dart
index 0b38f43..5af9fc1 100644
--- a/pkg/compiler/lib/src/js/size_estimator.dart
+++ b/pkg/compiler/lib/src/js/size_estimator.dart
@@ -449,9 +449,7 @@
         (newAtStatementBegin &&
             (node is NamedFunction ||
                 node is FunctionExpression ||
-                node is ObjectInitializer)) ||
-        // (() => x)()
-        (requiredPrecedence == CALL && node is ArrowFunction);
+                node is ObjectInitializer));
     if (needsParentheses) {
       inForInit = false;
       atStatementBegin = false;
@@ -1016,6 +1014,7 @@
 
   @override
   void visitMethodDefinition(MethodDefinition node) {
+    propertyNameOut(node);
     VarCollector vars = new VarCollector();
     vars.visitMethodDefinition(node);
     methodOut(node, vars);
@@ -1023,7 +1022,6 @@
 
   int methodOut(MethodDefinition node, VarCollector vars) {
     // TODO: support static, get/set, async, and generators.
-    propertyNameOut(node);
     Fun fun = node.function;
     out("(");
     if (fun.params != null) {
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index 5398071..004132a 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -9,6 +9,7 @@
 import '../js/js.dart' as js;
 import '../serialization/serialization.dart';
 import '../util/util.dart';
+import '../js_emitter/model.dart' show Fragment;
 
 import 'namer.dart';
 
@@ -17,7 +18,7 @@
 // for the entity referenced in the DeferredHolderExpression.
 enum DeferredHolderExpressionKind {
   globalObjectForStaticState,
-  globalObjectForConstants,
+  globalObjectForConstant,
   globalObjectForLibrary,
   globalObjectForClass,
   globalObjectForMember,
@@ -34,19 +35,15 @@
   static const String tag = 'deferred-holder-expression';
 
   final DeferredHolderExpressionKind kind;
-  final Entity entity;
+  final Object data;
   js.Expression _value;
 
   @override
   final js.JavaScriptNodeSourceInformation sourceInformation;
 
-  DeferredHolderExpression(this.kind, this.entity) : sourceInformation = null;
+  DeferredHolderExpression(this.kind, this.data) : sourceInformation = null;
   DeferredHolderExpression._(
-      this.kind, this.entity, this._value, this.sourceInformation);
-  factory DeferredHolderExpression.forConstants() {
-    return DeferredHolderExpression(
-        DeferredHolderExpressionKind.globalObjectForConstants, null);
-  }
+      this.kind, this.data, this._value, this.sourceInformation);
 
   factory DeferredHolderExpression.forStaticState() {
     return DeferredHolderExpression(
@@ -56,24 +53,26 @@
   factory DeferredHolderExpression.readFromDataSource(DataSource source) {
     source.begin(tag);
     var kind = source.readEnum(DeferredHolderExpressionKind.values);
-    Entity entity;
+    Object data;
     switch (kind) {
       case DeferredHolderExpressionKind.globalObjectForLibrary:
-        entity = source.readLibrary();
+        data = source.readLibrary();
         break;
       case DeferredHolderExpressionKind.globalObjectForClass:
-        entity = source.readClass();
+        data = source.readClass();
         break;
       case DeferredHolderExpressionKind.globalObjectForMember:
-        entity = source.readMember();
+        data = source.readMember();
+        break;
+      case DeferredHolderExpressionKind.globalObjectForConstant:
+        data = source.readConstant();
         break;
       case DeferredHolderExpressionKind.globalObjectForStaticState:
-      case DeferredHolderExpressionKind.globalObjectForConstants:
         // no entity.
         break;
     }
     source.end(tag);
-    return DeferredHolderExpression(kind, entity);
+    return DeferredHolderExpression(kind, data);
   }
 
   void writeToDataSink(DataSink sink) {
@@ -81,16 +80,18 @@
     sink.writeEnum(kind);
     switch (kind) {
       case DeferredHolderExpressionKind.globalObjectForLibrary:
-        sink.writeLibrary(entity);
+        sink.writeLibrary(data);
         break;
       case DeferredHolderExpressionKind.globalObjectForClass:
-        sink.writeClass(entity);
+        sink.writeClass(data);
         break;
       case DeferredHolderExpressionKind.globalObjectForMember:
-        sink.writeMember(entity);
+        sink.writeMember(data);
+        break;
+      case DeferredHolderExpressionKind.globalObjectForConstant:
+        sink.writeConstant(data);
         break;
       case DeferredHolderExpressionKind.globalObjectForStaticState:
-      case DeferredHolderExpressionKind.globalObjectForConstants:
         // no entity.
         break;
     }
@@ -116,8 +117,7 @@
       js.JavaScriptNodeSourceInformation newSourceInformation) {
     if (newSourceInformation == sourceInformation) return this;
     if (newSourceInformation == null) return this;
-    return DeferredHolderExpression._(
-        kind, entity, _value, newSourceInformation);
+    return DeferredHolderExpression._(kind, data, _value, newSourceInformation);
   }
 
   @override
@@ -125,7 +125,7 @@
 
   @override
   int get hashCode {
-    return Hashing.objectsHash(kind, entity);
+    return Hashing.objectsHash(kind, data);
   }
 
   @override
@@ -133,13 +133,13 @@
     if (identical(this, other)) return true;
     return other is DeferredHolderExpression &&
         kind == other.kind &&
-        entity == other.entity;
+        data == other.data;
   }
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('DeferredHolderExpression(kind=$kind,entity=$entity,');
+    StringBuffer sb = StringBuffer();
+    sb.write('DeferredHolderExpression(kind=$kind,data=$data,');
     sb.write('value=$_value)');
     return sb.toString();
   }
@@ -205,40 +205,43 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('DeferredHolderParameter(name=$_name)');
     return sb.toString();
   }
 }
 
 enum DeferredHolderResourceKind {
-  declaration,
-  update,
+  mainFragment,
+  deferredFragment,
 }
 
 /// A [DeferredHolderResource] is a deferred JavaScript statement determined by
-/// the finalization of holders. It is the injection point for data or
-/// code to holders. The actual [Statement] contained with the
+/// the finalization of holders. Each fragment contains one
+/// [DeferredHolderResource]. The actual [Statement] contained with the
 /// [DeferredHolderResource] will be determined by the
 /// [DeferredHolderResourceKind]. These [Statement]s differ considerably
-/// depending on where they are used in the AST. This class does not support
-/// serialization.
+/// depending on where they are used in the AST. This class is created by the
+/// fragment emitter so does not need to support serialization.
 class DeferredHolderResource extends js.DeferredStatement
     implements js.AstContainer {
   DeferredHolderResourceKind kind;
+  // Each resource has a distinct name.
+  String name;
+  List<Fragment> fragments;
   Map<Entity, List<js.Property>> holderCode;
-  bool initializeEmptyHolders;
   js.Statement _statement;
 
   @override
   final js.JavaScriptNodeSourceInformation sourceInformation;
 
-  DeferredHolderResource(this.kind,
-      {this.holderCode: const {}, this.initializeEmptyHolders: false})
+  DeferredHolderResource(this.kind, this.name, this.fragments, this.holderCode)
       : sourceInformation = null;
 
-  DeferredHolderResource._(this.kind, this.holderCode,
-      this.initializeEmptyHolders, this._statement, this.sourceInformation);
+  DeferredHolderResource._(this.kind, this.name, this.fragments,
+      this.holderCode, this._statement, this.sourceInformation);
+
+  bool get isMainFragment => kind == DeferredHolderResourceKind.mainFragment;
 
   set statement(js.Statement statement) {
     assert(!isFinalized && statement != null);
@@ -259,7 +262,7 @@
       js.JavaScriptNodeSourceInformation newSourceInformation) {
     if (newSourceInformation == sourceInformation) return this;
     if (newSourceInformation == null) return this;
-    return DeferredHolderResource._(kind, holderCode, initializeEmptyHolders,
+    return DeferredHolderResource._(kind, this.name, this.fragments, holderCode,
         _statement, newSourceInformation);
   }
 
@@ -277,14 +280,66 @@
   }
 }
 
+const String mainResourceName = 'MAIN';
+
 abstract class DeferredHolderExpressionFinalizer {
   /// Collects DeferredHolderExpressions from the JavaScript
-  /// AST [code];
-  void addCode(js.Node code);
+  /// AST [code] and associates it with [resourceName].
+  void addCode(String resourceName, js.Node code);
 
   /// Performs analysis on all collected DeferredHolderExpression nodes
   /// finalizes the values to expressions to access the holders.
   void finalize();
+
+  /// The below registration functions are for use only by the visitor.
+  void registerDeferredHolderExpression(
+      String resourceName, DeferredHolderExpression node);
+  void registerDeferredHolderResource(DeferredHolderResource node);
+  void registerDeferredHolderParameter(DeferredHolderParameter node);
+}
+
+/// An abstraction representing a [Holder] object, which will contain some
+/// portion of the programs code.
+class Holder {
+  final String name;
+  final Map<String, int> refCountPerResource = {};
+  final Map<String, List<js.Property>> propertiesPerResource = {};
+  int _index;
+  int _hashCode;
+
+  Holder(this.name);
+
+  int refCount(String resource) => refCountPerResource[resource];
+
+  void registerUse(String resource) {
+    refCountPerResource.update(resource, (count) => count + 1,
+        ifAbsent: () => 0);
+  }
+
+  void registerUpdate(String resource, List<js.Property> properties) {
+    (propertiesPerResource[resource] ??= []).addAll(properties);
+    registerUse(resource);
+  }
+
+  int get index {
+    assert(_index != null);
+    return _index;
+  }
+
+  set index(int newIndex) {
+    assert(_index == null);
+    _index = newIndex;
+  }
+
+  @override
+  bool operator ==(that) {
+    return that is Holder && name == that.name;
+  }
+
+  @override
+  int get hashCode {
+    return _hashCode ??= Hashing.objectsHash(name);
+  }
 }
 
 /// [DeferredHolderExpressionFinalizerImpl] finalizes
@@ -293,6 +348,418 @@
 class DeferredHolderExpressionFinalizerImpl
     implements DeferredHolderExpressionFinalizer {
   _DeferredHolderExpressionCollectorVisitor _visitor;
+  final Map<String, List<DeferredHolderExpression>> holderReferences = {};
+  final List<DeferredHolderParameter> holderParameters = [];
+  final List<DeferredHolderResource> holderResources = [];
+  final Map<String, Set<Holder>> holdersPerResource = {};
+  final Map<String, Holder> holderMap = {};
+  final JCommonElements _commonElements;
+  DeferredHolderResource mainHolderResource;
+
+  DeferredHolderExpressionFinalizerImpl(this._commonElements) {
+    _visitor = _DeferredHolderExpressionCollectorVisitor(this);
+  }
+
+  @override
+  void addCode(String resourceName, js.Node code) {
+    _visitor.setResourceNameAndVisit(resourceName, code);
+  }
+
+  final List<String> userGlobalObjects =
+      List.from(Namer.reservedGlobalObjectNames)
+        ..remove('C')
+        ..remove('H')
+        ..remove('J')
+        ..remove('P')
+        ..remove('W');
+
+  /// Returns the [reservedGlobalObjectNames] for [library].
+  String globalObjectNameForLibrary(LibraryEntity library) {
+    if (library == _commonElements.interceptorsLibrary) return 'J';
+    Uri uri = library.canonicalUri;
+    if (uri.scheme == 'dart') {
+      if (uri.path == 'html') return 'W';
+      if (uri.path.startsWith('_')) return 'H';
+      return 'P';
+    }
+    return userGlobalObjects[library.name.hashCode % userGlobalObjects.length];
+  }
+
+  /// Returns true if [element] is stored in the static state holder
+  /// ([staticStateHolder]).  We intend to store only mutable static state
+  /// there, whereas constants are stored in 'C'. Functions, accessors,
+  /// classes, etc. are stored in one of the other objects in
+  /// [reservedGlobalObjectNames].
+  bool _isPropertyOfStaticStateHolder(MemberEntity element) {
+    // TODO(ahe): Make sure this method's documentation is always true and
+    // remove the word "intend".
+    return element.isField;
+  }
+
+  String globalObjectNameForMember(MemberEntity entity) {
+    if (_isPropertyOfStaticStateHolder(entity)) {
+      return globalObjectNameForStaticState();
+    } else {
+      return globalObjectNameForLibrary(entity.library);
+    }
+  }
+
+  String globalObjectNameForClass(ClassEntity entity) {
+    return globalObjectNameForLibrary(entity.library);
+  }
+
+  final Holder globalObjectForStaticState =
+      Holder(globalObjectNameForStaticState());
+
+  static String globalObjectNameForStaticState() => r'$';
+
+  String globalObjectNameForConstants() => 'C';
+
+  String globalObjectNameForEntity(Entity entity) {
+    if (entity is MemberEntity) {
+      return globalObjectNameForMember(entity);
+    } else if (entity is ClassEntity) {
+      return globalObjectNameForLibrary(entity.library);
+    } else {
+      assert(entity is LibraryEntity);
+      return globalObjectNameForLibrary(entity);
+    }
+  }
+
+  Holder holderNameToHolder(String holderKey) {
+    if (holderKey == globalObjectNameForStaticState()) {
+      return globalObjectForStaticState;
+    } else {
+      return holderMap[holderKey];
+    }
+  }
+
+  Holder globalObjectForEntity(Entity entity) {
+    return holderNameToHolder(globalObjectNameForEntity(entity));
+  }
+
+  /// Registers a [holder] use within a given [resource], if [properties] are
+  /// provided then it is assumed this is an update to a holder.
+  void registerHolderUseOrUpdate(String resourceName, String holderName,
+      {List<js.Property> properties}) {
+    // For simplicity, we don't currently track the static state holder per
+    // resource.
+    if (holderName == globalObjectNameForStaticState()) return;
+    Holder holder = holderMap[holderName] ??= Holder(holderName);
+    if (properties == null) {
+      holder.registerUse(resourceName);
+    } else {
+      holder.registerUpdate(resourceName, properties);
+    }
+    (holdersPerResource[resourceName] ??= {}).add(holder);
+  }
+
+  /// Returns a key to a global object for a given [Object] based on the
+  /// [DeferredHolderExpressionKind].
+  String kindToHolderName(DeferredHolderExpressionKind kind, Object data) {
+    switch (kind) {
+      case DeferredHolderExpressionKind.globalObjectForLibrary:
+        return globalObjectNameForLibrary(data);
+      case DeferredHolderExpressionKind.globalObjectForClass:
+        return globalObjectNameForClass(data);
+      case DeferredHolderExpressionKind.globalObjectForMember:
+        return globalObjectNameForMember(data);
+      case DeferredHolderExpressionKind.globalObjectForConstant:
+        return globalObjectNameForConstants();
+      case DeferredHolderExpressionKind.globalObjectForStaticState:
+        return globalObjectNameForStaticState();
+    }
+    throw UnsupportedError("Unreachable");
+  }
+
+  /// Returns a global object for a given [Object] based on the
+  /// [DeferredHolderExpressionKind].
+  Holder kindToHolder(DeferredHolderExpressionKind kind, Object data) {
+    return holderNameToHolder(kindToHolderName(kind, data));
+  }
+
+  /// Finalizes [DeferredHolderParameter]s.
+  void finalizeParameters() {
+    for (var parameter in holderParameters) {
+      if (parameter.isFinalized) continue;
+      parameter.name = globalObjectNameForStaticState();
+    }
+  }
+
+  /// Finalizes all of the [DeferredHolderExpression]s associated with a
+  /// [DeferredHolderResource].
+  void finalizeReferences(DeferredHolderResource resource) {
+    if (!holderReferences.containsKey(resource.name)) return;
+    for (var reference in holderReferences[resource.name]) {
+      if (reference.isFinalized) continue;
+      String holder = kindToHolder(reference.kind, reference.data).name;
+      js.Expression value = js.VariableUse(holder);
+      reference.value =
+          value.withSourceInformation(reference.sourceInformation);
+    }
+  }
+
+  /// Registers all of the holders used in the entire program.
+  void registerHolders() {
+    // Register all holders used in all [DeferredHolderResource]s.
+    for (var resource in holderResources) {
+      resource.holderCode.forEach((entity, properties) {
+        String holderName = globalObjectNameForEntity(entity);
+        registerHolderUseOrUpdate(resource.name, holderName,
+            properties: properties);
+      });
+    }
+
+    // Register all holders used in [DeferredHolderReference]s.
+    holderReferences.forEach((resource, references) {
+      for (var reference in references) {
+        String holderName = kindToHolderName(reference.kind, reference.data);
+        registerHolderUseOrUpdate(resource, holderName);
+      }
+    });
+  }
+
+  /// Returns an [Iterable<Holder>] containing all of the holders used within a
+  /// given [DeferredHolderResource]except the static state holder (if any).
+  Iterable<Holder> nonStaticStateHolders(DeferredHolderResource resource) {
+    return holdersPerResource[resource.name] ?? [];
+  }
+
+  /// Returns an [Iterable<Holder>] containing all of the holders used within a
+  /// given [DeferredHolderResource] except the static state holder.
+  Iterable<Holder> get allNonStaticStateHolders {
+    return holderMap.values;
+  }
+
+  /// Generates code to declare holders for a given [resourceName].
+  HolderInitCode declareHolders(String resourceName, Iterable<Holder> holders,
+      {bool initializeEmptyHolders = false}) {
+    // Create holder initialization code. If there are no properties
+    // associated with a given holder in this specific [DeferredHolderResource]
+    // then it will be omitted. However, in some cases, i.e. the main output
+    // unit, we still want to declare the holder with an empty object literal
+    // which will be filled in later by another [DeferredHolderResource], i.e.
+    // in a specific deferred fragment. The generated code looks like this:
+    //
+    //    {
+    //      var H = {...}, ..., G = {...};
+    //    }
+
+    List<Holder> activeHolders = [];
+    List<js.VariableInitialization> holderInitializations = [];
+    for (var holder in holders) {
+      var holderName = holder.name;
+      List<js.Property> properties =
+          holder.propertiesPerResource[resourceName] ?? [];
+      if (properties.isEmpty) {
+        holderInitializations.add(js.VariableInitialization(
+            js.VariableDeclaration(holderName, allowRename: false),
+            initializeEmptyHolders ? js.ObjectInitializer(properties) : null));
+      } else {
+        activeHolders.add(holder);
+        holderInitializations.add(js.VariableInitialization(
+            js.VariableDeclaration(holderName, allowRename: false),
+            js.ObjectInitializer(properties)));
+      }
+    }
+
+    // Create statement to initialize holders.
+    var initStatement = js.ExpressionStatement(
+        js.VariableDeclarationList(holderInitializations, indentSplits: false));
+    return HolderInitCode(holders, activeHolders, initStatement);
+  }
+
+  /// Finalizes [resource] to code that updates holders. [resource] must be in
+  /// the AST of a deferred fragment.
+  void updateHolders(DeferredHolderResource resource) {
+    final holderCode =
+        declareHolders(resource.name, nonStaticStateHolders(resource));
+
+    // Set names if necessary on deferred holders list.
+    js.Expression deferredHoldersList = js.ArrayInitializer(holderCode
+        .activeHolders
+        .map((holder) => js.js("#", holder.name))
+        .toList(growable: false));
+    js.Statement setNames = js.js.statement(
+        'hunkHelpers.setFunctionNamesIfNecessary(#deferredHoldersList)',
+        {'deferredHoldersList': deferredHoldersList});
+
+    // Update holder assignments.
+    List<js.Statement> updateHolderAssignments = [
+      if (holderCode.allHolders.isNotEmpty) holderCode.statement,
+      setNames
+    ];
+    for (var holder in holderCode.allHolders) {
+      var holderName = holder.name;
+      var holderIndex = js.number(holder.index);
+      if (holderCode.activeHolders.contains(holder)) {
+        updateHolderAssignments.add(js.js.statement(
+            '#holder = hunkHelpers.updateHolder(holdersList[#index], #holder)',
+            {'index': holderIndex, 'holder': js.VariableUse(holderName)}));
+      } else {
+        // TODO(sra): Change declaration followed by assignments to declarations
+        // with initialization.
+        updateHolderAssignments.add(js.js.statement(
+            '#holder = holdersList[#index]',
+            {'index': holderIndex, 'holder': js.VariableUse(holderName)}));
+      }
+    }
+
+    // Create a single block of all statements.
+    resource.statement = js.Block(updateHolderAssignments);
+  }
+
+  /// Declares all holders in the [DeferredHolderResource] representing the main
+  /// fragment.
+  void declareHoldersInMainResource() {
+    // Declare holders in main output unit.
+    var holders = allNonStaticStateHolders;
+    var holderCode = declareHolders(mainHolderResource.name, holders,
+        initializeEmptyHolders: true);
+
+    // Create holder uses and init holder indices.
+    List<js.VariableUse> holderUses = [];
+    int i = 0;
+    for (var holder in holders) {
+      holder.index = i++;
+      holderUses.add(js.VariableUse(holder.name));
+    }
+
+    // Create holders array statement.
+    //    {
+    //      var holders = [ H, ..., G ];
+    //    }
+    var holderArray =
+        js.js.statement('var holders = #', js.ArrayInitializer(holderUses));
+
+    mainHolderResource.statement =
+        js.Block([holderCode.statement, holderArray]);
+  }
+
+  /// Allocates all [DeferredHolderResource]s and finalizes the associated
+  /// [DeferredHolderExpression]s.
+  void allocateResourcesAndFinalizeReferences() {
+    // First finalize all holders in the main output unit.
+    declareHoldersInMainResource();
+
+    // Next finalize all [DeferredHolderResource]s.
+    for (var resource in holderResources) {
+      switch (resource.kind) {
+        case DeferredHolderResourceKind.mainFragment:
+          // There should only be one main resource and at this point it
+          // should have already been finalized.
+          assert(mainHolderResource == resource && resource.isFinalized);
+          break;
+        case DeferredHolderResourceKind.deferredFragment:
+          updateHolders(resource);
+          break;
+      }
+      finalizeReferences(resource);
+    }
+  }
+
+  @override
+  void finalize() {
+    registerHolders();
+    finalizeParameters();
+    allocateResourcesAndFinalizeReferences();
+  }
+
+  @override
+  void registerDeferredHolderExpression(
+      String resourceName, DeferredHolderExpression node) {
+    (holderReferences[resourceName] ??= []).add(node);
+  }
+
+  @override
+  void registerDeferredHolderResource(DeferredHolderResource node) {
+    if (node.isMainFragment) {
+      assert(mainHolderResource == null);
+      mainHolderResource = node;
+    }
+    holderResources.add(node);
+  }
+
+  @override
+  void registerDeferredHolderParameter(DeferredHolderParameter node) {
+    holderParameters.add(node);
+  }
+}
+
+/// Scans a JavaScript AST to collect all the [DeferredHolderExpression],
+/// [DeferredHolderParameter], [DeferredHolderResource], and
+/// [DeferredHolderResourceExpression] nodes.
+///
+/// The state is kept in the finalizer so that this scan could be extended to
+/// look for other deferred expressions in one pass.
+class _DeferredHolderExpressionCollectorVisitor extends js.BaseVisitor<void> {
+  String resourceName;
+  final DeferredHolderExpressionFinalizer _finalizer;
+
+  _DeferredHolderExpressionCollectorVisitor(this._finalizer);
+
+  void setResourceNameAndVisit(String resourceName, js.Node code) {
+    this.resourceName = resourceName;
+    code.accept(this);
+    this.resourceName = null;
+  }
+
+  @override
+  void visitNode(js.Node node) {
+    assert(node is! DeferredHolderExpression);
+    if (node is js.AstContainer) {
+      for (js.Node element in node.containedNodes) {
+        element.accept(this);
+      }
+    } else {
+      super.visitNode(node);
+    }
+  }
+
+  @override
+  void visitDeferredExpression(js.DeferredExpression node) {
+    if (node is DeferredHolderExpression) {
+      assert(resourceName != null);
+      _finalizer.registerDeferredHolderExpression(resourceName, node);
+    } else {
+      visitNode(node);
+    }
+  }
+
+  @override
+  void visitDeferredStatement(js.DeferredStatement node) {
+    if (node is DeferredHolderResource) {
+      _finalizer.registerDeferredHolderResource(node);
+    } else {
+      visitNode(node);
+    }
+  }
+
+  @override
+  void visitParameter(js.Parameter node) {
+    if (node is DeferredHolderParameter) {
+      _finalizer.registerDeferredHolderParameter(node);
+    } else {
+      visitNode(node);
+    }
+  }
+}
+
+class HolderInitCode {
+  final Iterable<Holder> allHolders;
+  final List<Holder> activeHolders;
+  final js.Statement statement;
+  HolderInitCode(this.allHolders, this.activeHolders, this.statement);
+}
+
+/// All of the code below this point is legacy code.
+
+/// [DeferredHolderExpressionFinalizerImpl] finalizes
+/// [DeferredHolderExpression]s, [DeferredHolderParameter]s,
+/// [DeferredHolderResource]s, [DeferredHolderResourceExpression]s.
+class LegacyDeferredHolderExpressionFinalizerImpl
+    implements DeferredHolderExpressionFinalizer {
+  _DeferredHolderExpressionCollectorVisitor _visitor;
   final List<DeferredHolderExpression> holderReferences = [];
   final List<DeferredHolderParameter> holderParameters = [];
   final List<DeferredHolderResource> holderResources = [];
@@ -301,13 +768,13 @@
   final Map<Entity, String> _entityMap = {};
   final JCommonElements _commonElements;
 
-  DeferredHolderExpressionFinalizerImpl(this._commonElements) {
+  LegacyDeferredHolderExpressionFinalizerImpl(this._commonElements) {
     _visitor = _DeferredHolderExpressionCollectorVisitor(this);
   }
 
   @override
-  void addCode(js.Node code) {
-    code.accept(_visitor);
+  void addCode(String resourceName, js.Node code) {
+    _visitor.setResourceNameAndVisit(resourceName, code);
   }
 
   final List<String> userGlobalObjects =
@@ -369,25 +836,25 @@
   }
 
   /// Registers an [Entity] with a specific [holder].
-  void registerHolderUse(String holder, Entity entity) {
+  void registerHolderUse(String holder, Object data) {
     if (_uniqueHolders.add(holder)) _holders.add(holder);
-    if (entity != null) {
-      assert(!_entityMap.containsKey(entity) || _entityMap[entity] == holder);
-      _entityMap[entity] = holder;
+    if (data != null && data is Entity) {
+      assert(!_entityMap.containsKey(data) || _entityMap[data] == holder);
+      _entityMap[data] = holder;
     }
   }
 
-  /// Returns a global object for a given [Entity] based on the
+  /// Returns a global object for a given [Object] based on the
   /// [DeferredHolderExpressionKind].
-  String kindToHolder(DeferredHolderExpressionKind kind, Entity entity) {
+  String kindToHolder(DeferredHolderExpressionKind kind, Object data) {
     switch (kind) {
       case DeferredHolderExpressionKind.globalObjectForLibrary:
-        return globalObjectForLibrary(entity);
+        return globalObjectForLibrary(data);
       case DeferredHolderExpressionKind.globalObjectForClass:
-        return globalObjectForClass(entity);
+        return globalObjectForClass(data);
       case DeferredHolderExpressionKind.globalObjectForMember:
-        return globalObjectForMember(entity);
-      case DeferredHolderExpressionKind.globalObjectForConstants:
+        return globalObjectForMember(data);
+      case DeferredHolderExpressionKind.globalObjectForConstant:
         return globalObjectForConstants();
       case DeferredHolderExpressionKind.globalObjectForStaticState:
         return globalObjectForStaticState();
@@ -400,10 +867,10 @@
     // Finalize [DeferredHolderExpression]s and registers holder usage.
     for (var reference in holderReferences) {
       if (reference.isFinalized) continue;
-      Entity entity = reference.entity;
-      String holder = kindToHolder(reference.kind, entity);
+      Object data = reference.data;
+      String holder = kindToHolder(reference.kind, data);
       js.Expression value = js.VariableUse(holder);
-      registerHolderUse(holder, entity);
+      registerHolderUse(holder, data);
       reference.value =
           value.withSourceInformation(reference.sourceInformation);
     }
@@ -432,7 +899,7 @@
   }
 
   /// Generates code to declare holders.
-  HolderCode declareHolders(DeferredHolderResource resource) {
+  LegacyHolderCode declareHolders(DeferredHolderResource resource) {
     // Collect all holders except the static state holder. Then, create a map of
     // holder to list of properties which are associated with that holder, but
     // only with respect to a given [DeferredHolderResource]. Each fragment will
@@ -471,9 +938,7 @@
       if (properties.isEmpty) {
         holderInitializations.add(js.VariableInitialization(
             js.VariableDeclaration(holder, allowRename: false),
-            resource.initializeEmptyHolders
-                ? js.ObjectInitializer(properties)
-                : null));
+            resource.isMainFragment ? js.ObjectInitializer(properties) : null));
       } else {
         activeHolders.add(holder);
         holderInitializations.add(js.VariableInitialization(
@@ -486,14 +951,14 @@
     statements.add(js.ExpressionStatement(js.VariableDeclarationList(
         holderInitializations,
         indentSplits: false)));
-    if (resource.initializeEmptyHolders) {
+    if (resource.isMainFragment) {
       statements.add(js.js.statement(
           'var holders = #',
           js.ArrayInitializer(holders
               .map((holder) => js.VariableUse(holder))
               .toList(growable: false))));
     }
-    return HolderCode(activeHolders, statements);
+    return LegacyHolderCode(activeHolders, statements);
   }
 
   /// Finalizes [resource] to code that updates holders. [resource] must be in
@@ -549,11 +1014,11 @@
     // Next finalize all [DeferredHolderResource]s.
     for (var resource in holderResources) {
       switch (resource.kind) {
-        case DeferredHolderResourceKind.declaration:
+        case DeferredHolderResourceKind.mainFragment:
           var holderCode = declareHolders(resource);
           resource.statement = js.Block(holderCode.statements);
           break;
-        case DeferredHolderResourceKind.update:
+        case DeferredHolderResourceKind.deferredFragment:
           updateHolders(resource);
           break;
       }
@@ -566,72 +1031,25 @@
     allocateResources();
   }
 
-  void _registerDeferredHolderExpression(DeferredHolderExpression node) {
+  @override
+  void registerDeferredHolderExpression(
+      String resourceName, DeferredHolderExpression node) {
     holderReferences.add(node);
   }
 
-  void _registerDeferredHolderResource(DeferredHolderResource node) {
+  @override
+  void registerDeferredHolderResource(DeferredHolderResource node) {
     holderResources.add(node);
   }
 
-  void _registerDeferredHolderParameter(DeferredHolderParameter node) {
+  @override
+  void registerDeferredHolderParameter(DeferredHolderParameter node) {
     holderParameters.add(node);
   }
 }
 
-/// Scans a JavaScript AST to collect all the [DeferredHolderExpression],
-/// [DeferredHolderParameter], [DeferredHolderResource], and
-/// [DeferredHolderResourceExpression] nodes.
-///
-/// The state is kept in the finalizer so that this scan could be extended to
-/// look for other deferred expressions in one pass.
-class _DeferredHolderExpressionCollectorVisitor extends js.BaseVisitor<void> {
-  final DeferredHolderExpressionFinalizerImpl _finalizer;
-
-  _DeferredHolderExpressionCollectorVisitor(this._finalizer);
-
-  @override
-  void visitNode(js.Node node) {
-    assert(node is! DeferredHolderExpression);
-    if (node is js.AstContainer) {
-      for (js.Node element in node.containedNodes) {
-        element.accept(this);
-      }
-    } else {
-      super.visitNode(node);
-    }
-  }
-
-  @override
-  void visitDeferredExpression(js.DeferredExpression node) {
-    if (node is DeferredHolderExpression) {
-      _finalizer._registerDeferredHolderExpression(node);
-    } else {
-      visitNode(node);
-    }
-  }
-
-  @override
-  void visitDeferredStatement(js.DeferredStatement node) {
-    if (node is DeferredHolderResource) {
-      _finalizer._registerDeferredHolderResource(node);
-    } else {
-      visitNode(node);
-    }
-  }
-
-  @override
-  void visitParameter(js.Parameter node) {
-    if (node is DeferredHolderParameter) {
-      _finalizer._registerDeferredHolderParameter(node);
-    } else {
-      visitNode(node);
-    }
-  }
-}
-
-class HolderCode {
+class LegacyHolderCode {
   final List<String> activeHolders;
   final List<js.Statement> statements;
-  HolderCode(this.activeHolders, this.statements);
+  LegacyHolderCode(this.activeHolders, this.statements);
 }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 8503a49..5e4afbd 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -2071,8 +2071,9 @@
   FixedNames get fixedNames;
 
   /// Returns a variable use for accessing constants.
-  jsAst.Expression globalObjectForConstants() {
-    return DeferredHolderExpression.forConstants();
+  jsAst.Expression globalObjectForConstant(ConstantValue constant) {
+    return DeferredHolderExpression(
+        DeferredHolderExpressionKind.globalObjectForConstant, constant);
   }
 
   /// Returns a variable use for accessing static state.
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index a32d4a1..8c806eb 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -610,8 +610,10 @@
       this._nativeEmitter,
       this._closedWorld,
       this._codegenWorld)
-      : _holderFinalizer =
-            DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements) {
+      : _holderFinalizer = _options.features.newHolders.isEnabled
+            ? DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements)
+            : LegacyDeferredHolderExpressionFinalizerImpl(
+                _closedWorld.commonElements) {
     _recipeEncoder = RecipeEncoderImpl(
         _closedWorld,
         _options.disableRtiOptimization
@@ -673,6 +675,7 @@
       size = estimator.charCount;
     }
     var emittedOutputUnit = EmittedOutputUnit(
+        fragment,
         fragment.outputUnit,
         fragment.libraries,
         classPrototypes,
@@ -698,9 +701,10 @@
     // Emit holder code.
     var holderCode = emitHolderCode(fragment.libraries);
     var holderDeclaration = DeferredHolderResource(
-        DeferredHolderResourceKind.declaration,
-        holderCode: holderCode,
-        initializeEmptyHolders: true);
+        DeferredHolderResourceKind.mainFragment,
+        mainResourceName,
+        [fragment],
+        holderCode);
     js.Statement mainCode = js.js.statement(_mainBoilerplate, {
       // TODO(29455): 'hunkHelpers' displaces other names, so don't minify it.
       'hunkHelpers': js.VariableDeclaration('hunkHelpers', allowRename: false),
@@ -752,7 +756,7 @@
       'call2selector': js.quoteName(call2Name)
     });
     // We assume emitMainFragment will be the last piece of code we emit.
-    finalizeCode(mainCode, holderCode, finalizeHolders: true);
+    finalizeCode(mainResourceName, mainCode, holderCode, finalizeHolders: true);
     return mainCode;
   }
 
@@ -772,9 +776,12 @@
       return null;
     }
 
+    var resourceName = fragment.canonicalOutputUnit.name;
     var updateHolders = DeferredHolderResource(
-        DeferredHolderResourceKind.update,
-        holderCode: holderCode);
+        DeferredHolderResourceKind.deferredFragment,
+        resourceName,
+        fragment.fragments,
+        holderCode);
     js.Expression code = js.js(_deferredBoilerplate, {
       // TODO(floitsch): don't just reference 'init'.
       'embeddedGlobalsObject': new js.Parameter('init'),
@@ -800,7 +807,7 @@
     if (_options.experimentStartupFunctions) {
       code = js.Parentheses(code);
     }
-    finalizeCode(code, holderCode);
+    finalizeCode(resourceName, code, holderCode);
     return code;
   }
 
@@ -817,7 +824,8 @@
 
   /// Finalizes the code for a fragment, and optionally finalizes holders.
   /// Finalizing holders must be the last step of the emitter.
-  void finalizeCode(js.Node code, Map<Entity, List<js.Property>> holderCode,
+  void finalizeCode(String resourceName, js.Node code,
+      Map<Entity, List<js.Property>> holderCode,
       {bool finalizeHolders: false}) {
     StringReferenceFinalizer stringFinalizer =
         StringReferenceFinalizerImpl(_options.enableMinification);
@@ -835,7 +843,11 @@
     // per output unit, the holderFinalizer is a whole-program finalizer,
     // which collects deferred [Node]s from each call to `finalizeCode`
     // before begin finalized once for the last (main) unit.
-    addCodeToFinalizer(_holderFinalizer.addCode, code, holderCode);
+    void _addCode(js.Node code) {
+      _holderFinalizer.addCode(resourceName, code);
+    }
+
+    addCodeToFinalizer(_addCode, code, holderCode);
     if (finalizeHolders) {
       _holderFinalizer.finalize();
     }
@@ -1570,7 +1582,7 @@
       // TODO(25230): We only need to name constants that are used from function
       // bodies or from other constants in a different part.
       var assignment = js.js.statement('#.# = #', [
-        _namer.globalObjectForConstants(),
+        _namer.globalObjectForConstant(constant.value),
         constant.name,
         _constantEmitter.generate(constant.value)
       ]);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
index 89cc19c..9fae89c 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
@@ -109,6 +109,7 @@
 /// sent to the client.
 
 class EmittedOutputUnit {
+  final Fragment fragment;
   final OutputUnit outputUnit;
   final List<Library> libraries;
   final js.Statement classPrototypes;
@@ -124,6 +125,7 @@
   final js.Statement nativeSupport;
 
   EmittedOutputUnit(
+      this.fragment,
       this.outputUnit,
       this.libraries,
       this.classPrototypes,
@@ -140,6 +142,7 @@
 
   CodeFragment toCodeFragment(Program program) {
     return CodeFragment(
+        [fragment],
         [outputUnit],
         libraries,
         classPrototypes,
@@ -201,6 +204,7 @@
       return seedEmittedOutputUnit.toCodeFragment(program);
     } else {
       var seedOutputUnit = seedEmittedOutputUnit.outputUnit;
+      List<Fragment> fragments = [];
       List<Library> libraries = [];
       List<OutputUnit> outputUnits = [seedOutputUnit];
       List<js.Statement> classPrototypes = [];
@@ -219,6 +223,7 @@
         if (seedOutputUnit != thatOutputUnit) {
           program.mergeOutputUnitMetadata(seedOutputUnit, thatOutputUnit);
           outputUnits.add(thatOutputUnit);
+          fragments.add(emittedOutputUnit.fragment);
         }
         libraries.addAll(emittedOutputUnit.libraries);
         classPrototypes.add(emittedOutputUnit.classPrototypes);
@@ -234,6 +239,7 @@
         nativeSupport.add(emittedOutputUnit.nativeSupport);
       }
       return CodeFragment(
+          fragments,
           outputUnits,
           libraries,
           js.Block(classPrototypes),
@@ -316,6 +322,7 @@
 }
 
 class CodeFragment {
+  final List<Fragment> fragments;
   final List<OutputUnit> outputUnits;
   final List<Library> libraries;
   final js.Statement classPrototypes;
@@ -332,6 +339,7 @@
   final js.Expression deferredTypes;
 
   CodeFragment(
+      this.fragments,
       this.outputUnits,
       this.libraries,
       this.classPrototypes,
@@ -388,6 +396,8 @@
     }
     return outputUnitStrings.join('+');
   }
+
+  OutputUnit get canonicalOutputUnit => outputUnits.first;
 }
 
 class FinalizedFragment {
@@ -400,7 +410,7 @@
   // TODO(joshualitt): Refactor this to more clearly disambiguate between
   // [OutputUnits](units of deferred merging), fragments(units of emitted code),
   // and files.
-  OutputUnit get canonicalOutputUnit => codeFragments.first.outputUnits.first;
+  OutputUnit get canonicalOutputUnit => codeFragments.first.canonicalOutputUnit;
 
   @override
   String toString() {
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 21fe02f..6cacacb 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -65,7 +65,9 @@
         DeferredHolderExpressionFinalizerImpl,
         DeferredHolderParameter,
         DeferredHolderResource,
-        DeferredHolderResourceKind;
+        DeferredHolderResourceKind,
+        LegacyDeferredHolderExpressionFinalizerImpl,
+        mainResourceName;
 import '../../js_backend/type_reference.dart'
     show
         TypeReferenceFinalizer,
@@ -218,8 +220,8 @@
     if (isConstantInlinedOrAlreadyEmitted(value)) {
       return constantEmitter.generate(value);
     }
-    return js.js(
-        '#.#', [_namer.globalObjectForConstants(), _namer.constantName(value)]);
+    return js.js('#.#',
+        [_namer.globalObjectForConstant(value), _namer.constantName(value)]);
   }
 
   bool get shouldMergeFragments => _options.mergeFragmentsThreshold != null;
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index e309a00..da2aa26 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -58,6 +58,9 @@
   FeatureOption legacyJavaScript =
       FeatureOption('legacy-javascript', isNegativeFlag: true);
 
+  /// Whether to use optimized holders.
+  FeatureOption newHolders = FeatureOption('new-holders');
+
   /// [FeatureOption]s which default to enabled.
   List<FeatureOption> shipping;
 
@@ -67,7 +70,7 @@
   // Initialize feature lists.
   FeatureOptions() {
     shipping = [];
-    canary = [legacyJavaScript];
+    canary = [legacyJavaScript, newHolders];
   }
 
   void parse(List<String> options) {
diff --git a/pkg/dds/test/dap/integration/test_server.dart b/pkg/dds/test/dap/integration/test_server.dart
index 2bfb0a0..1beb3cd 100644
--- a/pkg/dds/test/dap/integration/test_server.dart
+++ b/pkg/dds/test/dap/integration/test_server.dart
@@ -6,12 +6,15 @@
 import 'dart:convert';
 import 'dart:io';
 import 'dart:isolate';
+import 'dart:math' show Random;
 
 import 'package:dds/src/dap/logging.dart';
 import 'package:dds/src/dap/server.dart';
 import 'package:path/path.dart' as path;
 import 'package:pedantic/pedantic.dart';
 
+final _random = Random();
+
 abstract class DapTestServer {
   String get host;
   int get port;
@@ -50,10 +53,13 @@
 /// but will be a little more difficult to debug tests as the debugger will not
 /// be attached to the process.
 class OutOfProcessDapTestServer extends DapTestServer {
-  /// Since each test library will spawn its own server (setup/teardown are
-  /// library-scoped) we'll use a different port for each one to avoid any issues
-  /// with overlapping tests.
-  static var _nextPort = DapServer.defaultPort;
+  /// To avoid issues with port bindings if multiple test libraries are run
+  /// concurrently (in their own processes), start from a random port between
+  /// [DapServer.defaultPort] and [DapServer.defaultPort] + 5000.
+  ///
+  /// This number will then be increased should multiple libraries run within
+  /// this same process.
+  static var _nextPort = DapServer.defaultPort + _random.nextInt(5000);
 
   var _isShuttingDown = false;
   final Process _process;
diff --git a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.1.expect b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.1.expect
index 4d7e73b..7d948ed 100644
--- a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.1.expect
@@ -58,7 +58,7 @@
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
     static factory •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
-      return #C10;
+      return #C11;
     static factory _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       let dynamic #redirecting_factory = foo::Baz::__ in invalid-expression;
   }
@@ -71,7 +71,7 @@
         return new foo::Boz::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
       }
       else {
-        return #C14;
+        return #C16;
       }
     }
   }
@@ -80,47 +80,44 @@
 
   import "org-dartlang-test:///foo.dart";
 
-  static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C17);
-  static field foo::Bar newBar = new foo::Bar::_($creationLocationd_0dea112b090073317d4: #C19);
-  static field foo::Bar constBar = #C23;
-  static field foo::Baz newBaz = foo::Baz::•($creationLocationd_0dea112b090073317d4: #C25);
+  static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C19);
+  static field foo::Bar newBar = new foo::Bar::_($creationLocationd_0dea112b090073317d4: #C22);
+  static field foo::Bar constBar = #C26;
+  static field foo::Baz newBaz = foo::Baz::•($creationLocationd_0dea112b090073317d4: #C28);
   static field foo::Boz newBoz = foo::Boz::•(createNew: true, $creationLocationd_0dea112b090073317d4: #C29);
-  static field foo::Boz constBoz = foo::Boz::•(createNew: false, $creationLocationd_0dea112b090073317d4: #C35);
+  static field foo::Boz constBoz = foo::Boz::•(createNew: false, $creationLocationd_0dea112b090073317d4: #C32);
 }
 constants  {
   #C1 = null
   #C2 = "org-dartlang-test:///foo.dart"
   #C3 = 2.0
   #C4 = 51.0
-  #C5 = <wid::_Location*>[]
-  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C1, parameterLocations:#C5}
+  #C5 = "Foo"
+  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C5, parameterLocations:#C1}
   #C7 = foo::Foo {_location:#C6}
   #C8 = 6.0
-  #C9 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C1, parameterLocations:#C5}
-  #C10 = foo::Baz {_location:#C9}
-  #C11 = 9.0
-  #C12 = 128.0
-  #C13 = wid::_Location {file:#C2, line:#C11, column:#C12, name:#C1, parameterLocations:#C5}
-  #C14 = foo::Boz {_location:#C13}
-  #C15 = "org-dartlang-test:///main.dart"
-  #C16 = 18.0
-  #C17 = wid::_Location {file:#C15, line:#C3, column:#C16, name:#C1, parameterLocations:#C5}
-  #C18 = 3.0
-  #C19 = wid::_Location {file:#C15, line:#C18, column:#C16, name:#C1, parameterLocations:#C5}
-  #C20 = 4.0
-  #C21 = 22.0
-  #C22 = wid::_Location {file:#C15, line:#C20, column:#C21, name:#C1, parameterLocations:#C5}
-  #C23 = foo::Bar {_location:#C22}
-  #C24 = 5.0
-  #C25 = wid::_Location {file:#C15, line:#C24, column:#C16, name:#C1, parameterLocations:#C5}
-  #C26 = "createNew"
-  #C27 = wid::_Location {file:#C1, line:#C8, column:#C21, name:#C26, parameterLocations:#C1}
-  #C28 = <wid::_Location*>[#C27]
-  #C29 = wid::_Location {file:#C15, line:#C8, column:#C16, name:#C1, parameterLocations:#C28}
+  #C9 = "Baz"
+  #C10 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C9, parameterLocations:#C1}
+  #C11 = foo::Baz {_location:#C10}
+  #C12 = 9.0
+  #C13 = 128.0
+  #C14 = "Boz"
+  #C15 = wid::_Location {file:#C2, line:#C12, column:#C13, name:#C14, parameterLocations:#C1}
+  #C16 = foo::Boz {_location:#C15}
+  #C17 = "org-dartlang-test:///main.dart"
+  #C18 = 18.0
+  #C19 = wid::_Location {file:#C17, line:#C3, column:#C18, name:#C5, parameterLocations:#C1}
+  #C20 = 3.0
+  #C21 = "Bar"
+  #C22 = wid::_Location {file:#C17, line:#C20, column:#C18, name:#C21, parameterLocations:#C1}
+  #C23 = 4.0
+  #C24 = 22.0
+  #C25 = wid::_Location {file:#C17, line:#C23, column:#C24, name:#C21, parameterLocations:#C1}
+  #C26 = foo::Bar {_location:#C25}
+  #C27 = 5.0
+  #C28 = wid::_Location {file:#C17, line:#C27, column:#C18, name:#C9, parameterLocations:#C1}
+  #C29 = wid::_Location {file:#C17, line:#C8, column:#C18, name:#C14, parameterLocations:#C1}
   #C30 = 7.0
   #C31 = 20.0
-  #C32 = 24.0
-  #C33 = wid::_Location {file:#C1, line:#C30, column:#C32, name:#C26, parameterLocations:#C1}
-  #C34 = <wid::_Location*>[#C33]
-  #C35 = wid::_Location {file:#C15, line:#C30, column:#C31, name:#C1, parameterLocations:#C34}
+  #C32 = wid::_Location {file:#C17, line:#C30, column:#C31, name:#C14, parameterLocations:#C1}
 }
diff --git a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.2.expect
index f3b9199..b101e36 100644
--- a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.2.expect
@@ -58,7 +58,7 @@
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
     static factory •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
-      return #C10;
+      return #C11;
     static factory _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       let dynamic #redirecting_factory = foo::Baz::__ in invalid-expression;
   }
@@ -71,7 +71,7 @@
         return new foo::Boz::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
       }
       else {
-        return #C14;
+        return #C16;
       }
     }
   }
@@ -86,14 +86,16 @@
   #C2 = "org-dartlang-test:///foo.dart"
   #C3 = 2.0
   #C4 = 51.0
-  #C5 = <wid::_Location*>[]
-  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C1, parameterLocations:#C5}
+  #C5 = "Foo"
+  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C5, parameterLocations:#C1}
   #C7 = foo::Foo {_location:#C6}
   #C8 = 6.0
-  #C9 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C1, parameterLocations:#C5}
-  #C10 = foo::Baz {_location:#C9}
-  #C11 = 9.0
-  #C12 = 128.0
-  #C13 = wid::_Location {file:#C2, line:#C11, column:#C12, name:#C1, parameterLocations:#C5}
-  #C14 = foo::Boz {_location:#C13}
+  #C9 = "Baz"
+  #C10 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C9, parameterLocations:#C1}
+  #C11 = foo::Baz {_location:#C10}
+  #C12 = 9.0
+  #C13 = 128.0
+  #C14 = "Boz"
+  #C15 = wid::_Location {file:#C2, line:#C12, column:#C13, name:#C14, parameterLocations:#C1}
+  #C16 = foo::Boz {_location:#C15}
 }
diff --git a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.3.expect b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.3.expect
index 4d7e73b..7d948ed 100644
--- a/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental/flutter_widget_transform_const.yaml.world.3.expect
@@ -58,7 +58,7 @@
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
     static factory •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
-      return #C10;
+      return #C11;
     static factory _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       let dynamic #redirecting_factory = foo::Baz::__ in invalid-expression;
   }
@@ -71,7 +71,7 @@
         return new foo::Boz::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
       }
       else {
-        return #C14;
+        return #C16;
       }
     }
   }
@@ -80,47 +80,44 @@
 
   import "org-dartlang-test:///foo.dart";
 
-  static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C17);
-  static field foo::Bar newBar = new foo::Bar::_($creationLocationd_0dea112b090073317d4: #C19);
-  static field foo::Bar constBar = #C23;
-  static field foo::Baz newBaz = foo::Baz::•($creationLocationd_0dea112b090073317d4: #C25);
+  static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C19);
+  static field foo::Bar newBar = new foo::Bar::_($creationLocationd_0dea112b090073317d4: #C22);
+  static field foo::Bar constBar = #C26;
+  static field foo::Baz newBaz = foo::Baz::•($creationLocationd_0dea112b090073317d4: #C28);
   static field foo::Boz newBoz = foo::Boz::•(createNew: true, $creationLocationd_0dea112b090073317d4: #C29);
-  static field foo::Boz constBoz = foo::Boz::•(createNew: false, $creationLocationd_0dea112b090073317d4: #C35);
+  static field foo::Boz constBoz = foo::Boz::•(createNew: false, $creationLocationd_0dea112b090073317d4: #C32);
 }
 constants  {
   #C1 = null
   #C2 = "org-dartlang-test:///foo.dart"
   #C3 = 2.0
   #C4 = 51.0
-  #C5 = <wid::_Location*>[]
-  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C1, parameterLocations:#C5}
+  #C5 = "Foo"
+  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C5, parameterLocations:#C1}
   #C7 = foo::Foo {_location:#C6}
   #C8 = 6.0
-  #C9 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C1, parameterLocations:#C5}
-  #C10 = foo::Baz {_location:#C9}
-  #C11 = 9.0
-  #C12 = 128.0
-  #C13 = wid::_Location {file:#C2, line:#C11, column:#C12, name:#C1, parameterLocations:#C5}
-  #C14 = foo::Boz {_location:#C13}
-  #C15 = "org-dartlang-test:///main.dart"
-  #C16 = 18.0
-  #C17 = wid::_Location {file:#C15, line:#C3, column:#C16, name:#C1, parameterLocations:#C5}
-  #C18 = 3.0
-  #C19 = wid::_Location {file:#C15, line:#C18, column:#C16, name:#C1, parameterLocations:#C5}
-  #C20 = 4.0
-  #C21 = 22.0
-  #C22 = wid::_Location {file:#C15, line:#C20, column:#C21, name:#C1, parameterLocations:#C5}
-  #C23 = foo::Bar {_location:#C22}
-  #C24 = 5.0
-  #C25 = wid::_Location {file:#C15, line:#C24, column:#C16, name:#C1, parameterLocations:#C5}
-  #C26 = "createNew"
-  #C27 = wid::_Location {file:#C1, line:#C8, column:#C21, name:#C26, parameterLocations:#C1}
-  #C28 = <wid::_Location*>[#C27]
-  #C29 = wid::_Location {file:#C15, line:#C8, column:#C16, name:#C1, parameterLocations:#C28}
+  #C9 = "Baz"
+  #C10 = wid::_Location {file:#C2, line:#C8, column:#C4, name:#C9, parameterLocations:#C1}
+  #C11 = foo::Baz {_location:#C10}
+  #C12 = 9.0
+  #C13 = 128.0
+  #C14 = "Boz"
+  #C15 = wid::_Location {file:#C2, line:#C12, column:#C13, name:#C14, parameterLocations:#C1}
+  #C16 = foo::Boz {_location:#C15}
+  #C17 = "org-dartlang-test:///main.dart"
+  #C18 = 18.0
+  #C19 = wid::_Location {file:#C17, line:#C3, column:#C18, name:#C5, parameterLocations:#C1}
+  #C20 = 3.0
+  #C21 = "Bar"
+  #C22 = wid::_Location {file:#C17, line:#C20, column:#C18, name:#C21, parameterLocations:#C1}
+  #C23 = 4.0
+  #C24 = 22.0
+  #C25 = wid::_Location {file:#C17, line:#C23, column:#C24, name:#C21, parameterLocations:#C1}
+  #C26 = foo::Bar {_location:#C25}
+  #C27 = 5.0
+  #C28 = wid::_Location {file:#C17, line:#C27, column:#C18, name:#C9, parameterLocations:#C1}
+  #C29 = wid::_Location {file:#C17, line:#C8, column:#C18, name:#C14, parameterLocations:#C1}
   #C30 = 7.0
   #C31 = 20.0
-  #C32 = 24.0
-  #C33 = wid::_Location {file:#C1, line:#C30, column:#C32, name:#C26, parameterLocations:#C1}
-  #C34 = <wid::_Location*>[#C33]
-  #C35 = wid::_Location {file:#C15, line:#C30, column:#C31, name:#C1, parameterLocations:#C34}
+  #C32 = wid::_Location {file:#C17, line:#C30, column:#C31, name:#C14, parameterLocations:#C1}
 }
diff --git a/pkg/front_end/testcases/incremental/flutter_widget_transform_nnbd.yaml.world.2.expect b/pkg/front_end/testcases/incremental/flutter_widget_transform_nnbd.yaml.world.2.expect
index 5a5826d..178186e 100644
--- a/pkg/front_end/testcases/incremental/flutter_widget_transform_nnbd.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/flutter_widget_transform_nnbd.yaml.world.2.expect
@@ -54,7 +54,7 @@
   #C2 = "org-dartlang-test:///main.dart"
   #C3 = 3.0
   #C4 = 17.0
-  #C5 = <wid::_Location*>[]
-  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C1, parameterLocations:#C5}
+  #C5 = "Foo"
+  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C5, parameterLocations:#C1}
   #C7 = foo::Foo {_location:#C6}
 }
diff --git a/pkg/front_end/testcases/incremental/flutter_widget_transformer_non_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental/flutter_widget_transformer_non_const.yaml.world.2.expect
index ec9e667..8d1b8cf 100644
--- a/pkg/front_end/testcases/incremental/flutter_widget_transformer_non_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/flutter_widget_transformer_non_const.yaml.world.2.expect
@@ -48,16 +48,13 @@
 
   import "org-dartlang-test:///foo.dart";
 
-  static field foo::Foo foo = new foo::Foo::•(name: "foo", $creationLocationd_0dea112b090073317d4: #C9);
+  static field foo::Foo foo = new foo::Foo::•(name: "foo", $creationLocationd_0dea112b090073317d4: #C6);
 }
 constants  {
   #C1 = null
   #C2 = "org-dartlang-test:///main.dart"
   #C3 = 2.0
   #C4 = 15.0
-  #C5 = 19.0
-  #C6 = "name"
-  #C7 = wid::_Location {file:#C1, line:#C3, column:#C5, name:#C6, parameterLocations:#C1}
-  #C8 = <wid::_Location*>[#C7]
-  #C9 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C1, parameterLocations:#C8}
+  #C5 = "Foo"
+  #C6 = wid::_Location {file:#C2, line:#C3, column:#C4, name:#C5, parameterLocations:#C1}
 }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
index dceb836..22e37ea 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
@@ -325,7 +325,7 @@
       }
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
-      dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
+      dart.core::int* value = let dart.core::int? #t6 = fill in #t6 == null ?{dart.core::int*} #t6 : #t6{dart.core::int*};
       dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}{dart.core::int});
       for (dart.core::int i = start; i.{dart.core::num::<}(end){(dart.core::num) → dart.core::bool}; i = i.{dart.core::num::+}(1){(dart.core::num) → dart.core::int}) {
         this.{dart.core::List::[]=}(i, value){(dart.core::int, dart.core::int*) → void};
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
index dceb836..22e37ea 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
@@ -325,7 +325,7 @@
       }
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
-      dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
+      dart.core::int* value = let dart.core::int? #t6 = fill in #t6 == null ?{dart.core::int*} #t6 : #t6{dart.core::int*};
       dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}{dart.core::int});
       for (dart.core::int i = start; i.{dart.core::num::<}(end){(dart.core::num) → dart.core::bool}; i = i.{dart.core::num::+}(1){(dart.core::num) → dart.core::int}) {
         this.{dart.core::List::[]=}(i, value){(dart.core::int, dart.core::int*) → void};
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
index 1f47a4a..0bef535 100644
--- a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
@@ -994,7 +994,7 @@
   dynamicVar = xPotentiallyNullArg;
   dynamicVar = yNonNullArg;
   dynamicVar = yPotentiallyNullArg;
-  core::Object objectVar = let dynamic #t1 = dynamicArg in #t1.==(null) ?{core::Object} #t1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t1{core::Object};
+  core::Object objectVar = let dynamic #t1 = dynamicArg in #t1 == null ?{core::Object} #t1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t1{core::Object};
   objectVar = objectArg;
   objectVar = numArg;
   objectVar = intArg;
@@ -1035,57 +1035,57 @@
   core::Object objectVar = let final Never #t4 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:114:22: Error: A value of type 'Object?' can't be assigned to a variable of type 'Object' because 'Object?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   Object objectVar = objectNullableArg;
-                     ^" in let core::Object? #t5 = objectNullableArg in #t5.==(null) ?{core::Object} #t5 as{TypeError,ForNonNullableByDefault} core::Object : #t5{core::Object};
+                     ^" in let core::Object? #t5 = objectNullableArg in #t5 == null ?{core::Object} #t5 as{TypeError,ForNonNullableByDefault} core::Object : #t5{core::Object};
   objectVar = let final Never #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:115:15: Error: A value of type 'num?' can't be assigned to a variable of type 'Object' because 'num?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = numNullableArg;
-              ^" in let core::num? #t7 = numNullableArg in #t7.==(null) ?{core::Object} #t7 as{TypeError,ForNonNullableByDefault} core::Object : #t7{core::Object};
+              ^" in let core::num? #t7 = numNullableArg in #t7 == null ?{core::Object} #t7 as{TypeError,ForNonNullableByDefault} core::Object : #t7{core::Object};
   objectVar = let final Never #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:116:15: Error: A value of type 'int?' can't be assigned to a variable of type 'Object' because 'int?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = intNullableArg;
-              ^" in let core::int? #t9 = intNullableArg in #t9.==(null) ?{core::Object} #t9 as{TypeError,ForNonNullableByDefault} core::Object : #t9{core::Object};
+              ^" in let core::int? #t9 = intNullableArg in #t9 == null ?{core::Object} #t9 as{TypeError,ForNonNullableByDefault} core::Object : #t9{core::Object};
   objectVar = let final Never #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:117:15: Error: A value of type 'double?' can't be assigned to a variable of type 'Object' because 'double?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = doubleNullableArg;
-              ^" in let core::double? #t11 = doubleNullableArg in #t11.==(null) ?{core::Object} #t11 as{TypeError,ForNonNullableByDefault} core::Object : #t11{core::Object};
+              ^" in let core::double? #t11 = doubleNullableArg in #t11 == null ?{core::Object} #t11 as{TypeError,ForNonNullableByDefault} core::Object : #t11{core::Object};
   objectVar = let final Never #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:118:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'Object' because 'Function?' is nullable and 'Object' isn't.
  - 'Function' is from 'dart:core'.
  - 'Object' is from 'dart:core'.
   objectVar = functionNullableArg;
-              ^" in let core::Function? #t13 = functionNullableArg in #t13.==(null) ?{core::Object} #t13 as{TypeError,ForNonNullableByDefault} core::Object : #t13{core::Object};
+              ^" in let core::Function? #t13 = functionNullableArg in #t13 == null ?{core::Object} #t13 as{TypeError,ForNonNullableByDefault} core::Object : #t13{core::Object};
   objectVar = let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:119:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Object' because 'void Function()?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = toVoidNullableArg;
-              ^" in let () →? void #t15 = toVoidNullableArg in #t15.==(null) ?{core::Object} #t15 as{TypeError,ForNonNullableByDefault} core::Object : #t15{core::Object};
+              ^" in let () →? void #t15 = toVoidNullableArg in #t15 == null ?{core::Object} #t15 as{TypeError,ForNonNullableByDefault} core::Object : #t15{core::Object};
   objectVar = let final Never #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:120:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Object' because 'Tearoffable?' is nullable and 'Object' isn't.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
  - 'Object' is from 'dart:core'.
   objectVar = tearoffableNullableArg;
-              ^" in let self::Tearoffable? #t17 = tearoffableNullableArg in #t17.==(null) ?{core::Object} #t17 as{TypeError,ForNonNullableByDefault} core::Object : #t17{core::Object};
+              ^" in let self::Tearoffable? #t17 = tearoffableNullableArg in #t17 == null ?{core::Object} #t17 as{TypeError,ForNonNullableByDefault} core::Object : #t17{core::Object};
   objectVar = let final Never #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:121:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Object' because 'XnonNull?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = xNonNullNullableArg;
-              ^" in let self::error::XnonNull? #t19 = xNonNullNullableArg in #t19.==(null) ?{core::Object} #t19 as{TypeError,ForNonNullableByDefault} core::Object : #t19{core::Object};
+              ^" in let self::error::XnonNull? #t19 = xNonNullNullableArg in #t19 == null ?{core::Object} #t19 as{TypeError,ForNonNullableByDefault} core::Object : #t19{core::Object};
   objectVar = let final Never #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:122:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Object' because 'XpotentiallyNull' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = xPotentiallyNullArg;
-              ^" in let self::error::XpotentiallyNull% #t21 = xPotentiallyNullArg in #t21.==(null) ?{core::Object} #t21 as{TypeError,ForNonNullableByDefault} core::Object : #t21{core::Object};
+              ^" in let self::error::XpotentiallyNull% #t21 = xPotentiallyNullArg in #t21 == null ?{core::Object} #t21 as{TypeError,ForNonNullableByDefault} core::Object : #t21{core::Object};
   objectVar = let final Never #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:123:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Object' because 'XpotentiallyNull?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = xPotentiallyNullNullableArg;
-              ^" in let self::error::XpotentiallyNull? #t23 = xPotentiallyNullNullableArg in #t23.==(null) ?{core::Object} #t23 as{TypeError,ForNonNullableByDefault} core::Object : #t23{core::Object};
+              ^" in let self::error::XpotentiallyNull? #t23 = xPotentiallyNullNullableArg in #t23 == null ?{core::Object} #t23 as{TypeError,ForNonNullableByDefault} core::Object : #t23{core::Object};
   objectVar = let final Never #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:124:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Object' because 'YnonNull?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = yNonNullNullableArg;
-              ^" in let self::error::YnonNull? #t25 = yNonNullNullableArg in #t25.==(null) ?{core::Object} #t25 as{TypeError,ForNonNullableByDefault} core::Object : #t25{core::Object};
+              ^" in let self::error::YnonNull? #t25 = yNonNullNullableArg in #t25 == null ?{core::Object} #t25 as{TypeError,ForNonNullableByDefault} core::Object : #t25{core::Object};
   objectVar = let final Never #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:125:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Object' because 'YpotentiallyNull' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = yPotentiallyNullArg;
-              ^" in let self::error::YpotentiallyNull% #t27 = yPotentiallyNullArg in #t27.==(null) ?{core::Object} #t27 as{TypeError,ForNonNullableByDefault} core::Object : #t27{core::Object};
+              ^" in let self::error::YpotentiallyNull% #t27 = yPotentiallyNullArg in #t27 == null ?{core::Object} #t27 as{TypeError,ForNonNullableByDefault} core::Object : #t27{core::Object};
   objectVar = let final Never #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:126:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Object' because 'YpotentiallyNull?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   objectVar = yPotentiallyNullNullableArg;
-              ^" in let self::error::YpotentiallyNull? #t29 = yPotentiallyNullNullableArg in #t29.==(null) ?{core::Object} #t29 as{TypeError,ForNonNullableByDefault} core::Object : #t29{core::Object};
+              ^" in let self::error::YpotentiallyNull? #t29 = yPotentiallyNullNullableArg in #t29 == null ?{core::Object} #t29 as{TypeError,ForNonNullableByDefault} core::Object : #t29{core::Object};
   core::num numVar = let final Never #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:128:16: Error: A value of type 'Object' can't be assigned to a variable of type 'num'.
  - 'Object' is from 'dart:core'.
   num numVar = objectArg;
@@ -1096,13 +1096,13 @@
            ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::num;
   numVar = let final Never #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:130:12: Error: A value of type 'num?' can't be assigned to a variable of type 'num' because 'num?' is nullable and 'num' isn't.
   numVar = numNullableArg;
-           ^" in let core::num? #t33 = numNullableArg in #t33.==(null) ?{core::num} #t33 as{TypeError,ForNonNullableByDefault} core::num : #t33{core::num};
+           ^" in let core::num? #t33 = numNullableArg in #t33 == null ?{core::num} #t33 as{TypeError,ForNonNullableByDefault} core::num : #t33{core::num};
   numVar = let final Never #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:131:12: Error: A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
   numVar = intNullableArg;
-           ^" in let core::int? #t35 = intNullableArg in #t35.==(null) ?{core::num} #t35 as{TypeError,ForNonNullableByDefault} core::num : #t35{core::num};
+           ^" in let core::int? #t35 = intNullableArg in #t35 == null ?{core::num} #t35 as{TypeError,ForNonNullableByDefault} core::num : #t35{core::num};
   numVar = let final Never #t36 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:132:12: Error: A value of type 'double?' can't be assigned to a variable of type 'num' because 'double?' is nullable and 'num' isn't.
   numVar = doubleNullableArg;
-           ^" in let core::double? #t37 = doubleNullableArg in #t37.==(null) ?{core::num} #t37 as{TypeError,ForNonNullableByDefault} core::num : #t37{core::num};
+           ^" in let core::double? #t37 = doubleNullableArg in #t37 == null ?{core::num} #t37 as{TypeError,ForNonNullableByDefault} core::num : #t37{core::num};
   numVar = let final Never #t38 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:133:12: Error: A value of type 'Function' can't be assigned to a variable of type 'num'.
  - 'Function' is from 'dart:core'.
   numVar = functionArg;
@@ -1165,7 +1165,7 @@
            ^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::int;
   intVar = let final Never #t56 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:152:12: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   intVar = intNullableArg;
-           ^" in let core::int? #t57 = intNullableArg in #t57.==(null) ?{core::int} #t57 as{TypeError,ForNonNullableByDefault} core::int : #t57{core::int};
+           ^" in let core::int? #t57 = intNullableArg in #t57 == null ?{core::int} #t57 as{TypeError,ForNonNullableByDefault} core::int : #t57{core::int};
   intVar = let final Never #t58 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:153:12: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
   intVar = doubleArg;
            ^" in doubleArg as{TypeError,ForNonNullableByDefault} core::int;
@@ -1240,7 +1240,7 @@
               ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::double;
   doubleVar = let final Never #t80 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:176:15: Error: A value of type 'double?' can't be assigned to a variable of type 'double' because 'double?' is nullable and 'double' isn't.
   doubleVar = doubleNullableArg;
-              ^" in let core::double? #t81 = doubleNullableArg in #t81.==(null) ?{core::double} #t81 as{TypeError,ForNonNullableByDefault} core::double : #t81{core::double};
+              ^" in let core::double? #t81 = doubleNullableArg in #t81 == null ?{core::double} #t81 as{TypeError,ForNonNullableByDefault} core::double : #t81{core::double};
   doubleVar = let final Never #t82 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:177:15: Error: A value of type 'Function' can't be assigned to a variable of type 'double'.
  - 'Function' is from 'dart:core'.
   doubleVar = functionArg;
@@ -1400,7 +1400,7 @@
               ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} () → void;
   toVoidVar = let final Never #t125 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()' because 'void Function()?' is nullable and 'void Function()' isn't.
   toVoidVar = toVoidNullableArg;
-              ^" in let () →? void #t126 = toVoidNullableArg in #t126.==(null) ?{() → void} #t126 as{TypeError,ForNonNullableByDefault} () → void : #t126{() → void};
+              ^" in let () →? void #t126 = toVoidNullableArg in #t126 == null ?{() → void} #t126 as{TypeError,ForNonNullableByDefault} () → void : #t126{() → void};
   toVoidVar = let final Never #t127 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
   toVoidVar = tearoffableNullableArg;
               ^" in tearoffableNullableArg as{TypeError} () → void;
@@ -1483,7 +1483,7 @@
   tearoffableVar = let final Never #t148 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable' because 'Tearoffable?' is nullable and 'Tearoffable' isn't.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = tearoffableNullableArg;
-                   ^" in let self::Tearoffable? #t149 = tearoffableNullableArg in #t149.==(null) ?{self::Tearoffable} #t149 as{TypeError,ForNonNullableByDefault} self::Tearoffable : #t149{self::Tearoffable};
+                   ^" in let self::Tearoffable? #t149 = tearoffableNullableArg in #t149 == null ?{self::Tearoffable} #t149 as{TypeError,ForNonNullableByDefault} self::Tearoffable : #t149{self::Tearoffable};
   tearoffableVar = let final Never #t150 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = xNonNullArg;
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
index 68d5235..ca909b2 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
@@ -207,12 +207,12 @@
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   fooContext(x); // Error.
-             ^" in let self::B? #t2 = x in #t2.==(null) ?{self::A} #t2 as{TypeError,ForNonNullableByDefault} self::A : #t2{self::A});
+             ^" in let self::B? #t2 = x in #t2 == null ?{self::A} #t2 as{TypeError,ForNonNullableByDefault} self::A : #t2{self::A});
   self::A a = let final Never #t3 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:28:9: Error: A value of type 'B?' can't be assigned to a variable of type 'A' because 'B?' is nullable and 'A' isn't.
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   A a = x; // Error.
-        ^" in let self::B? #t4 = x in #t4.==(null) ?{self::A} #t4 as{TypeError,ForNonNullableByDefault} self::A : #t4{self::A};
+        ^" in let self::B? #t4 = x in #t4 == null ?{self::A} #t4 as{TypeError,ForNonNullableByDefault} self::A : #t4{self::A};
   core::_GrowableList::_literal1<self::A>(invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:29:10: Error: Can't assign spread elements of type 'B?' to collection elements of type 'A' because 'B?' is nullable and 'A' isn't.
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -243,7 +243,7 @@
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
 Try changing the type of the variable.
   for (A y in l) {} // Error.
-         ^" in let self::B? #t7 = #t5 in #t7.==(null) ?{self::A} #t7 as{TypeError,ForNonNullableByDefault} self::A : #t7{self::A};
+         ^" in let self::B? #t7 = #t5 in #t7 == null ?{self::A} #t7 as{TypeError,ForNonNullableByDefault} self::A : #t7{self::A};
       }
     }
   }
@@ -253,7 +253,7 @@
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'Iterable' is from 'dart:core'.
   for (A y in l2) {} // Error.
-              ^" in let core::List<self::B>? #t9 = l2 in #t9.==(null) ?{core::Iterable<dynamic>} #t9 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t9{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
+              ^" in let core::List<self::B>? #t9 = l2 in #t9 == null ?{core::Iterable<dynamic>} #t9 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t9{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
       self::A y = :sync-for-iterator.{core::Iterator::current}{dynamic};
       {}
@@ -289,7 +289,7 @@
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
       return x; // Error.
-             ^" in let self::B? #t11 = x in #t11.==(null) ?{self::A} #t11 as{TypeError,ForNonNullableByDefault} self::A : #t11{self::A};
+             ^" in let self::B? #t11 = x in #t11 == null ?{self::A} #t11 as{TypeError,ForNonNullableByDefault} self::A : #t11{self::A};
             break #L4;
           }
           else {
@@ -318,7 +318,7 @@
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   return x; // Error.
-         ^" in let self::B? #t14 = x in #t14.==(null) ?{self::A} #t14 as{TypeError,ForNonNullableByDefault} self::A : #t14{self::A};
+         ^" in let self::B? #t14 = x in #t14 == null ?{self::A} #t14 as{TypeError,ForNonNullableByDefault} self::A : #t14{self::A};
 }
 static method bar(core::List<self::B?> x, core::List<core::List<self::B?>> l, core::Map<core::List<self::B?>, core::List<self::B?>> m) → core::List<self::A> {
   self::barContext(let final Never #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
@@ -381,30 +381,30 @@
   self::fooContext(let final Never #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   fooContext(x); // Error.
-             ^" in let Null #t23 = x in #t23.==(null) ?{self::A} #t23 as{TypeError,ForNonNullableByDefault} self::A : #t23{self::A});
+             ^" in let Null #t23 = x in #t23 == null ?{self::A} #t23 as{TypeError,ForNonNullableByDefault} self::A : #t23{self::A});
   self::fooContext(let final Never #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   fooContext(null); // Error.
-             ^" in let Null #t25 = null in #t25.==(null) ?{self::A} #t25 as{TypeError,ForNonNullableByDefault} self::A : #t25{self::A});
+             ^" in let Null #t25 = null in #t25 == null ?{self::A} #t25 as{TypeError,ForNonNullableByDefault} self::A : #t25{self::A});
   self::A a1 = let final Never #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   A a1 = x; // Error.
-         ^" in let Null #t27 = x in #t27.==(null) ?{self::A} #t27 as{TypeError,ForNonNullableByDefault} self::A : #t27{self::A};
+         ^" in let Null #t27 = x in #t27 == null ?{self::A} #t27 as{TypeError,ForNonNullableByDefault} self::A : #t27{self::A};
   self::A a2 = let final Never #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
   A a2 = null; // Error.
-         ^" in let Null #t29 = null in #t29.==(null) ?{self::A} #t29 as{TypeError,ForNonNullableByDefault} self::A : #t29{self::A};
+         ^" in let Null #t29 = null in #t29 == null ?{self::A} #t29 as{TypeError,ForNonNullableByDefault} self::A : #t29{self::A};
   if(true) {
     return let final Never #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
     return x; // Error.
-           ^" in let Null #t31 = x in #t31.==(null) ?{self::A} #t31 as{TypeError,ForNonNullableByDefault} self::A : #t31{self::A};
+           ^" in let Null #t31 = x in #t31 == null ?{self::A} #t31 as{TypeError,ForNonNullableByDefault} self::A : #t31{self::A};
   }
   else {
     return let final Never #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
     return null; // Error.
-           ^" in let Null #t33 = null in #t33.==(null) ?{self::A} #t33 as{TypeError,ForNonNullableByDefault} self::A : #t33{self::A};
+           ^" in let Null #t33 = null in #t33 == null ?{self::A} #t33 as{TypeError,ForNonNullableByDefault} self::A : #t33{self::A};
   }
   function local() → FutureOr<self::A> /* originally async */ {
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
@@ -422,7 +422,7 @@
             :return_value = let final Never #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
       return null; // Error.
-             ^" in let Null #t35 = null in #t35.==(null) ?{self::A} #t35 as{TypeError,ForNonNullableByDefault} self::A : #t35{self::A};
+             ^" in let Null #t35 = null in #t35 == null ?{self::A} #t35 as{TypeError,ForNonNullableByDefault} self::A : #t35{self::A};
             break #L5;
           }
           else {
@@ -454,16 +454,16 @@
 }
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:67:14 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///assignability_error_messages.dart:67:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:67:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:67:14 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:69:10 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///assignability_error_messages.dart:69:10 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:69:10 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:69:10 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:73:12 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///assignability_error_messages.dart:73:12 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:73:12 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:73:12 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
 Extra constant evaluation: evaluated: 208, effectively constant: 12
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.strong.transformed.expect
index 8295079..b110df5 100644
--- a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.strong.transformed.expect
@@ -104,7 +104,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → T%
     return value;
-  late T% local7 = #local7#initializer.call();
+  late T% local7 = #local7#initializer(){() → T%};
   let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
   ^^^^^^" in local1;
@@ -134,7 +134,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → T%
     return value;
-  late T% local7 = #local7#initializer.call();
+  late T% local7 = #local7#initializer(){() → T%};
   if(b) {
     local1 = value;
     local2 = value;
@@ -177,7 +177,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → self::methodDirect::T%
     return value;
-  late self::methodDirect::T% local7 = #local7#initializer.call();
+  late self::methodDirect::T% local7 = #local7#initializer(){() → self::methodDirect::T%};
   let final Never #t12 = invalid-expression "pkg/front_end/testcases/nnbd/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
   ^^^^^^" in local1;
@@ -207,7 +207,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → self::methodConditional::T%
     return value;
-  late self::methodConditional::T% local7 = #local7#initializer.call();
+  late self::methodConditional::T% local7 = #local7#initializer(){() → self::methodConditional::T%};
   if(b) {
     local1 = value;
     local2 = value;
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.weak.transformed.expect
index 8295079..b110df5 100644
--- a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.weak.transformed.expect
@@ -104,7 +104,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → T%
     return value;
-  late T% local7 = #local7#initializer.call();
+  late T% local7 = #local7#initializer(){() → T%};
   let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
   ^^^^^^" in local1;
@@ -134,7 +134,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → T%
     return value;
-  late T% local7 = #local7#initializer.call();
+  late T% local7 = #local7#initializer(){() → T%};
   if(b) {
     local1 = value;
     local2 = value;
@@ -177,7 +177,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → self::methodDirect::T%
     return value;
-  late self::methodDirect::T% local7 = #local7#initializer.call();
+  late self::methodDirect::T% local7 = #local7#initializer(){() → self::methodDirect::T%};
   let final Never #t12 = invalid-expression "pkg/front_end/testcases/nnbd/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
   ^^^^^^" in local1;
@@ -207,7 +207,7 @@
   late FutureOr<core::int>local6;
   function #local7#initializer() → self::methodConditional::T%
     return value;
-  late self::methodConditional::T% local7 = #local7#initializer.call();
+  late self::methodConditional::T% local7 = #local7#initializer(){() → self::methodConditional::T%};
   if(b) {
     local1 = value;
     local2 = value;
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
index 810d4fa..4eda5c5 100644
--- a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
@@ -56,7 +56,7 @@
     core::Iterator<dynamic> :sync-for-iterator = (let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'Iterable<int>?' is nullable and 'Iterable<dynamic>' isn't.
  - 'Iterable' is from 'dart:core'.
   for (int x in i2) x;
-                ^" in let core::Iterable<core::int>? #t2 = i2 in #t2.==(null) ?{core::Iterable<dynamic>} #t2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t2{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
+                ^" in let core::Iterable<core::int>? #t2 = i2 in #t2 == null ?{core::Iterable<dynamic>} #t2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t2{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
       core::int x = :sync-for-iterator.{core::Iterator::current}{dynamic};
       x;
@@ -68,7 +68,7 @@
       core::Iterator<dynamic> :sync-for-iterator = (let final Never #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'Iterable<int>?' is nullable and 'Iterable<dynamic>' isn't.
  - 'Iterable' is from 'dart:core'.
   [for (int x in i2) x];
-                 ^" in let core::Iterable<core::int>? #t5 = i2 in #t5.==(null) ?{core::Iterable<dynamic>} #t5 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t5{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
+                 ^" in let core::Iterable<core::int>? #t5 = i2 in #t5 == null ?{core::Iterable<dynamic>} #t5 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t5{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
         core::int x = :sync-for-iterator.{core::Iterator::current}{dynamic};
         #t3.{core::List::add}(x){(core::int) → void};
@@ -80,7 +80,7 @@
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in l2) x;
-                ^" in let core::List<core::int>? #t7 = l2 in #t7.==(null) ?{core::Iterable<dynamic>} #t7 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t7{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
+                ^" in let core::List<core::int>? #t7 = l2 in #t7 == null ?{core::Iterable<dynamic>} #t7 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t7{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
       core::int x = :sync-for-iterator.{core::Iterator::current}{dynamic};
       x;
@@ -93,7 +93,7 @@
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in l2) x];
-                 ^" in let core::List<core::int>? #t10 = l2 in #t10.==(null) ?{core::Iterable<dynamic>} #t10 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t10{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
+                 ^" in let core::List<core::int>? #t10 = l2 in #t10 == null ?{core::Iterable<dynamic>} #t10 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t10{core::Iterable<dynamic>}).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
         core::int x = :sync-for-iterator.{core::Iterator::current}{dynamic};
         #t8.{core::List::add}(x){(core::int) → void};
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index 2cbfb9d..3d7775d 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -72,7 +72,7 @@
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1 == null ?{core::int?} null : #t1.{core::List::length}{core::int};
 static final field core::List<core::int> s3 = core::_List::filled<core::int>(2, let final Never #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
 final s3 = new List<int>.filled(2, null);
-                                   ^" in let Null #t3 = null in #t3.==(null) ?{core::int} #t3 as{TypeError,ForNonNullableByDefault} core::int : #t3{core::int});
+                                   ^" in let Null #t3 = null in #t3 == null ?{core::int} #t3 as{TypeError,ForNonNullableByDefault} core::int : #t3{core::int});
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
@@ -130,7 +130,7 @@
 }
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41102.dart:17:36 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///issue41102.dart:17:36 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:15 -> IntConstant(0)
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
index f7c18e2..023355f 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
@@ -30,7 +30,7 @@
   List y = await l(); // should be a List?
            ^";
         [yield] let dynamic #t2 = asy::_awaitHelper(self::l(), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<dynamic> y = let core::List<dynamic>? #t3 = _in::unsafeCast<core::List<dynamic>?>(:result) in #t3.==(null) ?{core::List<dynamic>} #t3 as{TypeError,ForNonNullableByDefault} core::List<dynamic> : #t3{core::List<dynamic>};
+        core::List<dynamic> y = let core::List<dynamic>? #t3 = _in::unsafeCast<core::List<dynamic>?>(:result) in #t3 == null ?{core::List<dynamic>} #t3 as{TypeError,ForNonNullableByDefault} core::List<dynamic> : #t3{core::List<dynamic>};
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
index 8c2b6ba..ebee0fc 100644
--- a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
@@ -31,7 +31,7 @@
   self::Null x = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: The value 'null' can't be assigned to a variable of type 'Null' because 'Null' is not nullable.
  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
   Null x = null;
-           ^" in let Null #t2 = null in #t2.==(null) ?{self::Null} #t2 as{TypeError,ForNonNullableByDefault} self::Null : #t2{self::Null};
+           ^" in let Null #t2 = null in #t2 == null ?{self::Null} #t2 as{TypeError,ForNonNullableByDefault} self::Null : #t2{self::Null};
   invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'foo'.
@@ -48,7 +48,7 @@
 
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41700b.dart:8:12 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///issue41700b.dart:8:12 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41700b.dart:8:12 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41700b.dart:8:12 -> NullConstant(null)
 Extra constant evaluation: evaluated: 7, effectively constant: 3
diff --git a/pkg/front_end/testcases/nnbd/issue42089.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42089.dart.strong.transformed.expect
index 39f4cd7..d066ef6 100644
--- a/pkg/front_end/testcases/nnbd/issue42089.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42089.dart.strong.transformed.expect
@@ -20,11 +20,11 @@
     core::Object o = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object' because 'X?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
     Object o = x;
-               ^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t2 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object};
+               ^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t2 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t2 == null ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object};
     o = let final Never #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object' because 'X?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
     o = x;
-        ^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t4 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t4.==(null) ?{core::Object} #t4 as{TypeError,ForNonNullableByDefault} core::Object : #t4{core::Object};
+        ^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t4 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t4 == null ?{core::Object} #t4 as{TypeError,ForNonNullableByDefault} core::Object : #t4{core::Object};
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
index 617bbec..e39daa0 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
@@ -119,12 +119,12 @@
   constructor constructor5([core::int? i = #C1]) → self::A
     : self::A::i = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42362.dart:19:18: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
       : this.i = i; // error
-                 ^" in let core::int? #t2 = i in #t2.==(null) ?{core::int} #t2 as{TypeError,ForNonNullableByDefault} core::int : #t2{core::int}, super core::Object::•()
+                 ^" in let core::int? #t2 = i in #t2 == null ?{core::int} #t2 as{TypeError,ForNonNullableByDefault} core::int : #t2{core::int}, super core::Object::•()
     ;
   constructor constructor6({core::int? i = #C1}) → self::A
     : self::A::i = let final Never #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42362.dart:22:18: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
       : this.i = i; // error
-                 ^" in let core::int? #t4 = i in #t4.==(null) ?{core::int} #t4 as{TypeError,ForNonNullableByDefault} core::int : #t4{core::int}, super core::Object::•()
+                 ^" in let core::int? #t4 = i in #t4 == null ?{core::int} #t4 as{TypeError,ForNonNullableByDefault} core::int : #t4{core::int}, super core::Object::•()
     ;
   constructor constructor7({required core::int i = #C1}) → self::A
     : self::A::i = i, super core::Object::•()
@@ -186,12 +186,12 @@
   constructor constructor5([core::int? i = #C1]) → self::C
     : self::C::i = let final Never #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue42362.dart:85:39: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   C.constructor5([int? i]) : this.i = i; // error
-                                      ^" in let core::int? #t6 = i in #t6.==(null) ?{core::int} #t6 as{TypeError,ForNonNullableByDefault} core::int : #t6{core::int}, super core::Object::•()
+                                      ^" in let core::int? #t6 = i in #t6 == null ?{core::int} #t6 as{TypeError,ForNonNullableByDefault} core::int : #t6{core::int}, super core::Object::•()
     ;
   constructor constructor6({core::int? i = #C1}) → self::C
     : self::C::i = let final Never #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue42362.dart:87:39: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   C.constructor6({int? i}) : this.i = i; // error
-                                      ^" in let core::int? #t8 = i in #t8.==(null) ?{core::int} #t8 as{TypeError,ForNonNullableByDefault} core::int : #t8{core::int}, super core::Object::•()
+                                      ^" in let core::int? #t8 = i in #t8 == null ?{core::int} #t8 as{TypeError,ForNonNullableByDefault} core::int : #t8{core::int}, super core::Object::•()
     ;
   constructor constructor7({required core::int i = #C1}) → self::C
     : self::C::i = i, super core::Object::•()
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
index 6ba990a..2bb4719 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
@@ -19,9 +19,9 @@
       #L1:
       {
         [yield] let dynamic #t1 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
-        core::Object o = let dynamic #t2 = :result in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t2{core::Object};
+        core::Object o = let dynamic #t2 = :result in #t2 == null ?{core::Object} #t2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t2{core::Object};
         [yield] let dynamic #t3 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
-        :return_value = let dynamic #t4 = :result in #t4.==(null) ?{FutureOr<core::Object>} #t4 as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> : #t4{FutureOr<core::Object>};
+        :return_value = let dynamic #t4 = :result in #t4 == null ?{FutureOr<core::Object>} #t4 as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> : #t4{FutureOr<core::Object>};
         break #L1;
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue43689.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43689.dart.strong.transformed.expect
index 6fcf485..ad3780a 100644
--- a/pkg/front_end/testcases/nnbd/issue43689.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43689.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
     return invalid-expression "pkg/front_end/testcases/nnbd/issue43689.dart:10:19: Error: 'x' is already declared in this scope.
   late final int? x;
                   ^";
-  late final core::int? x = #x#initializer.call();
+  late final core::int? x = #x#initializer(){() → core::int?};
   core::int z;
   core::int? z = invalid-expression "pkg/front_end/testcases/nnbd/issue43689.dart:12:8: Error: 'z' is already declared in this scope.
   int? z;
diff --git a/pkg/front_end/testcases/nnbd/issue43689.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43689.dart.weak.transformed.expect
index 6fcf485..ad3780a 100644
--- a/pkg/front_end/testcases/nnbd/issue43689.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43689.dart.weak.transformed.expect
@@ -33,7 +33,7 @@
     return invalid-expression "pkg/front_end/testcases/nnbd/issue43689.dart:10:19: Error: 'x' is already declared in this scope.
   late final int? x;
                   ^";
-  late final core::int? x = #x#initializer.call();
+  late final core::int? x = #x#initializer(){() → core::int?};
   core::int z;
   core::int? z = invalid-expression "pkg/front_end/testcases/nnbd/issue43689.dart:12:8: Error: 'z' is already declared in this scope.
   int? z;
diff --git a/pkg/front_end/testcases/nnbd/issue43716a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43716a.dart.strong.transformed.expect
index 03d87ee..e1b2b87 100644
--- a/pkg/front_end/testcases/nnbd/issue43716a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43716a.dart.strong.transformed.expect
@@ -22,7 +22,7 @@
     return let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue43716a.dart:15:14: Error: A value of type 'Object?' can't be returned from a function with return type 'Object' because 'Object?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
     return z.x; // Error.
-             ^" in let core::Object? #t2 = z{self::C<core::Object?, core::Object?>}.{self::C::x}{core::Object?} in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object};
+             ^" in let core::Object? #t2 = z{self::C<core::Object?, core::Object?>}.{self::C::x}{core::Object?} in #t2 == null ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object};
   }
 }
 static field core::bool b = true;
diff --git a/pkg/front_end/testcases/nnbd/issue43721.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43721.dart.strong.transformed.expect
index 2c12b09..01f043c 100644
--- a/pkg/front_end/testcases/nnbd/issue43721.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43721.dart.strong.transformed.expect
@@ -20,6 +20,6 @@
   self::foo(let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue43721.dart:13:7: Error: The argument type 'FutureOr<num?>' can't be assigned to the parameter type 'Object' because 'num?' is nullable and 'Object' isn't.
  - 'Object' is from 'dart:core'.
   foo(z); // Error.
-      ^" in let FutureOr<core::num?>#t2 = z in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object});
+      ^" in let FutureOr<core::num?>#t2 = z in #t2 == null ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object});
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index 18efa67..415a7b1 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -193,12 +193,12 @@
           return invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest();
                    ^^^^^";
-        late core::String s1 = #s1#initializer.call();
+        late core::String s1 = #s1#initializer(){() → core::String};
         function #s2#initializer() → core::String
           return "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}';
                              ^^^^^"}${#C1}";
-        late core::String s2 = #s2#initializer.call();
+        late core::String s2 = #s2#initializer(){() → core::String};
         function #f#initializer() → core::Function
           return () → asy::Future<dynamic> /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
@@ -229,7 +229,7 @@
             :is_sync = true;
             return :async_future;
           };
-        late core::Function f = #f#initializer.call();
+        late core::Function f = #f#initializer(){() → core::Function};
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index 18efa67..415a7b1 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -193,12 +193,12 @@
           return invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest();
                    ^^^^^";
-        late core::String s1 = #s1#initializer.call();
+        late core::String s1 = #s1#initializer(){() → core::String};
         function #s2#initializer() → core::String
           return "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}';
                              ^^^^^"}${#C1}";
-        late core::String s2 = #s2#initializer.call();
+        late core::String s2 = #s2#initializer(){() → core::String};
         function #f#initializer() → core::Function
           return () → asy::Future<dynamic> /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
@@ -229,7 +229,7 @@
             :is_sync = true;
             return :async_future;
           };
-        late core::Function f = #f#initializer.call();
+        late core::Function f = #f#initializer(){() → core::Function};
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
index 7c865b5..a736515 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
@@ -123,13 +123,13 @@
   let final self::Class1? #t75 = c1 in #t75 == null ?{core::int?} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field}{self::Class2?} in #t76 == null ?{core::int?} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77) == null ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1){(core::int) → core::int}){(core::num) → core::int}) : null;
   let final self::Class1? #t78 = c1 in #t78 == null ?{core::int?} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field}{self::Class2?} in #t79 == null ?{core::int?} null : self::Extension|[](#t79{self::Class2}, 0);
   let final self::Class1? #t80 = c1 in #t80 == null ?{void} null : let final self::Class2? #t81 = #t80{self::Class1}.{self::Class1::field}{self::Class2?} in #t81 == null ?{void} null : self::Extension|[]=(#t81{self::Class2}, 0, 1);
-  let final self::Class1? #t82 = c1 in #t82 == null ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field}{self::Class2?} in #t83 == null ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let core::int? #t84 = let final self::Class2? #t85 = c2 in #t85 == null ?{core::int?} null : self::Extension|[](#t85{self::Class2}, 0)! in #t84.==(null) ?{core::int} #t84 as{ForNonNullableByDefault} core::int : #t84{core::int}){(core::num) → core::int});
+  let final self::Class1? #t82 = c1 in #t82 == null ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field}{self::Class2?} in #t83 == null ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let core::int? #t84 = let final self::Class2? #t85 = c2 in #t85 == null ?{core::int?} null : self::Extension|[](#t85{self::Class2}, 0)! in #t84 == null ?{core::int} #t84 as{ForNonNullableByDefault} core::int : #t84{core::int}){(core::num) → core::int});
   let final self::Class1? #t86 = c1 in #t86 == null ?{core::int?} null : let final self::Class2? #t87 = #t86{self::Class1}.{self::Class1::field}{self::Class2?} in #t87 == null ?{core::int?} null : let final core::int #t88 = 0 in self::Extension|[]=(#t87{self::Class2}, #t88, self::Extension|[](#t87{self::Class2}, #t88).{core::num::+}(1){(core::num) → core::int});
-  let final self::Class1? #t89 = c1 in #t89 == null ?{core::int?} null : let final self::Class2? #t90 = #t89{self::Class1}.{self::Class1::field}{self::Class2?} in #t90 == null ?{core::int?} null : let final core::int #t91 = 0 in self::Extension|[]=(#t90{self::Class2}, #t91, self::Extension|[](#t90{self::Class2}, #t91).{core::num::+}(1.{core::num::+}(let core::int? #t92 = let final self::Class2? #t93 = c2 in #t93 == null ?{core::int?} null : self::Extension|[](#t93{self::Class2}, 0)! in #t92.==(null) ?{core::int} #t92 as{ForNonNullableByDefault} core::int : #t92{core::int}){(core::num) → core::int}){(core::num) → core::int});
+  let final self::Class1? #t89 = c1 in #t89 == null ?{core::int?} null : let final self::Class2? #t90 = #t89{self::Class1}.{self::Class1::field}{self::Class2?} in #t90 == null ?{core::int?} null : let final core::int #t91 = 0 in self::Extension|[]=(#t90{self::Class2}, #t91, self::Extension|[](#t90{self::Class2}, #t91).{core::num::+}(1.{core::num::+}(let core::int? #t92 = let final self::Class2? #t93 = c2 in #t93 == null ?{core::int?} null : self::Extension|[](#t93{self::Class2}, 0)! in #t92 == null ?{core::int} #t92 as{ForNonNullableByDefault} core::int : #t92{core::int}){(core::num) → core::int}){(core::num) → core::int});
   let final self::Class1? #t94 = c1 in #t94 == null ?{core::int?} null : let final self::Class2? #t95 = #t94{self::Class1}.{self::Class1::field}{self::Class2?} in #t95 == null ?{core::int?} null : let final core::int #t96 = 0 in let final core::int #t97 = self::Extension|[](#t95{self::Class2}, #t96).{core::num::+}(1){(core::num) → core::int} in let final void #t98 = self::Extension|[]=(#t95{self::Class2}, #t96, #t97) in #t97;
   let final self::Class1? #t99 = c1 in #t99 == null ?{core::int?} null : let final self::Class2? #t100 = #t99{self::Class1}.{self::Class1::field}{self::Class2?} in #t100 == null ?{core::int?} null : let final core::int #t101 = 0 in self::Extension|[]=(#t100{self::Class2}, #t101, self::Extension|[](#t100{self::Class2}, #t101).{core::num::+}(1){(core::num) → core::int});
   let final self::Class1? #t102 = c1 in #t102 == null ?{core::int?} null : let final self::Class2? #t103 = #t102{self::Class1}.{self::Class1::field}{self::Class2?} in #t103 == null ?{core::int?} null : let final core::int #t104 = 0 in self::Extension|[](#t103{self::Class2}, #t104) == null ?{core::int} self::Extension|[]=(#t103{self::Class2}, #t104, 1) : null;
-  let final self::Class1? #t105 = c1 in #t105 == null ?{core::int?} null : let final self::Class2? #t106 = #t105{self::Class1}.{self::Class1::field}{self::Class2?} in #t106 == null ?{core::int?} null : let final core::int #t107 = 0 in self::Extension|[](#t106{self::Class2}, #t107) == null ?{core::int} self::Extension|[]=(#t106{self::Class2}, #t107, 1.{core::num::+}(let core::int? #t108 = let final self::Class2? #t109 = c2 in #t109 == null ?{core::int?} null : self::Extension|[](#t109{self::Class2}, 1)! in #t108.==(null) ?{core::int} #t108 as{ForNonNullableByDefault} core::int : #t108{core::int}){(core::num) → core::int}) : null;
+  let final self::Class1? #t105 = c1 in #t105 == null ?{core::int?} null : let final self::Class2? #t106 = #t105{self::Class1}.{self::Class1::field}{self::Class2?} in #t106 == null ?{core::int?} null : let final core::int #t107 = 0 in self::Extension|[](#t106{self::Class2}, #t107) == null ?{core::int} self::Extension|[]=(#t106{self::Class2}, #t107, 1.{core::num::+}(let core::int? #t108 = let final self::Class2? #t109 = c2 in #t109 == null ?{core::int?} null : self::Extension|[](#t109{self::Class2}, 1)! in #t108 == null ?{core::int} #t108 as{ForNonNullableByDefault} core::int : #t108{core::int}){(core::num) → core::int}) : null;
 }
 
 
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect
index c6dc621..11d4db7 100644
--- a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect
@@ -8,6 +8,6 @@
     : super core::Object::•()
     ;
   get current() → self::A::T%
-    return let self::A::T? #t1 = this.{self::A::_current}{self::A::T?} in #t1.==(null) ?{self::A::T%} #t1 as{ForNonNullableByDefault} self::A::T% : #t1{self::A::T%};
+    return let self::A::T? #t1 = this.{self::A::_current}{self::A::T?} in #t1 == null ?{self::A::T%} #t1 as{ForNonNullableByDefault} self::A::T% : #t1{self::A::T%};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect
index 6c634e1..c6d78f7 100644
--- a/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect
@@ -10,20 +10,20 @@
   method returnTypeVariable() → self::Class::E% {
     function #result#initializer() → self::Class::E%
       return this.{self::Class::field}{self::Class::E%};
-    late self::Class::E% result = #result#initializer.call();
+    late self::Class::E% result = #result#initializer(){() → self::Class::E%};
     return result;
   }
 }
 static method returnNonNullable(core::int value) → core::int {
   function #result#initializer() → core::int
     return value;
-  late core::int result = #result#initializer.call();
+  late core::int result = #result#initializer(){() → core::int};
   return result;
 }
 static method returnNullable(core::int? value) → core::int? {
   function #result#initializer() → core::int?
     return value;
-  late core::int? result = #result#initializer.call();
+  late core::int? result = #result#initializer(){() → core::int?};
   return result;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect
index 6c634e1..c6d78f7 100644
--- a/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect
@@ -10,20 +10,20 @@
   method returnTypeVariable() → self::Class::E% {
     function #result#initializer() → self::Class::E%
       return this.{self::Class::field}{self::Class::E%};
-    late self::Class::E% result = #result#initializer.call();
+    late self::Class::E% result = #result#initializer(){() → self::Class::E%};
     return result;
   }
 }
 static method returnNonNullable(core::int value) → core::int {
   function #result#initializer() → core::int
     return value;
-  late core::int result = #result#initializer.call();
+  late core::int result = #result#initializer(){() → core::int};
   return result;
 }
 static method returnNullable(core::int? value) → core::int? {
   function #result#initializer() → core::int?
     return value;
-  late core::int? result = #result#initializer.call();
+  late core::int? result = #result#initializer(){() → core::int?};
   return result;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 702dfef..81d9731 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -80,14 +80,14 @@
   core::print("foo");
   return let final Never #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
   return null; // error
-         ^" in let Null #t3 = null in #t3.==(null) ?{core::String} #t3 as{TypeError,ForNonNullableByDefault} core::String : #t3{core::String};
+         ^" in let Null #t3 = null in #t3 == null ?{core::String} #t3 as{TypeError,ForNonNullableByDefault} core::String : #t3{core::String};
 }
 static method returnMixed(core::bool b) → core::String {
   if(b) {
     core::print("foo");
     return let final Never #t4 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
     return null; // error
-           ^" in let Null #t5 = null in #t5.==(null) ?{core::String} #t5 as{TypeError,ForNonNullableByDefault} core::String : #t5{core::String};
+           ^" in let Null #t5 = null in #t5 == null ?{core::String} #t5 as{TypeError,ForNonNullableByDefault} core::String : #t5{core::String};
   }
   return let final Never #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:16:8: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
 String returnMixed(bool b) /*error*/ {
@@ -348,14 +348,14 @@
     core::print("foo");
     return let final Never #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
     return null; // error
-           ^" in let Null #t11 = null in #t11.==(null) ?{core::String} #t11 as{TypeError,ForNonNullableByDefault} core::String : #t11{core::String};
+           ^" in let Null #t11 = null in #t11 == null ?{core::String} #t11 as{TypeError,ForNonNullableByDefault} core::String : #t11{core::String};
   }
   function returnMixed(core::bool b) → core::String {
     if(b) {
       core::print("foo");
       return let final Never #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
       return null; // error
-             ^" in let Null #t13 = null in #t13.==(null) ?{core::String} #t13 as{TypeError,ForNonNullableByDefault} core::String : #t13{core::String};
+             ^" in let Null #t13 = null in #t13 == null ?{core::String} #t13 as{TypeError,ForNonNullableByDefault} core::String : #t13{core::String};
     }
     return let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
   String returnMixed(bool b) /* error */ {
@@ -630,16 +630,16 @@
 }
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:13:10 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///return_null.dart:13:10 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:13:10 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:13:10 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:19:12 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///return_null.dart:19:12 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:19:12 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:19:12 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:69:12 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///return_null.dart:69:12 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:69:12 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:69:12 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:75:14 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///return_null.dart:75:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
 Extra constant evaluation: evaluated: 380, effectively constant: 12
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
index 09857e0..39b2ea0 100644
--- a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
@@ -57,7 +57,7 @@
 static method foo<T extends self::C?>(self::C? c, self::foo::T% t, self::foo::T? nt) → dynamic {
   self::functionContext(let final Never #t1 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:14:24: Error: Can't tear off method 'call' from a potentially null value.
   functionContext(null as C?); // Error.
-                       ^" in let Null #t2 = null in #t2.==(null) ?{() → core::int} #t2 as{TypeError} () → core::int : #t2{() → core::int});
+                       ^" in let Null #t2 = null in #t2 == null ?{() → core::int} #t2 as{TypeError} () → core::int : #t2{() → core::int});
   self::nullableFunctionContext(let final Never #t3 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:15:32: Error: Can't tear off method 'call' from a potentially null value.
   nullableFunctionContext(null as C?); // Error.
                                ^" in null);
@@ -94,7 +94,7 @@
 
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///tearoff_from_nullable_receiver.dart:14:24 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///tearoff_from_nullable_receiver.dart:14:24 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///tearoff_from_nullable_receiver.dart:14:24 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///tearoff_from_nullable_receiver.dart:14:24 -> NullConstant(null)
 Extra constant evaluation: evaluated: 58, effectively constant: 3
diff --git a/pkg/front_end/testcases/nnbd/type_constraint_solving_closures_in_upper_and_lower_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/type_constraint_solving_closures_in_upper_and_lower_bounds.dart.strong.transformed.expect
index f05ca02..680f436 100644
--- a/pkg/front_end/testcases/nnbd/type_constraint_solving_closures_in_upper_and_lower_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/type_constraint_solving_closures_in_upper_and_lower_bounds.dart.strong.transformed.expect
@@ -15,7 +15,7 @@
     ;
 }
 static method check<T extends core::Object? = dynamic>(self::C<core::List<self::check::T%>> f) → self::check::T% {
-  return let Null #t1 = null in #t1.==(null) ?{self::check::T%} #t1 as{ForNonNullableByDefault} self::check::T% : #t1{self::check::T%};
+  return let Null #t1 = null in #t1 == null ?{self::check::T%} #t1 as{ForNonNullableByDefault} self::check::T% : #t1{self::check::T%};
 }
 static method test() → void {
   core::int x = self::check<core::int>(new self::C::•<core::List<core::int>>((core::List<core::int> x) → void {}));
@@ -27,7 +27,7 @@
 
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///type_constraint_solving_closures_in_upper_and_lower_bounds.dart:10:3 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///type_constraint_solving_closures_in_upper_and_lower_bounds.dart:10:3 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///type_constraint_solving_closures_in_upper_and_lower_bounds.dart:10:15 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///type_constraint_solving_closures_in_upper_and_lower_bounds.dart:10:3 -> NullConstant(null)
 Extra constant evaluation: evaluated: 12, effectively constant: 3
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
index af7457b..aab83a3 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
@@ -24,12 +24,12 @@
   FutureOr<() → opt::A*>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAlias> foLegacyNonNullable = null; // error
-                                         ^" in let Null #t2 = null in #t2.==(null) ?{FutureOr<() → opt::A*>} #t2 as{TypeError,ForNonNullableByDefault} FutureOr<() → opt::A*> : #t2{FutureOr<() → opt::A*>};
+                                         ^" in let Null #t2 = null in #t2 == null ?{FutureOr<() → opt::A*>} #t2 as{TypeError,ForNonNullableByDefault} FutureOr<() → opt::A*> : #t2{FutureOr<() → opt::A*>};
   FutureOr<() →? opt::A*>foLegacyNullable = null;
   FutureOr<opt::A>foNonNullable = let final Never #t3 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAliasNonNullable> foNonNullable = null; // error
-                                              ^" in let Null #t4 = null in #t4.==(null) ?{FutureOr<opt::A>} #t4 as{TypeError,ForNonNullableByDefault} FutureOr<opt::A> : #t4{FutureOr<opt::A>};
+                                              ^" in let Null #t4 = null in #t4 == null ?{FutureOr<opt::A>} #t4 as{TypeError,ForNonNullableByDefault} FutureOr<opt::A> : #t4{FutureOr<opt::A>};
   FutureOr<opt::A?>foNullable = null;
   FutureOr<opt::A?>foNonNullableNullable = null;
   FutureOr<opt::A?>foNullableNullable = null;
@@ -74,10 +74,10 @@
 
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41501.dart:13:42 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///issue41501.dart:13:42 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41501.dart:13:42 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41501.dart:13:42 -> NullConstant(null)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41501.dart:15:47 -> BoolConstant(true)
+Evaluated: EqualsNull @ org-dartlang-testcase:///issue41501.dart:15:47 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41501.dart:15:47 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41501.dart:15:47 -> NullConstant(null)
 Extra constant evaluation: evaluated: 14, effectively constant: 6
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index d27c23d..30586c4 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -757,8 +757,8 @@
         if (lastToken == '=>') {
           lastCategory = ARROW;
         } else {
-          int binaryPrecendence = BINARY_PRECEDENCE[lastToken];
-          if (binaryPrecendence == null &&
+          int binaryPrecedence = BINARY_PRECEDENCE[lastToken];
+          if (binaryPrecedence == null &&
               !UNARY_OPERATORS.contains(lastToken)) {
             error("Unknown operator");
           }
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 2242961..8dcc958 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -1306,6 +1306,7 @@
 
   @override
   visitMethodDefinition(MethodDefinition node) {
+    propertyNameOut(node);
     VarCollector vars = new VarCollector();
     vars.visitMethodDefinition(node);
     startNode(node.function);
@@ -1315,7 +1316,6 @@
 
   int methodOut(MethodDefinition node, VarCollector vars) {
     // TODO: support static, get/set, async, and generators.
-    propertyNameOut(node);
     Fun fun = node.function;
     localNamer.enterScope(vars);
     out("(");
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 74461fa..cc4d1387 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -155,24 +155,14 @@
   ConstructorInvocation _constructLocation(
     Location location, {
     String? name,
-    ListLiteral? parameterLocations,
-    bool showFile: true,
   }) {
     final List<NamedExpression> arguments = <NamedExpression>[
+      new NamedExpression('file', new StringLiteral(location.file.toString())),
       new NamedExpression('line', new IntLiteral(location.line)),
       new NamedExpression('column', new IntLiteral(location.column)),
+      if (name != null) new NamedExpression('name', new StringLiteral(name))
     ];
-    if (showFile) {
-      arguments.add(new NamedExpression(
-          'file', new StringLiteral(location.file.toString())));
-    }
-    if (name != null) {
-      arguments.add(new NamedExpression('name', new StringLiteral(name)));
-    }
-    if (parameterLocations != null) {
-      arguments
-          .add(new NamedExpression('parameterLocations', parameterLocations));
-    }
+
     return new ConstructorInvocation(
       _locationClass.constructors.first,
       new Arguments(<Expression>[], named: arguments),
@@ -240,8 +230,11 @@
   }
 
   Expression _computeLocation(
-      InvocationExpression node, FunctionNode function, Class constructedClass,
-      {bool isConst: false}) {
+    InvocationExpression node,
+    FunctionNode function,
+    Class constructedClass, {
+    bool isConst: false,
+  }) {
     // For factory constructors we need to use the location specified as an
     // argument to the factory constructor rather than the location
     if (_currentFactory != null &&
@@ -260,35 +253,9 @@
       }
     }
 
-    final Arguments arguments = node.arguments;
-    final Location location = node.location!;
-    final List<ConstructorInvocation> parameterLocations =
-        <ConstructorInvocation>[];
-    final List<VariableDeclaration> parameters = function.positionalParameters;
-    for (int i = 0; i < arguments.positional.length; ++i) {
-      final Expression expression = arguments.positional[i];
-      final VariableDeclaration parameter = parameters[i];
-      parameterLocations.add(_constructLocation(
-        expression.location!,
-        name: parameter.name,
-        showFile: false,
-      ));
-    }
-    for (NamedExpression expression in arguments.named) {
-      parameterLocations.add(_constructLocation(
-        expression.location!,
-        name: expression.name,
-        showFile: false,
-      ));
-    }
     return _constructLocation(
-      location,
-      parameterLocations: new ListLiteral(
-        parameterLocations,
-        typeArgument:
-            new InterfaceType(_locationClass, _currentLibrary!.nonNullable),
-        isConst: true,
-      ),
+      node.location!,
+      name: constructedClass.name,
     );
   }
 
diff --git a/pkg/kernel/lib/transformations/type_casts_optimizer.dart b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
index 3ddbb77..759365d 100644
--- a/pkg/kernel/lib/transformations/type_casts_optimizer.dart
+++ b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
@@ -35,8 +35,7 @@
     return Let(
         tmp,
         ConditionalExpression(
-            MethodInvocation(
-                VariableGet(tmp), Name('=='), Arguments([NullLiteral()])),
+            EqualsNull(VariableGet(tmp)),
             AsExpression(VariableGet(tmp), dstType)
               ..flags = node.flags
               ..fileOffset = node.fileOffset,
diff --git a/pkg/vm/lib/transformations/late_var_init_transformer.dart b/pkg/vm/lib/transformations/late_var_init_transformer.dart
index 88d8a25..7d245f1 100644
--- a/pkg/vm/lib/transformations/late_var_init_transformer.dart
+++ b/pkg/vm/lib/transformations/late_var_init_transformer.dart
@@ -38,13 +38,14 @@
   List<Statement> _transformVariableDeclaration(VariableDeclaration node) {
     final fnNode =
         FunctionNode(ReturnStatement(node.initializer), returnType: node.type);
+    final functionType =
+        fnNode.computeThisFunctionType(Nullability.nonNullable);
     final fn = FunctionDeclaration(
-        VariableDeclaration("#${node.name}#initializer",
-            type: fnNode.computeThisFunctionType(Nullability.legacy)),
+        VariableDeclaration("#${node.name}#initializer", type: functionType),
         fnNode);
-    node.initializer =
-        MethodInvocation(VariableGet(fn.variable), Name("call"), Arguments([]))
-          ..parent = node;
+    node.initializer = LocalFunctionInvocation(fn.variable, Arguments([]),
+        functionType: functionType)
+      ..parent = node;
 
     return [fn, node];
   }
diff --git a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
index c1f616d..65e79ac 100644
--- a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
+++ b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
@@ -6,6 +6,7 @@
 import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
 import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/library_index.dart' show LibraryIndex;
+import 'package:kernel/type_algebra.dart' show Substitution;
 
 import 'utils.dart';
 
@@ -42,6 +43,10 @@
   final Field _tagNumberField;
   final Class _builderInfoClass;
   final Procedure _builderInfoAddMethod;
+
+  // Type of BuilderInfo.add<Null>().
+  FunctionType _typeOfBuilderInfoAddOfNull;
+
   final _messageClasses = <Class, _MessageClass>{};
   final _invalidatedClasses = <_MessageClass>{};
 
@@ -66,7 +71,12 @@
         _builderInfoClass =
             libraryIndex.getClass(protobufLibraryUri, 'BuilderInfo'),
         _builderInfoAddMethod =
-            libraryIndex.getMember(protobufLibraryUri, 'BuilderInfo', 'add');
+            libraryIndex.getMember(protobufLibraryUri, 'BuilderInfo', 'add') {
+    final functionType = _builderInfoAddMethod.getterType as FunctionType;
+    _typeOfBuilderInfoAddOfNull = Substitution.fromPairs(
+            functionType.typeParameters, const <DartType>[NullType()])
+        .substituteType(functionType.withoutTypeParameters) as FunctionType;
+  }
 
   bool usesAnnotationClass(Class cls) => cls == _tagNumberClass;
 
@@ -191,7 +201,8 @@
     // removing a field.
     // Change the tag-number to 0. Otherwise the decoder will get confused.
     ++numberOfFieldsPruned;
-    return MethodInvocation(
+    return InstanceInvocation(
+        InstanceAccessKind.Instance,
         node.receiver,
         ph._builderInfoAddMethod.name,
         Arguments(
@@ -204,9 +215,10 @@
             NullLiteral(), // valueOf
             NullLiteral(), // enumValues
           ],
-          types: <DartType>[const NullType()],
+          types: const <DartType>[NullType()],
         ),
-        ph._builderInfoAddMethod)
+        interfaceTarget: ph._builderInfoAddMethod,
+        functionType: ph._typeOfBuilderInfoAddOfNull)
       ..fileOffset = node.fileOffset;
   }
 
@@ -221,7 +233,8 @@
     // removing a field.
     // Change the tag-number to 0. Otherwise the decoder will get confused.
     ++numberOfFieldsPruned;
-    return MethodInvocation(
+    return InstanceInvocation(
+        InstanceAccessKind.Instance,
         node.receiver,
         ph._builderInfoAddMethod.name,
         Arguments(
@@ -236,7 +249,8 @@
           ],
           types: <DartType>[const NullType()],
         ),
-        ph._builderInfoAddMethod)
+        interfaceTarget: ph._builderInfoAddMethod,
+        functionType: ph._typeOfBuilderInfoAddOfNull)
       ..fileOffset = node.fileOffset;
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
index 82c3315..9dae16a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
@@ -37,9 +37,9 @@
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>((#C1) ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, keyFieldType: core::int?, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueFieldType: core::int?, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
@@ -82,7 +82,7 @@
 class BarKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
   constructor _() → self::BarKeep
@@ -105,7 +105,7 @@
 }
 class HasKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
   constructor _() → self::HasKeep
@@ -119,7 +119,7 @@
 }
 class ClearKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
   constructor _() → self::ClearKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
index ebe6ac2..133c846 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
@@ -30,9 +30,9 @@
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep", createEmptyInstance: #C2) in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>((#C1) ?{core::String} "" : "mapKeep", #C3){(core::int, core::String, {entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, keyFieldType: core::int?, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueFieldType: core::int?, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C5){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
@@ -69,7 +69,7 @@
 class BarKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep", createEmptyInstance: #C3) in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
   constructor _() → self::BarKeep
@@ -86,7 +86,7 @@
 }
 class HasKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep", createEmptyInstance: #C4) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
   constructor _() → self::HasKeep
@@ -100,7 +100,7 @@
 }
 class ClearKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t5 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep", createEmptyInstance: #C5) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t5;
   constructor _() → self::ClearKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
index 4720666..f223e18 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
@@ -44,7 +44,7 @@
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, (#C1) ?{core::String} "" : "mapKeep", "FooKeep.MapKeepEntry", "mapKeep", #C2){(core::int, core::String, {entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, keyFieldType: core::int?, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueFieldType: core::int?, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::ZopDrop>(4, (#C1) ?{core::String} "" : "mapDrop", "FooKeep.MapDropEntry", "mapDrop", #C3){(core::int, core::String, {entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, keyFieldType: core::int?, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueFieldType: core::int?, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep", "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
@@ -112,7 +112,7 @@
 }
 class HasKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
   constructor _() → self::HasKeep
@@ -128,7 +128,7 @@
 }
 class ClearKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
   constructor _() → self::ClearKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
index 45194d5..ee0cdfc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
@@ -40,9 +40,9 @@
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>((#C1) ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, keyFieldType: core::int?, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueFieldType: core::int?, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
@@ -85,7 +85,7 @@
 class BarKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
   constructor _() → self::BarKeep
@@ -108,7 +108,7 @@
 }
 class HasKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
   constructor _() → self::HasKeep
@@ -122,7 +122,7 @@
 }
 class ClearKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
   constructor _() → self::ClearKeep
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 6f7c808..7c31513 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -493,49 +493,81 @@
   /// Splits the string at matches of [pattern] and returns a list of substrings.
   ///
   /// Finds all the matches of `pattern` in this string,
-  /// and returns the list of the substrings between the matches.
+  /// as by using [Pattern.allMatches],
+  /// and returns the list of the substrings between the matches,
+  /// before the first match, and after the last match.
   /// ```dart
   /// var string = "Hello world!";
-  /// string.split(" ");                      // ['Hello', 'world!'];
+  /// string.split(" ");                      // ["Hello", "world!"];
   /// ```
-  /// Empty matches at the beginning and end of the strings are ignored,
-  /// and so are empty matches right after another match.
+  /// If the pattern doesn't match this string at all,
+  /// the result is always a list containing only the original string.
+  ///
+  /// If the [pattern] is a [String], then it's always the case that:
+  /// ```dart
+  /// string.split(pattern).join(pattern) == string
+  /// ```
+  ///
+  /// If the first match is an empty match at the start of the string,
+  /// the empty substring before it is not included in the result.
+  /// If the last match is an empty match at the end of the string,
+  /// the empty substring after it is not included in the result.
+  /// If a match is empty, and it immediately follows a previous
+  /// match (it starts at the position where the previous match ended),
+  /// then the empty substring between the two matches is not
+  /// included in the result.
   /// ```dart
   /// var string = "abba";
-  /// // Matches:   ^^ ^^
-  /// string.split(RegExp(r"b*"));        // ['a', 'a']
-  ///                                         // not ['', 'a', 'a', '']
-  ///                                         // not ['a', '', 'a']
+  /// var re = RegExp(r"b*");
+  /// // re.allMatches(string) will find four matches:
+  /// // * empty match before first "a".
+  /// // * match of "bb"
+  /// // * empty match after "bb", before second "a"
+  /// // * empty match after second "a".
+  /// print(string.split(re));  // ["a", "a"]
   /// ```
-  /// If this string is empty, the result is an empty list if `pattern` matches
-  /// the empty string, and it is `[""]` if the pattern doesn't match.
+  ///
+  /// A non-empty match at the start or end of the string, or after another
+  /// match, is not treated specially, and will introduce empty substrings
+  /// in the result:
   /// ```dart
-  /// var string = '';
-  /// string.split('');                       // []
-  /// string.split("a");                      // ['']
+  /// var string = "abbaa";
+  /// string.split("a"); // ["", "bb", "", ""]
   /// ```
+  ///
+  /// If this string is the empty string, the result is an empty list
+  /// if `pattern` matches the empty string, since the empty string
+  /// before and after the first-and-last empty match are not included.
+  /// (It is still a list containing the original empty string `[""]`
+  /// if the pattern doesn't match).
+  /// ```dart
+  /// var string = "";
+  /// string.split("");                       // []
+  /// string.split("a");                      // [""]
+  /// ```
+  ///
   /// Splitting with an empty pattern splits the string into single-code unit
   /// strings.
   /// ```dart
-  /// var string = 'Pub';
-  /// string.split('');                       // ['P', 'u', 'b']
-  ///
-  /// string.codeUnits.map((unit) {
-  ///   return String.fromCharCode(unit);
-  /// }).toList();                            // ['P', 'u', 'b']
+  /// var string = "Pub";
+  /// string.split("");                       // ["P", "u", "b"]
+  /// // Same as:
+  /// [for (var unit in string.codeUnits)
+  ///     String.fromCharCode(unit)]          // ["P", "u", "b"]
   /// ```
+  ///
   /// Splitting happens at UTF-16 code unit boundaries,
-  /// and not at rune boundaries:
+  /// and not at rune (Unicode code point) boundaries:
   /// ```dart
   /// // String made up of two code units, but one rune.
   /// string = '\u{1D11E}';
-  /// string.split('').length;                 // 2 surrogate values
+  /// string.split('')  // ["\ud834", "\udd1e"] - 2 unpaired surrogate values
   /// ```
   /// To get a list of strings containing the individual runes of a string,
-  /// you should not use split. You can instead map each rune to a string
-  /// as follows:
+  /// you should not use split.
+  /// You can instead get a string for each rune as follows:
   /// ```dart
-  /// string.runes.map((rune) => String.fromCharCode(rune)).toList();
+  /// [for (var run in string.runes) String.fromCharCode(rune)]
   /// ```
   List<String> split(Pattern pattern);
 
@@ -544,18 +576,24 @@
   ///
   /// The [pattern] is used to split the string
   /// into parts and separating matches.
+  /// Each match of [Pattern.allMatches] of [pattern] on this string is
+  /// used as a match, and the substrings between the end of one match
+  /// (or the start of the string) and the start of the next match (or the
+  /// end of the string) is treated as a non-matched part.
+  /// (There is no omission of leading or trailing empty matchs, like
+  /// in [split], all matches and parts between the are included.)
   ///
   /// Each match is converted to a string by calling [onMatch]. If [onMatch]
   /// is omitted, the matched substring is used.
   ///
-  /// Each non-matched part is converted by a call to [onNonMatch]. If
-  /// [onNonMatch] is omitted, the non-matching substring is used.
+  /// Each non-matched part is converted to a string by a call to [onNonMatch].
+  /// If [onNonMatch] is omitted, the non-matching substring itself is used.
   ///
-  /// Then all the converted parts are combined into the resulting string.
+  /// Then all the converted parts are concatenated into the resulting string.
   /// ```dart
   /// 'Eats shoots leaves'.splitMapJoin((RegExp(r'shoots')),
-  ///     onMatch:    (m) => '${m[0]!}',  // or no onMatch at all
-  ///     onNonMatch: (n) => '*'); // *shoots*
+  ///     onMatch:    (m) => '${m[0]}',  // (or no onMatch at all)
+  ///     onNonMatch: (n) => '*'); // Result: "*shoots*"
   /// ```
   String splitMapJoin(Pattern pattern,
       {String Function(Match)? onMatch, String Function(String)? onNonMatch});
diff --git a/tools/VERSION b/tools/VERSION
index 21694021..d90890e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 211
+PRERELEASE 212
 PRERELEASE_PATCH 0
\ No newline at end of file