Version 2.14.0-361.0.dev

Merge commit '9397b8ff055b3b97275e17aaf651bbb176b2b306' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 3555b29..771e607 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -6583,9 +6583,7 @@
               arguments))
         ..fileOffset = receiver.fileOffset;
     } else {
-      MethodInvocation node =
-          forest.createMethodInvocation(offset, receiver, name, arguments);
-      return node;
+      return forest.createMethodInvocation(offset, receiver, name, arguments);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 5333b0c..82dbe5c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -752,7 +752,7 @@
   Expression buildSimpleRead() {
     VariableDeclarationImpl variable =
         _helper.createVariableDeclarationForValue(receiverExpression);
-    PropertyGet read = _forest.createPropertyGet(
+    Expression read = _forest.createPropertyGet(
         fileOffset,
         _helper.createVariableGet(variable, receiverExpression.fileOffset,
             forNullGuardedAccess: true),
@@ -765,7 +765,7 @@
   Expression buildAssignment(Expression value, {bool voidContext = false}) {
     VariableDeclarationImpl variable =
         _helper.createVariableDeclarationForValue(receiverExpression);
-    PropertySet read = _helper.forest.createPropertySet(
+    Expression read = _helper.forest.createPropertySet(
         fileOffset,
         _helper.createVariableGet(variable, receiverExpression.fileOffset,
             forNullGuardedAccess: true),
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 8ba13f0..9dc0296 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -722,11 +722,11 @@
       ..fileOffset = fileOffset;
   }
 
-  MethodInvocation createMethodInvocation(
+  Expression createMethodInvocation(
       int fileOffset, Expression expression, Name name, Arguments arguments) {
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
-    return new MethodInvocation(expression, name, arguments)
+    return new InternalMethodInvocation(expression, name, arguments)
       ..fileOffset = fileOffset;
   }
 
@@ -758,19 +758,18 @@
     return new NullCheck(expression)..fileOffset = fileOffset;
   }
 
-  PropertyGet createPropertyGet(
-      int fileOffset, Expression receiver, Name name) {
+  Expression createPropertyGet(int fileOffset, Expression receiver, Name name) {
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
-    return new PropertyGet(receiver, name)..fileOffset = fileOffset;
+    return new InternalPropertyGet(receiver, name)..fileOffset = fileOffset;
   }
 
-  PropertySet createPropertySet(
+  Expression createPropertySet(
       int fileOffset, Expression receiver, Name name, Expression value,
       {required bool forEffect, bool readOnlyReceiver: false}) {
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
-    return new PropertySetImpl(receiver, name, value,
+    return new InternalPropertySet(receiver, name, value,
         forEffect: forEffect, readOnlyReceiver: readOnlyReceiver)
       ..fileOffset = fileOffset;
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 946ce03..719356e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -322,7 +322,7 @@
   }
 
   @override
-  void visitInvalidInitializer(Initializer node) {
+  void visitInvalidInitializer(InvalidInitializer node) {
     _unhandledInitializer(node);
   }
 
@@ -1112,6 +1112,8 @@
       return new LocalForInVariable(syntheticAssignment);
     } else if (syntheticAssignment is PropertySet) {
       return new PropertyForInVariable(syntheticAssignment);
+    } else if (syntheticAssignment is InternalPropertySet) {
+      return new InternalPropertyForInVariable(syntheticAssignment);
     } else if (syntheticAssignment is SuperPropertySet) {
       return new SuperPropertyForInVariable(syntheticAssignment);
     } else if (syntheticAssignment is StaticSet) {
@@ -2820,6 +2822,19 @@
         isExpressionInvocation: false, isImplicitCall: false);
   }
 
+  ExpressionInferenceResult visitInternalMethodInvocation(
+      InternalMethodInvocation node, DartType typeContext) {
+    assert(node.name != unaryMinusName);
+    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
+        node.receiver, const UnknownType(), true);
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    Expression receiver = result.nullAwareAction;
+    DartType receiverType = result.nullAwareActionType;
+    return inferrer.inferMethodInvocation(node.fileOffset, nullAwareGuards,
+        receiver, receiverType, node.name, node.arguments, typeContext,
+        isExpressionInvocation: false, isImplicitCall: false);
+  }
+
   ExpressionInferenceResult visitExpressionInvocation(
       ExpressionInvocation node, DartType typeContext) {
     ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
@@ -5900,6 +5915,44 @@
         rhsType, replacement, nullAwareGuards);
   }
 
+  ExpressionInferenceResult visitInternalPropertySet(
+      InternalPropertySet node, DartType typeContext) {
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+        isVoidAllowed: false);
+
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
+
+    ObjectAccessTarget target = inferrer.findInterfaceMember(
+        receiverType, node.name, node.fileOffset,
+        setter: true, instrumented: true, includeExtensionMethods: true);
+    if (target.isInstanceMember || target.isObjectMember) {
+      if (inferrer.instrumentation != null &&
+          receiverType == const DynamicType()) {
+        inferrer.instrumentation!.record(
+            inferrer.uriForInstrumentation,
+            node.fileOffset,
+            'target',
+            new InstrumentationValueForMember(target.member!));
+      }
+    }
+    DartType writeContext = inferrer.getSetterType(target, receiverType);
+    ExpressionInferenceResult rhsResult = inferrer
+        .inferExpression(node.value, writeContext, true, isVoidAllowed: true);
+    DartType rhsType = rhsResult.inferredType;
+    Expression rhs = inferrer.ensureAssignableResult(writeContext, rhsResult,
+        fileOffset: node.fileOffset, isVoidAllowed: writeContext is VoidType);
+
+    Expression replacement = _computePropertySet(
+        node.fileOffset, receiver, receiverType, node.name, target, rhs,
+        valueType: rhsType, forEffect: node.forEffect);
+
+    return inferrer.createNullAwareExpressionInferenceResult(
+        rhsType, replacement, nullAwareGuards);
+  }
+
   ExpressionInferenceResult visitNullAwareIfNullSet(
       NullAwareIfNullSet node, DartType typeContext) {
     ExpressionInferenceResult receiverResult = inferrer
@@ -6030,6 +6083,31 @@
     return expressionInferenceResult;
   }
 
+  ExpressionInferenceResult visitInternalPropertyGet(
+      InternalPropertyGet node, DartType typeContext) {
+    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
+        node.receiver, const UnknownType(), true);
+
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    Expression receiver = result.nullAwareAction;
+    DartType receiverType = result.nullAwareActionType;
+
+    node.receiver = receiver..parent = node;
+    PropertyGetInferenceResult propertyGetInferenceResult = _computePropertyGet(
+        node.fileOffset, receiver, receiverType, node.name, typeContext,
+        isThisReceiver: node.receiver is ThisExpression);
+    ExpressionInferenceResult readResult =
+        propertyGetInferenceResult.expressionInferenceResult;
+    inferrer.flowAnalysis.propertyGet(node, node.receiver, node.name.text,
+        propertyGetInferenceResult.member, readResult.inferredType);
+    ExpressionInferenceResult expressionInferenceResult =
+        inferrer.createNullAwareExpressionInferenceResult(
+            readResult.inferredType, readResult.expression, nullAwareGuards);
+    inferrer.flowAnalysis
+        .forwardExpression(expressionInferenceResult.nullAwareAction, node);
+    return expressionInferenceResult;
+  }
+
   @override
   void visitRedirectingInitializer(RedirectingInitializer node) {
     inferrer.inferConstructorParameterTypes(node.target);
@@ -7316,6 +7394,69 @@
   }
 }
 
+class InternalPropertyForInVariable implements ForInVariable {
+  final InternalPropertySet propertySet;
+
+  DartType? _writeType;
+
+  Expression? _rhs;
+
+  InternalPropertyForInVariable(this.propertySet);
+
+  @override
+  DartType computeElementType(TypeInferrerImpl inferrer) {
+    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+        propertySet.receiver, const UnknownType(), true);
+    propertySet.receiver = receiverResult.expression..parent = propertySet;
+    DartType receiverType = receiverResult.inferredType;
+    ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+        receiverType, propertySet.name, propertySet.fileOffset,
+        setter: true, instrumented: true, includeExtensionMethods: true);
+    DartType elementType =
+    _writeType = inferrer.getSetterType(writeTarget, receiverType);
+    Expression? error = inferrer.reportMissingInterfaceMember(
+        writeTarget,
+        receiverType,
+        propertySet.name,
+        propertySet.fileOffset,
+        templateUndefinedSetter);
+    if (error != null) {
+      _rhs = error;
+    } else {
+      if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
+        if (inferrer.instrumentation != null &&
+            receiverType == const DynamicType()) {
+          inferrer.instrumentation!.record(
+              inferrer.uriForInstrumentation,
+              propertySet.fileOffset,
+              'target',
+              new InstrumentationValueForMember(writeTarget.member!));
+        }
+      }
+      _rhs = propertySet.value;
+    }
+    return elementType;
+  }
+
+  @override
+  Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
+    Expression rhs = inferrer.ensureAssignable(
+        inferrer.computeGreatestClosure(_writeType!), rhsType, _rhs!,
+        errorTemplate: templateForInLoopElementTypeNotAssignable,
+        nullabilityErrorTemplate:
+        templateForInLoopElementTypeNotAssignableNullability,
+        nullabilityPartErrorTemplate:
+        templateForInLoopElementTypeNotAssignablePartNullability,
+        isVoidAllowed: true);
+
+    propertySet.value = rhs..parent = propertySet;
+    ExpressionInferenceResult result = inferrer.inferExpression(
+        propertySet, const UnknownType(), !inferrer.isTopLevel,
+        isVoidAllowed: true);
+    return result.expression;
+  }
+}
+
 class SuperPropertyForInVariable implements ForInVariable {
   final SuperPropertySet superPropertySet;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 749419c..9389905 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -422,6 +422,7 @@
   IndexSet,
   LoadLibraryTearOff,
   LocalPostIncDec,
+  MethodInvocation,
   NullAwareCompoundSet,
   NullAwareExtension,
   NullAwareIfNullSet,
@@ -429,7 +430,9 @@
   NullAwarePropertyGet,
   NullAwarePropertySet,
   Parenthesized,
+  PropertyGet,
   PropertyPostIncDec,
+  PropertySet,
   StaticPostIncDec,
   SuperIndexSet,
   SuperPostIncDec,
@@ -442,16 +445,19 @@
 
   @override
   R accept<R>(ExpressionVisitor<R> visitor) {
-    if (visitor is Printer || visitor is Precedence) {
-      // Allow visitors needed for toString.
+    if (visitor is Printer || visitor is Precedence || visitor is Transformer) {
+      // Allow visitors needed for toString and replaceWith.
       return visitor.defaultExpression(this);
     }
-    return unsupported("${runtimeType}.accept", -1, null);
+    return unsupported(
+        "${runtimeType}.accept on ${visitor.runtimeType}", -1, null);
   }
 
   @override
-  R accept1<R, A>(ExpressionVisitor1<R, A> visitor, A arg) =>
-      unsupported("${runtimeType}.accept1", -1, null);
+  R accept1<R, A>(ExpressionVisitor1<R, A> visitor, A arg) {
+    return unsupported(
+        "${runtimeType}.accept1 on ${visitor.runtimeType}", -1, null);
+  }
 
   @override
   DartType getStaticType(StaticTypeContext context) =>
@@ -1341,14 +1347,13 @@
   @override
   void toTextInternal(AstPrinter printer) {
     Expression propertyGet = read;
-    if (propertyGet is PropertyGet) {
+    if (propertyGet is InternalPropertyGet) {
       Expression receiver = propertyGet.receiver;
       if (receiver is VariableGet && receiver.variable == variable) {
         // Special-case the usual use of this node.
         printer.writeExpression(variable.initializer!);
         printer.write('?.');
-        printer.writeInterfaceMemberName(
-            propertyGet.interfaceTargetReference, propertyGet.name);
+        printer.writeName(propertyGet.name);
         return;
       }
     }
@@ -4524,3 +4529,244 @@
   }
   throw new UnsupportedError("Clone not supported for ${node.runtimeType}.");
 }
+
+/// A dynamically bound method invocation of the form `o.foo()`.
+///
+/// This will be transformed into an [InstanceInvocation], [DynamicInvocation],
+/// [FunctionInvocation] or [StaticInvocation] (for implicit extension method
+/// invocation) after type inference.
+// TODO(johnniwinther): Rename to `MethodInvocation` when [MethodInvocation]
+// has been removed.
+class InternalMethodInvocation extends InternalExpression {
+  Expression receiver;
+
+  Name name;
+
+  Arguments arguments;
+
+  InternalMethodInvocation(this.receiver, this.name, this.arguments)
+      // ignore: unnecessary_null_comparison
+      : assert(receiver != null),
+        // ignore: unnecessary_null_comparison
+        assert(arguments != null) {
+    receiver.parent = this;
+    arguments.parent = this;
+  }
+
+  @override
+  ExpressionInferenceResult acceptInference(
+      InferenceVisitor visitor, DartType typeContext) {
+    return visitor.visitInternalMethodInvocation(this, typeContext);
+  }
+
+  @override
+  InternalExpressionKind get kind => InternalExpressionKind.MethodInvocation;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    receiver.accept(v);
+    arguments.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (arguments != null) {
+      arguments = v.transform(arguments);
+      arguments.parent = this;
+    }
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (arguments != null) {
+      arguments = v.transform(arguments);
+      arguments.parent = this;
+    }
+  }
+
+  @override
+  String toString() {
+    return "InternalMethodInvocation(${toStringInternal()})";
+  }
+
+  @override
+  int get precedence => Precedence.PRIMARY;
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver, minimumPrecedence: Precedence.PRIMARY);
+    printer.write('.');
+    printer.writeName(name);
+    printer.writeArguments(arguments);
+  }
+}
+
+/// A dynamically bound property read of the form `o.foo`.
+///
+/// This will be transformed into an [InstanceGet], [InstanceTearOff],
+/// [DynamicGet], [FunctionTearOff] or [StaticInvocation] (for implicit
+/// extension member access) after type inference.
+// TODO(johnniwinther): Rename to `PropertyGet` when [PropertyGet]
+// has been removed.
+class InternalPropertyGet extends InternalExpression {
+  Expression receiver;
+
+  Name name;
+
+  InternalPropertyGet(this.receiver, this.name)
+      // ignore: unnecessary_null_comparison
+      : assert(receiver != null) {
+    receiver.parent = this;
+  }
+
+  @override
+  ExpressionInferenceResult acceptInference(
+      InferenceVisitor visitor, DartType typeContext) {
+    return visitor.visitInternalPropertyGet(this, typeContext);
+  }
+
+  @override
+  InternalExpressionKind get kind => InternalExpressionKind.PropertyGet;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    receiver.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+  }
+
+  @override
+  String toString() {
+    return "InternalPropertyGet(${toStringInternal()})";
+  }
+
+  @override
+  int get precedence => Precedence.PRIMARY;
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver, minimumPrecedence: Precedence.PRIMARY);
+    printer.write('.');
+    printer.writeName(name);
+  }
+}
+
+/// A dynamically bound property write of the form `o.foo = e`.
+///
+/// This will be transformed into an [InstanceSet], [DynamicSet], or
+/// [StaticInvocation] (for implicit extension member access) after type
+/// inference.
+// TODO(johnniwinther): Rename to `PropertySet` when [PropertySet]
+// has been removed.
+class InternalPropertySet extends InternalExpression {
+  Expression receiver;
+  Name name;
+  Expression value;
+
+  /// If `true` the assignment is need for its effect and not for its value.
+  final bool forEffect;
+
+  /// If `true` the receiver can be cloned and doesn't need a temporary variable
+  /// for multiple reads.
+  final bool readOnlyReceiver;
+
+  InternalPropertySet(this.receiver, this.name, this.value,
+      {required this.forEffect, required this.readOnlyReceiver})
+      // ignore: unnecessary_null_comparison
+      : assert(receiver != null),
+        // ignore: unnecessary_null_comparison
+        assert(value != null),
+        // ignore: unnecessary_null_comparison
+        assert(forEffect != null),
+        // ignore: unnecessary_null_comparison
+        assert(readOnlyReceiver != null) {
+    receiver.parent = this;
+    value.parent = this;
+  }
+
+  @override
+  ExpressionInferenceResult acceptInference(
+      InferenceVisitor visitor, DartType typeContext) {
+    return visitor.visitInternalPropertySet(this, typeContext);
+  }
+
+  @override
+  InternalExpressionKind get kind => InternalExpressionKind.PropertySet;
+
+  @override
+  void visitChildren(Visitor v) {
+    receiver.accept(v);
+    name.accept(v);
+    value.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (value != null) {
+      value = v.transform(value);
+      value.parent = this;
+    }
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (value != null) {
+      value = v.transform(value);
+      value.parent = this;
+    }
+  }
+
+  @override
+  String toString() {
+    return "InternalPropertySet(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver, minimumPrecedence: Precedence.PRIMARY);
+    printer.write('.');
+    printer.writeName(name);
+    printer.write(' = ');
+    printer.writeExpression(value);
+  }
+}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index e8b4e79..ae9d883 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -358,6 +358,7 @@
 dummy
 dupdate
 dyn
