Version 2.17.0-189.0.dev

Merge commit 'ed2344eba94dbebdc9ddf161992d3b04555ddf27' into 'dev'
diff --git a/DEPS b/DEPS
index ea1fd32..3da1ec8 100644
--- a/DEPS
+++ b/DEPS
@@ -698,6 +698,12 @@
 
 hooks = [
   {
+    # Generate the .dart_tool/package_confg.json file.
+    'name': 'Generate .dart_tool/package_confg.json',
+    'pattern': '.',
+    'action': ['python3', 'sdk/tools/generate_package_config.py'],
+  },
+  {
     # Pull Debian sysroot for i386 Linux
     'name': 'sysroot_i386',
     'pattern': '.',
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index 8cc8ab5..bbd5bbb 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -546,13 +546,25 @@
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 57, 1),
       error(HintCode.DEAD_CODE, 62, 3),
     ]);
-    assertMethodInvocation2(
-      findNode.methodInvocation('a.foo()'),
-      element: null,
-      typeArgumentTypes: [],
-      invokeType: 'dynamic',
-      type: 'Never',
-    );
+
+    var node = findNode.methodInvocation('a.foo()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: a
+    staticElement: a@50
+    staticType: Never
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: Never
+''');
   }
 
   test_instance_method_fromInstance_nullable() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index cfc5917..0c703558 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -88,13 +88,35 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('foo();'),
-      element: findElement.method('foo'),
-      typeArgumentTypes: [],
-      invokeType: 'int Function()',
-      type: 'int?',
-    );
+    var node = findNode.methodInvocation('foo();');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: ExtensionOverride
+    extensionName: SimpleIdentifier
+      token: E
+      staticElement: self::@extension::E
+      staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        SimpleIdentifier
+          token: a
+          staticElement: a@54
+          staticType: int?
+      rightParenthesis: )
+    extendedType: int
+    staticType: null
+  operator: ?.
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@extension::E::@method::foo
+    staticType: int Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int Function()
+  staticType: int?
+''');
   }
 
   test_propertyAccess_getter_nullAware() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
index 1846448..c83a1c0 100644
--- a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
@@ -176,15 +176,8 @@
 int g() => f(null)!;
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('f(null)'),
-      element: findElement.topFunction('f'),
-      typeArgumentTypes: ['int?'],
-      invokeType: 'int? Function(int?)',
-      type: 'int?',
-    );
-
-    assertResolvedNodeText(findNode.postfix('f(null)!'), r'''
+    var node = findNode.postfix('f(null)!');
+    assertResolvedNodeText(node, r'''
 PostfixExpression
   operand: MethodInvocation
     methodName: SimpleIdentifier
@@ -284,25 +277,27 @@
       error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 70, 6),
     ]);
 
-    assertTypeDynamic(findNode.super_('super!'));
-
-    assertResolvedNodeText(findNode.postfix('super!'), r'''
-PostfixExpression
-  operand: SuperExpression
-    superKeyword: super
+    var node = findNode.methodInvocation('foo();');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: PostfixExpression
+    operand: SuperExpression
+      superKeyword: super
+      staticType: dynamic
+    operator: !
+    staticElement: <null>
     staticType: dynamic
-  operator: !
-  staticElement: <null>
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: dynamic
   staticType: dynamic
 ''');
-
-    assertMethodInvocation2(
-      findNode.methodInvocation('foo();'),
-      element: null,
-      typeArgumentTypes: [],
-      invokeType: 'dynamic',
-      type: 'dynamic',
-    );
   }
 
   test_nullCheck_typeParameter() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index 59238ca..e0e6a2c 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -193,52 +193,36 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('f();'),
