Version 2.17.0-158.0.dev

Merge commit '248de89e8c9c32d439827b3a2eae584e019f1e84' into 'dev'
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 26c0537..8109b5f 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3697,10 +3697,18 @@
 
   /// Fills [typeArguments] with the type arguments needed for [selector] and
   /// returns the selector corresponding to the passed type arguments.
+  ///
+  /// If [isImplicitCall] is `true`, the target of the invocation can be either
+  /// the target of the [selector] or of the corresponding `.call` selector. In
+  /// this case we need to check both selectors to see if we need to pass type
+  /// arguments. This occurs for field/getter invocations.
   Selector _fillDynamicTypeArguments(
-      Selector selector, ir.Arguments arguments, List<DartType> typeArguments) {
+      Selector selector, ir.Arguments arguments, List<DartType> typeArguments,
+      {bool isImplicitCall = false}) {
     if (selector.typeArgumentCount > 0) {
-      if (_rtiNeed.selectorNeedsTypeArguments(selector)) {
+      if (_rtiNeed.selectorNeedsTypeArguments(selector) ||
+          (isImplicitCall &&
+              _rtiNeed.selectorNeedsTypeArguments(selector.toCallSelector()))) {
         typeArguments.addAll(arguments.types.map(_elementMap.getDartType));
       } else {
         return selector.toNonGeneric();
@@ -5216,12 +5224,14 @@
   }
 
   void _handleMethodInvocation(
-      ir.Expression node, ir.Expression receiver, ir.Arguments arguments) {
+      ir.Expression node, ir.Expression receiver, ir.Arguments arguments,
+      {bool isImplicitCall = false}) {
     receiver.accept(this);
     HInstruction receiverInstruction = pop();
     Selector selector = _elementMap.getSelector(node);
     List<DartType> typeArguments = [];
-    selector = _fillDynamicTypeArguments(selector, arguments, typeArguments);
+    selector = _fillDynamicTypeArguments(selector, arguments, typeArguments,
+        isImplicitCall: isImplicitCall);
     _pushDynamicInvocation(
         node,
         _getStaticType(receiver),
@@ -5242,7 +5252,8 @@
 
   @override
   void visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) {
-    _handleMethodInvocation(node, node.receiver, node.arguments);
+    _handleMethodInvocation(node, node.receiver, node.arguments,
+        isImplicitCall: true);
   }
 
   @override
diff --git a/pkg/compiler/test/impact/data/issue48304.dart b/pkg/compiler/test/impact/data/issue48304.dart
new file mode 100644
index 0000000..fe7da9a
--- /dev/null
+++ b/pkg/compiler/test/impact/data/issue48304.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class B {
+  call<T>();
+}
+
+/*member: C.:static=[Object.(0)]*/
+class C implements B {
+  /*member: C.call:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    _setArrayType(2),
+    createRuntimeType(1),
+    findType(1),
+    instanceType(1),
+    print(1),
+    typeLiteral(1)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSInt,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNumNotInt,
+    inst:JSNumber,
+    inst:JSPositiveInt,
+    inst:JSUInt31,
+    inst:JSUInt32,
+    inst:JSUnmodifiableArray<dynamic>,
+    inst:Type,
+    inst:_Type,
+    lit:call.T,
+    param:Object?]
+  */
+  call<T>() => print(T);
+}
+
+abstract class A {}
+
+class Wrapper {
+  /*member: Wrapper.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    init:Wrapper.b,
+    init:Wrapper.call,
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:B]
+  */
+  Wrapper(this.b, this.call);
+  /*member: Wrapper.b:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:B]
+  */
+  final B b;
+  /*member: Wrapper.call:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:B]
+  */
+  final B call;
+}
+
+/*member: main:
+ dynamic=[
+  B.call<A>(0),
+  exact:C.call<A>(0),
+  exact:Wrapper.b,
+  exact:Wrapper.b<A>(0),
+  exact:Wrapper.call,
+  exact:Wrapper.call<A>(0)],
+ static=[
+  C.(0),
+  Wrapper.(2)]
+*/
+void main() {
+  B b = C();
+  b<A>();
+  Wrapper(b, b).b<A>();
+  (Wrapper(b, b).b)<A>();
+  Wrapper(b, b).call<A>();
+  (Wrapper(b, b).call)<A>();
+}
diff --git a/pkg/compiler/test/inference/data/issue48304.dart b/pkg/compiler/test/inference/data/issue48304.dart
new file mode 100644
index 0000000..dc77fc3
--- /dev/null
+++ b/pkg/compiler/test/inference/data/issue48304.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class B {
+  call<T>();
+}
+
+/*member: C.:[exact=C]*/
+class C implements B {
+  /*member: C.call:[null]*/
+  call<T>() => print(T);
+}
+
+abstract class A {}
+
+class Wrapper {
+  /*member: Wrapper.:[exact=Wrapper]*/
+  Wrapper(this. /*[exact=C]*/ b, this. /*[exact=C]*/ call);
+  /*member: Wrapper.b:[exact=C]*/
+  final B b;
+  /*member: Wrapper.call:[exact=C]*/
+  final B call;
+}
+
+/*member: main:[null]*/
+void main() {
+  B b = C();
+  b/*invoke: [exact=C]*/ <A>();
+  Wrapper(b, b).b<A> /*invoke: [exact=Wrapper]*/ ();
+  (Wrapper(b, b). /*[exact=Wrapper]*/ b)<A> /*invoke: [exact=C]*/ ();
+  Wrapper(b, b).call<A> /*invoke: [exact=Wrapper]*/ ();
+  (Wrapper(b, b). /*[exact=Wrapper]*/ call)<A> /*invoke: [exact=C]*/ ();
+}
diff --git a/pkg/compiler/test/rti/data/issue48304.dart b/pkg/compiler/test/rti/data/issue48304.dart
new file mode 100644
index 0000000..dfb51be
--- /dev/null
+++ b/pkg/compiler/test/rti/data/issue48304.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*spec.class: B:explicit=[B]*/
+abstract class B {
+  call<T>();
+}
+
+class C implements B {
+  /*member: C.call:exp,needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+  call<T>() => print(T);
+}
+
+abstract class A {}
+
+class Wrapper {
+  Wrapper(this.b, this.call);
+  final B b;
+  final B call;
+}
+
+void main() {
+  B b = C();
+  b<A>();
+  Wrapper(b, b).b<A>();
+  (Wrapper(b, b).b)<A>();
+  Wrapper(b, b).call<A>();
+  (Wrapper(b, b).call)<A>();
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index f55c0f8..85449b2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -228,8 +228,10 @@
   macro.ResolvedIdentifier _resolveIdentifier(macro.Identifier identifier) {
     if (identifier is _IdentifierImpl) {
       MemberBuilder? memberBuilder = identifier.memberBuilder;
-      TypeBuilder? typeBuilder = identifier.typeBuilder;
       FormalParameterBuilder? parameterBuilder = identifier.parameterBuilder;
+      TypeDeclarationBuilder? typeDeclarationBuilder =
+          identifier.typeDeclarationBuilder ??
+              identifier.typeBuilder?.declaration;
       if (memberBuilder != null) {
         Uri? uri;
         String? staticScope;
@@ -250,9 +252,7 @@
             name: identifier.name,
             staticScope: staticScope,
             uri: uri);
-      } else if (typeBuilder != null) {
-        TypeDeclarationBuilder typeDeclarationBuilder =
-            typeBuilder.declaration!;
+      } else if (typeDeclarationBuilder != null) {
         Uri? uri;
         if (typeDeclarationBuilder is ClassBuilder) {
           uri = typeDeclarationBuilder.library.importUri;
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart b/pkg/front_end/testcases/dart2js/issue48304.dart
new file mode 100644
index 0000000..89351f8
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class B {
+  call<T>();
+}
+
+class C implements B {
+  call<T>() => print(T);
+}
+
+abstract class A {}
+
+class Wrapper {
+  Wrapper(this.b, this.call);
+  final B b;
+  final B call;
+}
+
+void main() {
+  B b = C();
+  b<A>();
+  Wrapper(b, b).b<A>();
+  (Wrapper(b, b).b)<A>();
+  Wrapper(b, b).call<A>();
+  (Wrapper(b, b).call)<A>();
+}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.strong.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.strong.expect
new file mode 100644
index 0000000..9f1d34d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.strong.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    return core::print(self::C::call::T%);
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    : self::Wrapper::b = b, self::Wrapper::call = call, super core::Object::•()
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void {
+  self::B b = new self::C::•();
+  b.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.strong.transformed.expect
new file mode 100644
index 0000000..9f1d34d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    return core::print(self::C::call::T%);
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    : self::Wrapper::b = b, self::Wrapper::call = call, super core::Object::•()
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void {
+  self::B b = new self::C::•();
+  b.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline.expect
new file mode 100644
index 0000000..05d076b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+abstract class B {
+  call<T>();
+}
+
+class C implements B {
+  call<T>() => print(T);
+}
+
+abstract class A {}
+
+class Wrapper {
+  Wrapper(this.b, this.call);
+  final B b;
+  final B call;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6997d4b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+abstract class A {}
+
+abstract class B {
+  call<T>();
+}
+
+class C implements B {
+  call<T>() => print(T);
+}
+
+class Wrapper {
+  Wrapper(this.b, this.call);
+  final B b;
+  final B call;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.weak.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.expect
new file mode 100644
index 0000000..9f1d34d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    return core::print(self::C::call::T%);
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    : self::Wrapper::b = b, self::Wrapper::call = call, super core::Object::•()
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void {
+  self::B b = new self::C::•();
+  b.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.modular.expect
new file mode 100644
index 0000000..9f1d34d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.modular.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    return core::print(self::C::call::T%);
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    : self::Wrapper::b = b, self::Wrapper::call = call, super core::Object::•()
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void {
+  self::B b = new self::C::•();
+  b.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+}
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.outline.expect
new file mode 100644
index 0000000..f6c8da7
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.outline.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    ;
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/dart2js/issue48304.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.transformed.expect
new file mode 100644
index 0000000..9f1d34d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/issue48304.dart.weak.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method call<T extends core::Object? = dynamic>() → dynamic;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>() → dynamic
+    return core::print(self::C::call::T%);
+  static method _#new#tearOff() → self::C
+    return new self::C::•();
+}
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Wrapper extends core::Object {
+  final field self::B b;
+  final field self::B call;
+  constructor •(self::B b, self::B call) → self::Wrapper
+    : self::Wrapper::b = b, self::Wrapper::call = call, super core::Object::•()
+    ;
+  static method _#new#tearOff(self::B b, self::B call) → self::Wrapper
+    return new self::Wrapper::•(b, call);
+}
+static method main() → void {
+  self::B b = new self::C::•();
+  b.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::b}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}<self::A>(){() → dynamic};
+  new self::Wrapper::•(b, b).{self::Wrapper::call}{self::B}.{self::B::call}<self::A>(){() → dynamic};
+}
diff --git a/tests/language/regress/regress48304_test.dart b/tests/language/regress/regress48304_test.dart
new file mode 100644
index 0000000..04de267
--- /dev/null
+++ b/tests/language/regress/regress48304_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+final String expected = '$A';
+
+abstract class B {
+  call<T>();
+}
+
+class C implements B {
+  call<T>() => '$T';
+}
+
+abstract class A {}
+
+class Wrapper {
+  Wrapper(this.b, this.call);
+  final B b;
+  final B call;
+}
+
+void main() {
+  B b = C();
+  Expect.equals(b<A>(), expected);
+  Expect.equals(Wrapper(b, b).b<A>(), expected);
+  Expect.equals((Wrapper(b, b).b)<A>(), expected);
+  Expect.equals(Wrapper(b, b).call<A>(), expected);
+  Expect.equals((Wrapper(b, b).call)<A>(), expected);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 5516267..f27b5c8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 157
+PRERELEASE 158
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/patches/flutter-engine/apply.sh b/tools/patches/flutter-engine/apply.sh
index 38ce731..5b49564 100755
--- a/tools/patches/flutter-engine/apply.sh
+++ b/tools/patches/flutter-engine/apply.sh
@@ -62,7 +62,7 @@
   # DEPS file might have been patched with new version of packages that
   # Dart SDK depends on. Get information about dependencies from the
   # DEPS file and forcefully update checkouts of those dependencies.
-  gclient.py revinfo --ignore-dep-type=cipd | grep 'src/third_party/dart/third_party' | while read -r line; do
+  gclient revinfo --ignore-dep-type=cipd | grep 'src/third_party/dart/third_party' | while read -r line; do
     # revinfo would produce lines in the following format:
     #     path: git-url@tag-or-hash
     # Where no spaces occur inside path, git-url or tag-or-hash.
@@ -97,5 +97,5 @@
     fi
     popd > /dev/null
   done
-  gclient.py runhooks
+  gclient runhooks
 fi