+dynamically
 e
 easy
 ecma
diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
index e1f4a5b..a88f79a 100644
--- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
@@ -44,6 +44,8 @@
   _testFunctionDeclarationImpl();
   _testIfNullExpression();
   _testIntLiterals();
+  _testInternalMethodInvocation();
+  _testInternalPropertyGet();
   _testExpressionInvocation();
   _testNamedFunctionExpressionJudgment();
   _testNullAwareMethodInvocation();
@@ -372,6 +374,35 @@
   testExpression(new ShadowLargeIntLiteral('bar', TreeNode.noOffset), 'bar');
 }
 
+void _testInternalMethodInvocation() {
+  testExpression(
+      new InternalMethodInvocation(
+          new IntLiteral(0), new Name('boz'), new ArgumentsImpl([])),
+      '''
+0.boz()''');
+  testExpression(
+      new InternalMethodInvocation(
+          new IntLiteral(0),
+          new Name('boz'),
+          new ArgumentsImpl([
+            new IntLiteral(1)
+          ], types: [
+            const VoidType(),
+            const DynamicType()
+          ], named: [
+            new NamedExpression('foo', new IntLiteral(2)),
+            new NamedExpression('bar', new IntLiteral(3))
+          ])),
+      '''
+0.boz<void, dynamic>(1, foo: 2, bar: 3)''');
+}
+
+void _testInternalPropertyGet() {
+  testExpression(
+      new InternalPropertyGet(new IntLiteral(0), new Name('boz')), '''
+0.boz''');
+}
+
 void _testExpressionInvocation() {
   testExpression(
       new ExpressionInvocation(new IntLiteral(0), new ArgumentsImpl([])), '''
@@ -417,7 +448,7 @@
   // An unusual use of this node.
   testExpression(
       new NullAwareMethodInvocation(variable,
-          new PropertyGet(new VariableGet(variable), new Name('foo'))),
+          new InternalPropertyGet(new VariableGet(variable), new Name('foo'))),
       '''
 let final dynamic #0 = 0 in null-aware #0.foo''');
 }
@@ -429,7 +460,7 @@
   // The usual use of this node.
   testExpression(
       new NullAwarePropertyGet(variable,
-          new PropertyGet(new VariableGet(variable), new Name('foo'))),
+          new InternalPropertyGet(new VariableGet(variable), new Name('foo'))),
       '''
 0?.foo''');
 