-      element: findElement.topFunction('f'),
-      typeArgumentTypes: ['bool'],
-      invokeType: 'bool Function()',
-      type: 'bool',
-    );
-
-    var node = findNode.prefix('!f()');
+    var node = findNode.methodInvocation('f();');
     if (isNullSafetyEnabled) {
       assertResolvedNodeText(node, r'''
-PrefixExpression
-  operator: !
-  operand: MethodInvocation
-    methodName: SimpleIdentifier
-      token: f
-      staticElement: self::@function::f
-      staticType: T Function<T>()
-    argumentList: ArgumentList
-      leftParenthesis: (
-      rightParenthesis: )
-    staticInvokeType: bool Function()
-    staticType: bool
-    typeArgumentTypes
-      bool
-  staticElement: <null>
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: f
+    staticElement: self::@function::f
+    staticType: T Function<T>()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: bool Function()
   staticType: bool
+  typeArgumentTypes
+    bool
 ''');
     } else {
       assertResolvedNodeText(node, r'''
-PrefixExpression
-  operator: !
-  operand: MethodInvocation
-    methodName: SimpleIdentifier
-      token: f
-      staticElement: self::@function::f
-      staticType: T* Function<T>()*
-    argumentList: ArgumentList
-      leftParenthesis: (
-      rightParenthesis: )
-    staticInvokeType: bool* Function()*
-    staticType: bool*
-    typeArgumentTypes
-      bool*
-  staticElement: <null>
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: f
+    staticElement: self::@function::f
+    staticType: T* Function<T>()*
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: bool* Function()*
   staticType: bool*
+  typeArgumentTypes
+    bool*
 ''');
     }
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 0495690..8744443 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -479,59 +478,6 @@
     assertSubstitution(actual.substitution, expectedSubstitution);
   }
 
-  void assertMethodInvocation(
-    MethodInvocation invocation,
-    Object? expectedElement,
-    String expectedInvokeType, {
-    String? expectedMethodNameType,
-    String? expectedNameType,
-    String? expectedType,
-    List<String> expectedTypeArguments = const <String>[],
-  }) {
-    var invocationImpl = invocation as MethodInvocationImpl;
-
-    // TODO(scheglov) Check for Member.
-    var element = invocation.methodName.staticElement;
-    if (expectedElement is Element) {
-      expect(element?.declaration, same(expectedElement));
-    } else {
-      expect(element, expectedElement);
-    }
-
-    // TODO(scheglov) Should we enforce this?
-//    if (expectedNameType == null) {
-//      if (expectedElement is ExecutableElement) {
-//        expectedNameType = expectedElement.type.displayName;
-//      } else if (expectedElement is VariableElement) {
-//        expectedNameType = expectedElement.type.displayName;
-//      }
-//    }
-//    assertType(invocation.methodName, expectedNameType);
-
-    assertTypeArgumentTypes(invocation, expectedTypeArguments);
-
-    assertInvokeType(invocation, expectedInvokeType);
-
-    expectedType ??= _extractReturnType(expectedInvokeType);
-    assertType(invocation, expectedType);
-
-    expectedMethodNameType ??= expectedInvokeType;
-    assertType(invocationImpl.methodNameType, expectedMethodNameType);
-  }
-
-  void assertMethodInvocation2(
-    MethodInvocation node, {
-    required Object? element,
-    required List<String> typeArgumentTypes,
-    required String invokeType,
-    required String type,
-  }) {
-    assertElement(node.methodName, element);
-    assertTypeArgumentTypes(node, typeArgumentTypes);
-    assertType(node.staticInvokeType, invokeType);
-    assertType(node.staticType, type);
-  }
-
   void assertNamedParameterRef(String search, String name) {
     var ref = findNode.simple(search);
     assertElement(ref, findElement.parameter(name));
@@ -1010,12 +956,6 @@
     );
     return buffer.toString();
   }
-
-  static String _extractReturnType(String invokeType) {
-    int functionIndex = invokeType.indexOf(' Function');
-    expect(functionIndex, isNonNegative);
-    return invokeType.substring(0, functionIndex);
-  }
 }
 
 class _ElementMatcher extends Matcher {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
index 8112a55..48e4fb1 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
@@ -11,12 +11,13 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtensionMethodsTest);
+    defineReflectiveTests(ExtensionMethodsWithoutNullSafetyTest);
   });
 }
 
 @reflectiveTest
 class ExtensionMethodsTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin, ExtensionMethodsTestCases {}
+    with ExtensionMethodsTestCases {}
 
 mixin ExtensionMethodsTestCases on ResolutionTest {
   test_implicit_getter() async {
@@ -75,16 +76,49 @@
   List<T> bar(List<T> other) => other.foo();
 }
 ''');
-    assertMethodInvocation2(
-      findNode.methodInvocation('other.foo()'),
-      element: elementMatcher(
-        findElement.method('foo'),
-        substitution: {'T': 'T'},
-      ),
-      typeArgumentTypes: [],
-      invokeType: 'List<T> Function()',
-      type: 'List<T>',
-    );
+
+    var node = findNode.methodInvocation('other.foo()');
+    if (result.libraryElement.isNonNullableByDefault) {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: other
+    staticElement: other@75
+    staticType: List<T>
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: MethodMember
+      base: self::@extension::E::@method::foo
+      substitution: {T: T}
+    staticType: List<T> Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: List<T> Function()
+  staticType: List<T>
+''');
+    } else {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: other
+    staticElement: other@75
+    staticType: List<T*>*
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: MethodMember
+      base: self::@extension::E::@method::foo
+      substitution: {T: T*}
+    staticType: List<T*>* Function()*
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: List<T*>* Function()*
+  staticType: List<T*>*
+''');
+    }
   }
 
   test_implicit_method_onTypeParameter() async {
@@ -171,28 +205,47 @@
 }
 ''');
 
+    var node = findNode.methodInvocation('test();');
     if (result.libraryElement.isNonNullableByDefault) {
-      assertMethodInvocation2(
-        findNode.methodInvocation('test();'),
-        element: elementMatcher(
-          findElement.method('test'),
-          substitution: {'T': 'S'},
-        ),
-        typeArgumentTypes: [],
-        invokeType: 'S Function(S) Function()',
-        type: 'S Function(S)',
-      );
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: x
+    staticElement: x@87
+    staticType: S
+  operator: .
+  methodName: SimpleIdentifier
+    token: test
+    staticElement: MethodMember
+      base: self::@extension::Test::@method::test
+      substitution: {T: S}
+    staticType: S Function(S) Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: S Function(S) Function()
+  staticType: S Function(S)
+''');
     } else {
-      assertMethodInvocation2(
-        findNode.methodInvocation('test();'),
-        element: elementMatcher(
-          findElement.method('test'),
-          substitution: {'T': 'num'},
-        ),
-        typeArgumentTypes: [],
-        invokeType: 'num Function(num) Function()',
-        type: 'num Function(num)',
-      );
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: x
+    staticElement: x@87
+    staticType: S*
+  operator: .
+  methodName: SimpleIdentifier
+    token: test
+    staticElement: MethodMember
+      base: self::@extension::Test::@method::test
+      substitution: {T: num*}
+    staticType: num* Function(num*)* Function()*
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: num* Function(num*)* Function()*
+  staticType: num* Function(num*)*
+''');
     }
   }
 
@@ -567,3 +620,7 @@
     );
   }
 }