diff --git a/pkg/front_end/testcases/general/invalid_super_initializer.dart b/pkg/front_end/testcases/general/invalid_super_initializer.dart
new file mode 100644
index 0000000..1e3f1aa
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_super_initializer.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {}
+
+class B extends A {
+  B(): super()?.foo() {}
+}
+
+bad() {
+  new B();
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/invalid_super_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_super_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..946f9ea
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_super_initializer.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+abstract class A {}
+class B extends A {
+  B(): super()?.foo() {}
+}
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.expect b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.expect
new file mode 100644
index 0000000..d8ef127
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   B(): super()?.foo() {}
+//        ^
+//
+// pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Expected an initializer.
+//   B(): super()?.foo() {}
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  constructor •() → self::B
+    : final dynamic #t1 = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  B(): super()?.foo() {}
+       ^" in #t2 == null ?{dynamic} null : #t2{dynamic}.foo() {}
+}
+static method bad() → dynamic {
+  new self::B::•();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.outline.expect
new file mode 100644
index 0000000..13e0b1e
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends self::A {
+  constructor •() → self::B
+    ;
+}
+static method bad() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.transformed.expect
new file mode 100644
index 0000000..d8ef127
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_super_initializer.dart.weak.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   B(): super()?.foo() {}
+//        ^
+//
+// pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Expected an initializer.
+//   B(): super()?.foo() {}
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  constructor •() → self::B
+    : final dynamic #t1 = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_super_initializer.dart:8:8: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  B(): super()?.foo() {}
+       ^" in #t2 == null ?{dynamic} null : #t2{dynamic}.foo() {}
+}
+static method bad() → dynamic {
+  new self::B::•();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart
new file mode 100644
index 0000000..d12b28b
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+class Class1 {
+  int field = 0;
+
+  factory Class1() = Class1._;
+
+  Class1._();
+
+  int get getter => 0;
+}
+
+class Class2 extends Class1 {
+  final Class2 _c2;
+
+  Class2(this._c2) : super._() {
+    // Invocation inside an invalid unary expression.
+    -new Class1();
+    // Invocation inside an invalid binary expression.
+    ('' + '') - new Class1();
+    // Invocation inside an invalid index set.
+    (0 + 1)[0] = new Class1();
+    _c2[0] = new Class1();
+    // Invocation inside an invalid index get.
+    (0 + 1)[new Class1()];
+    // Invocation inside an invalid property get.
+    new Class1().foo;
+    // Invocation inside an invalid property set.
+    (0 + 1).foo = new Class1();
+    // Invocation inside an invalid invocation.
+    new Class1().foo();
+    // Invocation inside an invalid implicit call invocation.
+    new Class1()();
+    // Invocation inside an invalid implicit field invocation.
+    new Class1().field();
+    // Invocation inside an invalid implicit getter invocation.
+    new Class1().getter();
+    // Invocation inside an invalid implicit call-getter invocation.
+    _c2(new Class1());
+    // Duplicate named arguments
+    method(a: 0, a: new Class1());
+    // Triple named arguments
+    method(a: 0, a: 1, a: new Class1());
+    // Invocation inside an invalid super index get.
+    super[new Class1()];
+    // Invocation inside an invalid super index set.
+    super[0] = new Class1();
+    // Invocation inside an invalid super set.
+    super.foo = new Class1();
+    // Invocation inside an invalid super invocation.
+    super.foo(new Class1());
+    // Invocation inside an invalid super binary.
+    super + new Class1();
+  }
+
+  method({a}) {}
+
+  int get call => 0;
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline.expect
new file mode 100644
index 0000000..607b231
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class Class1 {
+  int field = 0;
+  factory Class1() = Class1._;
+  Class1._();
+  int get getter => 0;
+}
+
+class Class2 extends Class1 {
+  final Class2 _c2;
+  Class2(this._c2) : super._() {}
+  method({a}) {}
+  int get call => 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca3ab16
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class Class1 {
+  Class1._();
+  factory Class1() = Class1._;
+  int field = 0;
+  int get getter => 0;
+}
+
+class Class2 extends Class1 {
+  Class2(this._c2) : super._() {}
+  final Class2 _c2;
+  int get call => 0;
+  method({a}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.expect
new file mode 100644
index 0000000..232d5ac
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.expect
@@ -0,0 +1,187 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:47:10: Error: Superclass has no method named '[]'.
+//     super[new Class1()];
+//          ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:49:10: Error: Superclass has no method named '[]='.
+//     super[0] = new Class1();
+//          ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:51:11: Error: Superclass has no setter named 'foo'.
+//     super.foo = new Class1();
+//           ^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:53:11: Error: Superclass has no method named 'foo'.
+//     super.foo(new Class1());
+//           ^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:55:11: Error: Superclass has no method named '+'.
+//     super + new Class1();
+//           ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:20:5: Error: The operator 'unary-' isn't defined for the class 'Class1'.
+//  - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+// Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+//     -new Class1();
+//     ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:22:15: Error: The operator '-' isn't defined for the class 'String'.
+// Try correcting the operator to an existing operator, or defining a '-' operator.
+//     ('' + '') - new Class1();
+//               ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:24:12: Error: The operator '[]=' isn't defined for the class 'int'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//     (0 + 1)[0] = new Class1();
+//            ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:25:8: Error: The operator '[]=' isn't defined for the class 'Class2'.
+//  - 'Class2' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//     _c2[0] = new Class1();
+//        ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:27:12: Error: The operator '[]' isn't defined for the class 'int'.
+// Try correcting the operator to an existing operator, or defining a '[]' operator.
+//     (0 + 1)[new Class1()];
+//            ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:29:18: Error: The getter 'foo' isn't defined for the class 'Class1'.
+//  - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+//     new Class1().foo;
+//                  ^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:31:13: Error: The setter 'foo' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//     (0 + 1).foo = new Class1();
+//             ^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:33:18: Error: The method 'foo' isn't defined for the class 'Class1'.
+//  - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//     new Class1().foo();
+//                  ^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:35:17: Error: The method 'call' isn't defined for the class 'Class1'.
+//  - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//     new Class1()();
+//                 ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:37:23: Error: 'field' isn't a function or method and can't be invoked.
+//     new Class1().field();
+//                       ^^^^...
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:39:24: Error: 'getter' isn't a function or method and can't be invoked.
+//     new Class1().getter();
+//                        ^^^^...
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:41:8: Error: 'call' isn't a function or method and can't be invoked.
+//     _c2(new Class1());
+//        ^^^^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:43:18: Error: Duplicated named argument 'a'.
+//     method(a: 0, a: new Class1());
+//                  ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:45:18: Error: Duplicated named argument 'a'.
+//     method(a: 0, a: 1, a: new Class1());
+//                  ^
+//
+// pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:45:24: Error: Duplicated named argument 'a'.
+//     method(a: 0, a: 1, a: new Class1());
+//                        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field = 0;
+  static final field dynamic _redirecting# = <dynamic>[self::Class1::•]/*isLegacy*/;
+  constructor _() → self::Class1
+    : super core::Object::•()
+    ;
+  static factory •() → self::Class1
+    let dynamic #redirecting_factory = self::Class1::_ in invalid-expression;
+  get getter() → core::int
+    return 0;
+}
+class Class2 extends self::Class1 {
+  final field self::Class2 _c2;
+  constructor •(self::Class2 _c2) → self::Class2
+    : self::Class2::_c2 = _c2, super self::Class1::_() {
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:20:5: Error: The operator 'unary-' isn't defined for the class 'Class1'.
+ - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+    -new Class1();
+    ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:22:15: Error: The operator '-' isn't defined for the class 'String'.
+Try correcting the operator to an existing operator, or defining a '-' operator.
+    ('' + '') - new Class1();
+              ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:24:12: Error: The operator '[]=' isn't defined for the class 'int'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+    (0 + 1)[0] = new Class1();
+           ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:25:8: Error: The operator '[]=' isn't defined for the class 'Class2'.
+ - 'Class2' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+    _c2[0] = new Class1();
+       ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:27:12: Error: The operator '[]' isn't defined for the class 'int'.
+Try correcting the operator to an existing operator, or defining a '[]' operator.
+    (0 + 1)[new Class1()];
+           ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:29:18: Error: The getter 'foo' isn't defined for the class 'Class1'.
+ - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+    new Class1().foo;
+                 ^^^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:31:13: Error: The setter 'foo' isn't defined for the class 'int'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+    (0 + 1).foo = new Class1();
+            ^^^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:33:18: Error: The method 'foo' isn't defined for the class 'Class1'.
+ - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+    new Class1().foo();
+                 ^^^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:35:17: Error: The method 'call' isn't defined for the class 'Class1'.
+ - 'Class1' is from 'pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'call'.
+    new Class1()();
+                ^";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:37:23: Error: 'field' isn't a function or method and can't be invoked.
+    new Class1().field();
+                      ^^^^...";
+    invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:39:24: Error: 'getter' isn't a function or method and can't be invoked.
+    new Class1().getter();
+                       ^^^^...";
+    let final self::Class2 #t1 = this.{self::Class2::_c2}{self::Class2} in let final self::Class1 #t2 = new self::Class1::_() in invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:41:8: Error: 'call' isn't a function or method and can't be invoked.
+    _c2(new Class1());
+       ^^^^";
+    this.{self::Class2::method}(a: invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:43:18: Error: Duplicated named argument 'a'.
+    method(a: 0, a: new Class1());
+                 ^"){({a: dynamic}) → dynamic};
+    this.{self::Class2::method}(a: invalid-expression "pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart:45:24: Error: Duplicated named argument 'a'.
+    method(a: 0, a: 1, a: new Class1());
+                       ^"){({a: dynamic}) → dynamic};
+    super.[](new self::Class1::_());
+    super.[]=(0, new self::Class1::_());
+    super.foo = new self::Class1::_();
+    super.foo(new self::Class1::_());
+    super.+(new self::Class1::_());
+  }
+  method method({dynamic a = #C1}) → dynamic {}
+  get call() → core::int
+    return 0;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.outline.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.outline.expect
new file mode 100644
index 0000000..83aea2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_in_invalid.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  static final field dynamic _redirecting# = <dynamic>[self::Class1::•]/*isLegacy*/;
+  constructor _() → self::Class1
+    ;
+  static factory •() → self::Class1
+    let dynamic #redirecting_factory = self::Class1::_ in invalid-expression;
+  get getter() → core::int
+    ;
+}
+class Class2 extends self::Class1 {
+  final field self::Class2 _c2;
+  constructor •(self::Class2 _c2) → self::Class2
+    ;
+  method method({dynamic a}) → dynamic
+    ;
+  get call() → core::int
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart
index 7b4cd53..7d7ffec 100644
--- a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
+
 // @dart=2.9
+
 // The test checks that type arguments of the target of redirection factory
 // constructors are preserved throughout the chain of redirections.
 
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 6aacb2f..6d07e17 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -100,6 +100,7 @@
 general/override_check_basic: TypeCheckError # Issue #31620
 general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
 general/override_setter_with_field: TypeCheckError
+general/redirecting_factory_invocation_in_invalid: TypeCheckError
 general/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
 general/type_parameter_type_named_int: RuntimeError
 general/type_variable_as_super: RuntimeError
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index e8cae1b..f4830a4 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -86,6 +86,7 @@
 general/incomplete_field_formal_parameter: FormatterCrash
 general/invalid_operator2: FormatterCrash
 general/invalid_operator: FormatterCrash
+general/invalid_super_initializer: FormatterCrash
 general/issue42997: FormatterCrash
 general/issue43363: FormatterCrash
 general/issue45490: FormatterCrash
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index d88eb7b16..9f50ba9 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -106,6 +106,7 @@
 general/override_check_basic: TypeCheckError # Issue #31620
 general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
 general/override_setter_with_field: TypeCheckError
+general/redirecting_factory_invocation_in_invalid: TypeCheckError
 general/spread_collection: RuntimeError
 general/type_parameter_type_named_int: RuntimeError # Expected
 general/type_variable_as_super: RuntimeError
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0009adc..d7c72c7 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3082,7 +3082,12 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
-    // TODO(johnniwinther): Implement this.
+    printer.write('super');
+    if (target.name.text.isNotEmpty) {
+      printer.write('.');
+      printer.write(target.name.text);
+    }
+    printer.writeArguments(arguments, includeTypeArguments: false);
   }
 }
 
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 5eec5a4..17a1c15 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2804,6 +2804,7 @@
     case Slot::Kind::kFunctionType_named_parameter_names:
     case Slot::Kind::kFunctionType_parameter_types:
     case Slot::Kind::kFunctionType_type_parameters:
+    case Slot::Kind::kInstance_native_fields_array:
     case Slot::Kind::kPointerBase_data_field:
     case Slot::Kind::kTypedDataView_data:
     case Slot::Kind::kType_arguments:
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index cd8e80c..9f84201 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -210,6 +210,7 @@
     case Slot::Kind::kArgumentsDescriptor_count:
     case Slot::Kind::kArgumentsDescriptor_size:
     case Slot::Kind::kArrayElement:
+    case Slot::Kind::kInstance_native_fields_array:
     case Slot::Kind::kTypeArguments:
     case Slot::Kind::kTypedDataView_offset_in_bytes:
     case Slot::Kind::kTypedDataView_data:
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 866e399..27adf00 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -61,6 +61,7 @@
   V(Closure, UntaggedClosure, function_type_arguments, TypeArguments, FINAL)   \
   V(FunctionType, UntaggedFunctionType, type_parameters, TypeParameters,       \
     FINAL)                                                                     \
+  V(Instance, UntaggedInstance, native_fields_array, Dynamic, VAR)             \
   V(Type, UntaggedType, arguments, TypeArguments, FINAL)                       \
   V(TypeParameters, UntaggedTypeParameters, flags, Array, FINAL)               \
   V(TypeParameters, UntaggedTypeParameters, bounds, TypeArguments, FINAL)      \
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 6968ff1..d35850e 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -854,6 +854,7 @@
     case MethodRecognizer::kFfiStorePointer:
     case MethodRecognizer::kFfiFromAddress:
     case MethodRecognizer::kFfiGetAddress:
+    case MethodRecognizer::kGetNativeField:
     case MethodRecognizer::kObjectEquals:
     case MethodRecognizer::kStringBaseLength:
     case MethodRecognizer::kStringBaseIsEmpty:
@@ -1491,6 +1492,20 @@
       body += Constant(Bool::False());
 #endif  // defined(ARCH_IS_64_BIT)
     } break;
+    case MethodRecognizer::kGetNativeField: {
+      auto& name = String::ZoneHandle(Z, function.name());
+      // Note: This method is force optimized so we can push untagged, etc.
+      // Load TypedDataArray from Instance Handle implementing
+      // NativeFieldWrapper.
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));  // Object.
+      body += CheckNullOptimized(TokenPosition::kNoSource, name);
+      body += LoadNativeField(Slot::Instance_native_fields_array());  // Fields.
+      body += CheckNullOptimized(TokenPosition::kNoSource, name);
+      // Load the native field at index.
+      body += IntConstant(0);  // Index.
+      body += LoadIndexed(kIntPtrCid);
+      body += Box(kUnboxedIntPtr);
+    } break;
     default: {
       UNREACHABLE();
       break;
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 0c5a85a..af01254 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -290,6 +290,7 @@
   libs->Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
   libs->Add(&Library::ZoneHandle(Library::AsyncLibrary()));
   libs->Add(&Library::ZoneHandle(Library::FfiLibrary()));
+  libs->Add(&Library::ZoneHandle(Library::NativeWrappersLibrary()));
 }
 
 static Token::Kind RecognizeTokenKindHelper(const String& name) {
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index f45e224..9680f0b 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -197,6 +197,7 @@
   V(::, _storePointer, FfiStorePointer, 0xea6b7751)                            \
   V(::, _fromAddress, FfiFromAddress, 0xfd8cb1cc)                              \
   V(Pointer, get:address, FfiGetAddress, 0x7cde87be)                           \
+  V(::, getNativeField, GetNativeField, 0x95b4ec94)                            \
   V(::, reachabilityFence, ReachabilityFence, 0x619235c1)                      \
   V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x1dcaf73d)                          \
   V(_Future, timeout, FutureTimeout, 0x73041520)                               \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index e1ad228..c8e499b 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -477,6 +477,10 @@
   return TranslateOffsetInWords(dart::Instance::NextFieldOffset());
 }
 
+word Instance::native_fields_array_offset() {
+  return TranslateOffsetInWords(dart::Instance::NativeFieldsOffset());
+}
+
 word Instance::DataOffsetFor(intptr_t cid) {
   if (dart::IsExternalTypedDataClassId(cid) ||
       dart::IsExternalStringClassId(cid)) {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 96342d7..52642b1 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -511,8 +511,8 @@
 class Instance : public AllStatic {
  public:
   // Returns the offset to the first field of [UntaggedInstance].
-  // Returns the offset to the first field of [UntaggedInstance].
   static word first_field_offset();
+  static word native_fields_array_offset();
   static word DataOffsetFor(intptr_t cid);
   static word ElementSizeFor(intptr_t cid);
   static word InstanceSize();
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 50b0ab9..b61e6c2 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4166,6 +4166,61 @@
   EXPECT_VALID(Dart_Invoke(lib, NewString("main"), 0, NULL));
 }
 
+void FUNCTION_NAME(SecretKeeper_KeepSecret)(Dart_NativeArguments native_args) {
+  Dart_Handle receiver = Dart_GetNativeArgument(native_args, 0);
+  int64_t secret = 0;
+  Dart_GetNativeIntegerArgument(native_args, 1, &secret);
+  EXPECT_VALID(Dart_SetNativeInstanceField(receiver, 0, secret));
+}
+
+static Dart_NativeFunction SecretKeeperNativeResolver(Dart_Handle name,
+                                                      int argument_count,
+                                                      bool* auto_setup_scope) {
+  return reinterpret_cast<Dart_NativeFunction>(Builtin_SecretKeeper_KeepSecret);
+}
+
+TEST_CASE(DartAPI_NativeFieldAccess) {
+  const char* kScriptChars = R"(
+    import 'dart:nativewrappers';
+    class SecretKeeper extends NativeFieldWrapperClass1 {
+      SecretKeeper(int secret) { _keepSecret(secret); }
+      void _keepSecret(int secret) native "SecretKeeper_KeepSecret";
+    }
+    main() => getNativeField(SecretKeeper(321));
+  )";
+
+  Dart_Handle result;
+  Dart_Handle lib =
+      TestCase::LoadTestScript(kScriptChars, SecretKeeperNativeResolver);
+  result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
+
+  EXPECT_VALID(result);
+  EXPECT(Dart_IsInteger(result));
+  int64_t value = 0;
+  result = Dart_IntegerToInt64(result, &value);
+  EXPECT_VALID(result);
+  EXPECT_EQ(321, value);
+}
+
+TEST_CASE(DartAPI_NativeFieldAccess_Throws) {
+  const char* kScriptChars = R"(
+    import 'dart:nativewrappers';
+    class ForgetfulSecretKeeper extends NativeFieldWrapperClass1 {
+      ForgetfulSecretKeeper(int secret) { /* Forget to init. native field. */ }
+    }
+    main() => getNativeField(ForgetfulSecretKeeper(321));
+  )";
+
+  Dart_Handle result;
+  Dart_Handle lib =
+      TestCase::LoadTestScript(kScriptChars, SecretKeeperNativeResolver);
+
+  result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
+
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_IsUnhandledExceptionError(result));
+}
+
 static Dart_WeakPersistentHandle weak1 = NULL;
 static Dart_WeakPersistentHandle weak2 = NULL;
 static Dart_WeakPersistentHandle weak3 = NULL;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e7fb75d..68a8470 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -14393,6 +14393,7 @@
   all_libs.Add(&Library::ZoneHandle(Library::ConvertLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::InternalLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::FfiLibrary()));
+  all_libs.Add(&Library::ZoneHandle(Library::NativeWrappersLibrary()));
   INTERNAL_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
   OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS_OTHER);
   POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 39b4940..5caf25f 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3101,7 +3101,7 @@
   bool ForceOptimize() const {
     return IsFfiFromAddress() || IsFfiGetAddress() || IsFfiLoad() ||
            IsFfiStore() || IsFfiTrampoline() || IsTypedDataViewFactory() ||
-           IsUtf8Scan();
+           IsUtf8Scan() || IsGetNativeField();
   }
 
   bool CanBeInlined() const;
@@ -3433,6 +3433,11 @@
     return kind == MethodRecognizer::kFfiGetAddress;
   }
 