+
+@reflectiveTest
+class ExtensionMethodsWithoutNullSafetyTest extends PubPackageResolutionTest
+    with WithoutNullSafetyMixin, ExtensionMethodsTestCases {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index 39f7df5..fd9aae8 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -26,13 +26,25 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('f(null)'),
-      element: findElement.topFunction('f'),
-      typeArgumentTypes: ['Iterable<int>?'],
-      invokeType: 'Iterable<int>? Function(Iterable<int>?)',
-      type: 'Iterable<int>?',
-    );
+    var node = findNode.methodInvocation('f(null)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: f
+    staticElement: self::@function::f
+    staticType: T Function<T>(T)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      NullLiteral
+        literal: null
+        staticType: Null
+    rightParenthesis: )
+  staticInvokeType: Iterable<int>? Function(Iterable<int>?)
+  staticType: Iterable<int>?
+  typeArgumentTypes
+    Iterable<int>?
+''');
   }
 
   test_nested_hasNull_1() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
index 2d38f07..d081d5f 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
@@ -41,13 +41,25 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('f(null)'),
-      element: findElement.topFunction('f'),
-      typeArgumentTypes: ['Map<int, double>?'],
-      invokeType: 'Map<int, double>? Function(Map<int, double>?)',
-      type: 'Map<int, double>?',
-    );
+    var node = findNode.methodInvocation('f(null)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: f
+    staticElement: self::@function::f
+    staticType: T Function<T>(T)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      NullLiteral
+        literal: null
+        staticType: Null
+    rightParenthesis: )
+  staticInvokeType: Map<int, double>? Function(Map<int, double>?)
+  staticType: Map<int, double>?
+  typeArgumentTypes
+    Map<int, double>?
+''');
   }
 
   test_noContext_noTypeArgs_spread_never() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
index 17dfe68..6c94826 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../node_text_expectations.dart';
 import 'collection_elements_test.dart' as collection_elements;
 import 'conditional_expression_test.dart' as conditional_expression;
 import 'equality_expressions_test.dart' as equality_expressions;
@@ -37,5 +38,6 @@
     tear_off.main();
     throw_expression.main();
     type_test_expressions.main();
+    defineReflectiveTests(UpdateNodeTextExpectations);
   }, name: 'type inference');
 }
diff --git a/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart b/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
index da65cb3..59a6b97 100644
--- a/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
@@ -30,13 +30,27 @@
       error(CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE, 82, 3),
     ]);
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo(0)'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function(int)',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('super.foo(0)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: M
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
   }
 
   test_methodInvocation_mixinHasConcrete() async {
@@ -56,13 +70,23 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo()'),
-      element: findElement.method('foo', of: 'M'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function()',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('super.foo()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: C
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::M::@method::foo
+    staticType: void Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: void Function()
+  staticType: void
+''');
   }
 
   test_methodInvocation_mixinHasNoSuchMethod() async {
@@ -80,13 +104,23 @@
       error(CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE, 107, 3),
     ]);
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo()'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function()',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('super.foo()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: B
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: void Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: void Function()
+  staticType: void
+''');
   }
 
   test_methodInvocation_superHasAbstract() async {
@@ -106,13 +140,27 @@
       error(CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE, 95, 3),
     ]);
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo(0)'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function(int)',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('super.foo(0)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: B
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
   }
 
   test_methodInvocation_superHasConcrete_mixinHasAbstract() async {
@@ -132,13 +180,23 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('foo(); // ref'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function()',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('foo(); // ref');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: C
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: void Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: void Function()
+  staticType: void
+''');
   }
 
   test_methodInvocation_superHasNoSuchMethod() async {
@@ -154,13 +212,23 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo()'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'int Function()',
-      type: 'int',
-    );
+    var node = findNode.methodInvocation('super.foo()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: B
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: int Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int Function()
+  staticType: int
+''');
   }
 
   test_methodInvocation_superSuperHasConcrete() async {
@@ -180,13 +248,23 @@
 }
 ''');
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.foo()'),
-      element: findElement.method('foo', of: 'A'),
-      typeArgumentTypes: [],
-      invokeType: 'void Function()',
-      type: 'void',
-    );
+    var node = findNode.methodInvocation('super.foo()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: C
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@class::A::@method::foo
+    staticType: void Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: void Function()
+  staticType: void
+''');
   }
 
   test_propertyAccess_getter() async {
diff --git a/pkg/analyzer/test/src/diagnostics/extension_override_access_to_static_member_test.dart b/pkg/analyzer/test/src/diagnostics/extension_override_access_to_static_member_test.dart
index 9b46e54..8279ab9 100644
--- a/pkg/analyzer/test/src/diagnostics/extension_override_access_to_static_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extension_override_access_to_static_member_test.dart
@@ -81,12 +81,34 @@
       error(CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER, 77,
           5),
     ]);
-    var invocation = findNode.methodInvocation('empty();');
-    assertMethodInvocation(
-      invocation,
-      findElement.method('empty'),
-      'String Function()',
-    );
+
+    var node = findNode.methodInvocation('empty();');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: ExtensionOverride
+    extensionName: SimpleIdentifier
+      token: E
+      staticElement: self::@extension::E
+      staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        SimpleStringLiteral
+          literal: 'a'
+      rightParenthesis: )
+    extendedType: String
+    staticType: null
+  operator: .
+  methodName: SimpleIdentifier
+    token: empty
+    staticElement: self::@extension::E::@method::empty
+    staticType: String Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: String Function()
+  staticType: String
+''');
   }
 
   test_setter() async {
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index ae6f8b6..b751b98 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -402,15 +402,36 @@
       error(HintCode.DEAD_CODE, 25, 8),
     ]);
 
-    assertMethodInvocation(
-      findNode.methodInvocation('.foo(1 + 2)'),
-      null,
-      'dynamic',
-      expectedType: 'Never',
-    );
-
-    // Verify that arguments are resolved.
-    assertType(findNode.binary('1 + 2'), 'int');
+    var node = findNode.methodInvocation('.foo(1 + 2)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: x
+    staticElement: x@13
+    staticType: Never
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      BinaryExpression
+        leftOperand: IntegerLiteral
+          literal: 1
+          staticType: int
+        operator: +
+        rightOperand: IntegerLiteral
+          literal: 2
+          staticType: int
+        staticElement: dart:core::@class::num::@method::+
+        staticInvokeType: num Function(num)
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: Never
+''');
   }
 
   test_methodInvocation_never_toString() async {
@@ -423,15 +444,36 @@
       error(HintCode.DEAD_CODE, 30, 8),
     ]);
 
-    assertMethodInvocation(
-      findNode.methodInvocation('.toString(1 + 2)'),
-      null,
-      'dynamic',
-      expectedType: 'Never',
-    );
-
-    // Verify that arguments are resolved.
-    assertType(findNode.binary('1 + 2'), 'int');
+    var node = findNode.methodInvocation('.toString(1 + 2)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: x
+    staticElement: x@13
+    staticType: Never
+  operator: .
+  methodName: SimpleIdentifier
+    token: toString
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      BinaryExpression
+        leftOperand: IntegerLiteral
+          literal: 1
+          staticType: int
+        operator: +
+        rightOperand: IntegerLiteral
+          literal: 2
+          staticType: int
+        staticElement: dart:core::@class::num::@method::+
+        staticInvokeType: num Function(num)
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: Never
+''');
   }
 
   test_methodInvocation_neverQ_toString() async {
@@ -443,15 +485,36 @@
       error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 32, 5),
     ]);
 
-    assertMethodInvocation(
-      findNode.methodInvocation('.toString(1 + 2)'),
-      objectElement.getMethod('toString'),
-      'String Function()',
-      expectedType: 'String',
-    );
-
-    // Verify that arguments are resolved.
-    assertType(findNode.binary('1 + 2'), 'int');
+    var node = findNode.methodInvocation('.toString(1 + 2)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: x
+    staticElement: x@14
+    staticType: Never?
+  operator: .
+  methodName: SimpleIdentifier
+    token: toString
+    staticElement: dart:core::@class::Object::@method::toString
+    staticType: String Function()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      BinaryExpression
+        leftOperand: IntegerLiteral
+          literal: 1
+          staticType: int
+        operator: +
+        rightOperand: IntegerLiteral
+          literal: 2
+          staticType: int
+        staticElement: dart:core::@class::num::@method::+
+        staticInvokeType: num Function(num)
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: String Function()
+  staticType: String
+''');
   }
 
   test_postfixExpression_never_plusPlus() async {
@@ -787,12 +850,29 @@
 }
 ''');
 
-    assertMethodInvocation(
-      findNode.methodInvocation('toString()'),
-      null,
-      'dynamic',
-      expectedType: 'dynamic',
-    );
+    var node = findNode.methodInvocation('toString()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: ParenthesizedExpression
+    leftParenthesis: (
+    expression: ThrowExpression
+      throwKeyword: throw
+      expression: SimpleStringLiteral
+        literal: ''
+      staticType: Never*
+    rightParenthesis: )
+    staticType: Never*
+  operator: .
+  methodName: SimpleIdentifier
+    token: toString
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: dynamic
+''');
   }
 
   test_propertyAccess_toString() async {
diff --git a/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart b/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
index ca2e979..a424550 100644
--- a/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
@@ -246,13 +246,23 @@
       error(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, 70, 5),
     ]);
 