+  bool IsGetNativeField() const {
+    const auto kind = recognized_kind();
+    return kind == MethodRecognizer::kGetNativeField;
+  }
+
   bool IsUtf8Scan() const {
     const auto kind = recognized_kind();
     return kind == MethodRecognizer::kUtf8DecoderScan;
@@ -7423,6 +7428,8 @@
 
   static intptr_t NextFieldOffset() { return sizeof(UntaggedInstance); }
 
+  static intptr_t NativeFieldsOffset() { return sizeof(UntaggedObject); }
+
  protected:
 #ifndef PRODUCT
   virtual void PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const;
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 58b4696..f89ccf7 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -282,6 +282,9 @@
   Sample* next = previous->is_allocation_sample()
                      ? buffer->ReserveAllocationSample(isolate)
                      : buffer->ReserveCPUSample(isolate);
+  if (next == nullptr) {
+    return nullptr;  // No blocks left, so drop sample.
+  }
   next->Init(previous->port(), previous->timestamp(), previous->tid());
   next->set_head_sample(false);
   // Mark that previous continues at next.
diff --git a/sdk/lib/html/dartium/nativewrappers.dart b/sdk/lib/html/dartium/nativewrappers.dart
index b6d2dc4..1d7787e 100644
--- a/sdk/lib/html/dartium/nativewrappers.dart
+++ b/sdk/lib/html/dartium/nativewrappers.dart
@@ -6,8 +6,18 @@
 
 class NativeFieldWrapperClass1 {}
 
-class NativeFieldWrapperClass2 {}
+class NativeFieldWrapperClass2 extends NativeFieldWrapperClass1 {}
 
-class NativeFieldWrapperClass3 {}
+class NativeFieldWrapperClass3 extends NativeFieldWrapperClass2 {}
 
-class NativeFieldWrapperClass4 {}
+class NativeFieldWrapperClass4 extends NativeFieldWrapperClass3 {}
+
+/// Gets the value of the native field of [object].
+///
+/// Throws an exception if [object] is null or if the native field was not set.
+///
+/// NOTE: This is function is temporary and will be deprecated in the near
+/// future.
+@pragma("vm:recognized", "other")
+int getNativeField(NativeFieldWrapperClass1 object)
+    native "FullyRecognizedMethod_NoNative";
diff --git a/tools/VERSION b/tools/VERSION
index dafe7ec..0e661f7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 360
+PRERELEASE 361
 PRERELEASE_PATCH 0
\ No newline at end of file