-    assertMethodInvocation2(
-      findNode.methodInvocation('super.m()'),
-      element: null,
-      typeArgumentTypes: [],
-      invokeType: 'dynamic',
-      type: 'dynamic',
-    );
+    var node = findNode.methodInvocation('super.m()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SuperExpression
+    superKeyword: super
+    staticType: B
+  operator: .
+  methodName: SimpleIdentifier
+    token: m
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: dynamic
+''');
   }
 
   test_staticVariableInitializer() async {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
index 07b1785..d01fefd 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
@@ -35,13 +35,34 @@
 ''', [
       error(CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD, 40, 1),
     ]);
-    var invocation = findNode.methodInvocation('m();');
-    assertMethodInvocation(
-      invocation,
-      null,
-      'dynamic',
-      expectedType: 'dynamic',
-    );
+
+    var node = findNode.methodInvocation('m();');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: ExtensionOverride
+    extensionName: SimpleIdentifier
+      token: E
+      staticElement: self::@extension::E
+      staticType: null
+    argumentList: ArgumentList
+      leftParenthesis: (
+      arguments
+        SimpleStringLiteral
+          literal: 'a'
+      rightParenthesis: )
+    extendedType: String
+    staticType: null
+  operator: .
+  methodName: SimpleIdentifier
+    token: m
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: dynamic
+''');
   }
 
   test_static_withInference() async {
diff --git a/tools/VERSION b/tools/VERSION
index 79638a7..91a5739 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 188
+PRERELEASE 189
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/generate_package_config.py b/tools/generate_package_config.py
new file mode 100644
index 0000000..b763b3d
--- /dev/null
+++ b/tools/generate_package_config.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# 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.
+
+# Invoke the `tools/generate_package_config.dart` script.
+
+import os
+import os.path
+import platform
+import subprocess
+import sys
+
+USE_PYTHON3 = True
+
+
+def is_windows():
+    os_id = platform.system()
+    return os_id == 'Windows'
+
+
+def checked_in_sdk_path():
+    tools_dir = os.path.dirname(os.path.realpath(__file__))
+    return os.path.join(tools_dir, 'sdks', 'dart-sdk')
+
+
+def checked_in_sdk_executable():
+    name = 'dart'
+    if is_windows():
+        name = 'dart.exe'
+    return os.path.join(checked_in_sdk_path(), 'bin', name)
+
+
+def generate_package_config():
+    tools_dir = os.path.dirname(os.path.realpath(__file__))
+    process = subprocess.run([
+        checked_in_sdk_executable(),
+        os.path.join(tools_dir, 'generate_package_config.dart')
+    ])
+    return process.returncode
+
+
+def Main():
+    sys.exit(generate_package_config())
+
+
+if __name__ == '__main__':
+    Main()