Pass TypeProvider to Member(s).

Bug: https://github.com/dart-lang/sdk/issues/43541
Bug: https://buganizer.corp.google.com/issues/169344717
Change-Id: I00b7c5308473de2bef949668c72aaad1967f199a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164462
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 5c08ec5..db5240f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -7,10 +7,12 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/display_string_builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -25,10 +27,11 @@
   /// Initialize a newly created element to represent a constructor, based on
   /// the [declaration], and applied [substitution].
   ConstructorMember(
+    TypeProviderImpl typeProvider,
     ConstructorElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
-  ) : super(declaration, substitution, isLegacy,
+  ) : super(typeProvider, declaration, substitution, isLegacy,
             const <TypeParameterElement>[]);
 
   @deprecated
@@ -79,7 +82,7 @@
       substitution = _substitution;
     }
 
-    return ConstructorMember(declaration, substitution, false);
+    return ConstructorMember(_typeProvider, declaration, substitution, false);
   }
 
   @override
@@ -118,6 +121,7 @@
     }
 
     return ConstructorMember(
+      constructor.library.typeProvider,
       constructor,
       Substitution.fromInterfaceType(definingType),
       isLegacy,
@@ -141,11 +145,12 @@
   /// their bounds.  The [substitution] includes replacing [declaration] type
   /// parameters with the provided fresh [typeParameters].
   ExecutableMember(
+    TypeProviderImpl typeProvider,
     ExecutableElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
     this.typeParameters,
-  ) : super(declaration, substitution, isLegacy);
+  ) : super(typeProvider, declaration, substitution, isLegacy);
 
   @deprecated
   @override
@@ -185,9 +190,10 @@
   List<ParameterElement> get parameters {
     return declaration.parameters.map<ParameterElement>((p) {
       if (p is FieldFormalParameterElement) {
-        return FieldFormalParameterMember(p, _substitution, isLegacy);
+        return FieldFormalParameterMember(
+            _typeProvider, p, _substitution, isLegacy);
       }
-      return ParameterMember(p, _substitution, isLegacy);
+      return ParameterMember(_typeProvider, p, _substitution, isLegacy);
     }).toList();
   }
 
@@ -222,11 +228,13 @@
       return null;
     }
 
+    TypeProvider typeProvider;
     var isLegacy = false;
     var combined = substitution;
     if (element is ExecutableMember) {
       ExecutableMember member = element;
       element = member.declaration;
+      typeProvider = member._typeProvider;
 
       isLegacy = member.isLegacy;
 
@@ -236,6 +244,8 @@
       }
       map.addAll(substitution.map);
       combined = Substitution.fromMap(map);
+    } else {
+      typeProvider = element.library.typeProvider;
     }
 
     if (!isLegacy && combined.map.isEmpty) {
@@ -243,11 +253,11 @@
     }
 
     if (element is ConstructorElement) {
-      return ConstructorMember(element, combined, isLegacy);
+      return ConstructorMember(typeProvider, element, combined, isLegacy);
     } else if (element is MethodElement) {
-      return MethodMember(element, combined, isLegacy);
+      return MethodMember(typeProvider, element, combined, isLegacy);
     } else if (element is PropertyAccessorElement) {
-      return PropertyAccessorMember(element, combined, isLegacy);
+      return PropertyAccessorMember(typeProvider, element, combined, isLegacy);
     } else {
       throw UnimplementedError('(${element.runtimeType}) $element');
     }
@@ -259,6 +269,7 @@
 class FieldFormalParameterMember extends ParameterMember
     implements FieldFormalParameterElement {
   factory FieldFormalParameterMember(
+    TypeProviderImpl typeProvider,
     FieldFormalParameterElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
@@ -268,6 +279,7 @@
       substitution,
     );
     return FieldFormalParameterMember._(
+      typeProvider,
       declaration,
       freshTypeParameters.substitution,
       isLegacy,
@@ -276,11 +288,18 @@
   }
 
   FieldFormalParameterMember._(
+    TypeProviderImpl typeProvider,
     FieldFormalParameterElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
     List<TypeParameterElement> typeParameters,
-  ) : super._(declaration, substitution, isLegacy, typeParameters);
+  ) : super._(
+          typeProvider,
+          declaration,
+          substitution,
+          isLegacy,
+          typeParameters,
+        );
 
   @override
   FieldElement get field {
@@ -289,7 +308,7 @@
       return null;
     }
 
-    return FieldMember(field, _substitution, isLegacy);
+    return FieldMember(_typeProvider, field, _substitution, isLegacy);
   }
 
   @override
@@ -309,10 +328,11 @@
   /// Initialize a newly created element to represent a field, based on the
   /// [declaration], with applied [substitution].
   FieldMember(
+    TypeProviderImpl typeProvider,
     FieldElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
-  ) : super(declaration, substitution, isLegacy);
+  ) : super(typeProvider, declaration, substitution, isLegacy);
 
   @deprecated
   @override
@@ -330,7 +350,8 @@
     if (baseGetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseGetter, _substitution, isLegacy);
   }
 
   @override
@@ -354,7 +375,8 @@
     if (baseSetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseSetter, _substitution, isLegacy);
   }
 
   @override
@@ -370,6 +392,7 @@
       return field;
     }
     return FieldMember(
+      field.library.typeProvider,
       field,
       Substitution.fromInterfaceType(definingType),
       false,
@@ -383,13 +406,16 @@
     if (substitution.map.isEmpty) {
       return element;
     }
-    return FieldMember(element, substitution, false);
+    var typeProvider = element.library.typeProvider;
+    return FieldMember(typeProvider, element, substitution, false);
   }
 }
 
 class FunctionMember extends ExecutableMember implements FunctionElement {
-  FunctionMember(FunctionElement declaration, bool isLegacy)
+  FunctionMember(
+      TypeProviderImpl typeProvider, FunctionElement declaration, bool isLegacy)
       : super(
+          typeProvider,
           declaration,
           Substitution.empty,
           isLegacy,
@@ -411,6 +437,9 @@
 /// An element defined in a parameterized type where the values of the type
 /// parameters are known.
 abstract class Member implements Element {
+  /// A type provider (might be legacy, might be null-safe).
+  final TypeProviderImpl _typeProvider;
+
   /// The element on which the parameterized element was created.
   final Element _declaration;
 
@@ -422,7 +451,8 @@
 
   /// Initialize a newly created element to represent a member, based on the
   /// [declaration], and applied [_substitution].
-  Member(this._declaration, this._substitution, this.isLegacy) {
+  Member(this._typeProvider, this._declaration, this._substitution,
+      this.isLegacy) {
     if (_declaration is Member) {
       throw StateError('Members must be created from a declarations.');
     }
@@ -599,8 +629,7 @@
   /// Otherwise, return the type unchanged.
   DartType _toLegacyType(DartType type) {
     if (isLegacy) {
-      var typeProvider = declaration.library.typeProvider;
-      return NullabilityEliminator.perform(typeProvider, type);
+      return NullabilityEliminator.perform(_typeProvider, type);
     } else {
       return type;
     }
@@ -617,18 +646,24 @@
       } else if (element is Member) {
         var member = element as Member;
         return ConstructorMember(
+          member._typeProvider,
           member._declaration,
           member._substitution,
           true,
         );
       } else {
-        return ConstructorMember(element, Substitution.empty, true);
+        var typeProvider = element.library.typeProvider;
+        return ConstructorMember(
+            typeProvider, element, Substitution.empty, true);
       }
     } else if (element is FunctionElement) {
       if (!element.library.isNonNullableByDefault) {
         return element;
       } else {
-        return FunctionMember(element.declaration, true);
+        var typeProvider = element is Member
+            ? (element as Member)._typeProvider
+            : element.library.typeProvider;
+        return FunctionMember(typeProvider, element.declaration, true);
       }
     } else if (element is MethodElement) {
       if (!element.library.isNonNullableByDefault) {
@@ -636,12 +671,14 @@
       } else if (element is Member) {
         var member = element as Member;
         return MethodMember(
+          member._typeProvider,
           member._declaration,
           member._substitution,
           true,
         );
       } else {
-        return MethodMember(element, Substitution.empty, true);
+        var typeProvider = element.library.typeProvider;
+        return MethodMember(typeProvider, element, Substitution.empty, true);
       }
     } else if (element is PropertyAccessorElement) {
       if (!element.library.isNonNullableByDefault) {
@@ -649,12 +686,15 @@
       } else if (element is Member) {
         var member = element as Member;
         return PropertyAccessorMember(
+          member._typeProvider,
           member._declaration,
           member._substitution,
           true,
         );
       } else {
-        return PropertyAccessorMember(element, Substitution.empty, true);
+        var typeProvider = element.library.typeProvider;
+        return PropertyAccessorMember(
+            typeProvider, element, Substitution.empty, true);
       }
     } else {
       return element;
@@ -666,6 +706,7 @@
 /// type parameters are known.
 class MethodMember extends ExecutableMember implements MethodElement {
   factory MethodMember(
+    TypeProviderImpl typeProvider,
     MethodElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
@@ -675,6 +716,7 @@
       substitution,
     );
     return MethodMember._(
+      typeProvider,
       declaration,
       freshTypeParameters.substitution,
       isLegacy,
@@ -683,11 +725,12 @@
   }
 
   MethodMember._(
+    TypeProviderImpl typeProvider,
     MethodElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
     List<TypeParameterElement> typeParameters,
-  ) : super(declaration, substitution, isLegacy, typeParameters);
+  ) : super(typeProvider, declaration, substitution, isLegacy, typeParameters);
 
   @deprecated
   @override
@@ -712,7 +755,9 @@
       return method;
     }
 
+    var typeProvider = method.library.typeProvider;
     return MethodMember(
+      typeProvider,
       method,
       Substitution.fromInterfaceType(definingType),
       false,
@@ -726,7 +771,8 @@
     if (substitution.map.isEmpty) {
       return element;
     }
-    return MethodMember(element, substitution, false);
+    var typeProvider = element.library.typeProvider;
+    return MethodMember(typeProvider, element, substitution, false);
   }
 }
 
@@ -739,6 +785,7 @@
   final List<TypeParameterElement> typeParameters;
 
   factory ParameterMember(
+    TypeProviderImpl typeProvider,
     ParameterElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
@@ -748,6 +795,7 @@
       substitution,
     );
     return ParameterMember._(
+      typeProvider,
       declaration,
       freshTypeParameters.substitution,
       isLegacy,
@@ -758,11 +806,12 @@
   /// Initialize a newly created element to represent a parameter, based on the
   /// [declaration], with applied [substitution].
   ParameterMember._(
+    TypeProviderImpl typeProvider,
     ParameterElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
     this.typeParameters,
-  ) : super(declaration, substitution, isLegacy);
+  ) : super(typeProvider, declaration, substitution, isLegacy);
 
   @deprecated
   @override
@@ -828,6 +877,7 @@
 class PropertyAccessorMember extends ExecutableMember
     implements PropertyAccessorElement {
   factory PropertyAccessorMember(
+    TypeProviderImpl typeProvider,
     PropertyAccessorElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
@@ -837,6 +887,7 @@
       substitution,
     );
     return PropertyAccessorMember._(
+      typeProvider,
       declaration,
       freshTypeParameters.substitution,
       isLegacy,
@@ -845,11 +896,12 @@
   }
 
   PropertyAccessorMember._(
+    TypeProviderImpl typeProvider,
     PropertyAccessorElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
     List<TypeParameterElement> typeParameters,
-  ) : super(declaration, substitution, isLegacy, typeParameters);
+  ) : super(typeProvider, declaration, substitution, isLegacy, typeParameters);
 
   @deprecated
   @override
@@ -861,7 +913,8 @@
     if (baseGetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseGetter, _substitution, isLegacy);
   }
 
   @override
@@ -870,7 +923,8 @@
     if (baseSetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseSetter, _substitution, isLegacy);
   }
 
   @override
@@ -891,9 +945,10 @@
     // TODO
     PropertyInducingElement variable = declaration.variable;
     if (variable is FieldElement) {
-      return FieldMember(variable, _substitution, isLegacy);
+      return FieldMember(_typeProvider, variable, _substitution, isLegacy);
     } else if (variable is TopLevelVariableElement) {
-      return TopLevelVariableMember(variable, _substitution, isLegacy);
+      return TopLevelVariableMember(
+          _typeProvider, variable, _substitution, isLegacy);
     }
     return variable;
   }
@@ -921,7 +976,9 @@
       return accessor;
     }
 
+    var typeProvider = accessor.library.typeProvider;
     return PropertyAccessorMember(
+      typeProvider,
       accessor,
       Substitution.fromInterfaceType(definingType),
       false,
@@ -932,10 +989,11 @@
 class TopLevelVariableMember extends VariableMember
     implements TopLevelVariableElement {
   TopLevelVariableMember(
+    TypeProviderImpl typeProvider,
     VariableElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
-  ) : super(declaration, substitution, isLegacy);
+  ) : super(typeProvider, declaration, substitution, isLegacy);
 
   @override
   TopLevelVariableElement get declaration => _declaration;
@@ -946,7 +1004,8 @@
     if (baseGetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseGetter, _substitution, isLegacy);
   }
 
   @override
@@ -961,7 +1020,8 @@
     if (baseSetter == null) {
       return null;
     }
-    return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+    return PropertyAccessorMember(
+        _typeProvider, baseSetter, _substitution, isLegacy);
   }
 
   @override
@@ -978,10 +1038,11 @@
   /// Initialize a newly created element to represent a variable, based on the
   /// [declaration], with applied [substitution].
   VariableMember(
+    TypeProviderImpl typeProvider,
     VariableElement declaration,
     MapSubstitution substitution,
     bool isLegacy,
-  ) : super(declaration, substitution, isLegacy);
+  ) : super(typeProvider, declaration, substitution, isLegacy);
 
   @deprecated
   @override
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a5956bb..c86ea47 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -1469,29 +1469,6 @@
     expect(typeA.getMethod(methodName), same(methodM));
   }
 
-  void test_getMethod_parameterized_doesNotUseTypeParameter() {
-    //
-    // class A<E> { B m() {} }
-    // class B {}
-    //
-    var classA = ElementFactory.classElement2("A", ["E"]);
-    InterfaceType typeB = interfaceTypeStar(class_(name: 'B'));
-    String methodName = "m";
-    MethodElementImpl methodM =
-        ElementFactory.methodElement(methodName, typeB, []);
-    classA.methods = <MethodElement>[methodM];
-    //
-    // A<I>
-    //
-    InterfaceType typeI = interfaceTypeStar(class_(name: 'I'));
-    InterfaceTypeImpl typeAI =
-        interfaceTypeStar(classA, typeArguments: <DartType>[typeI]);
-    MethodElement method = typeAI.getMethod(methodName);
-    expect(method, isNotNull);
-    FunctionType methodType = method.type;
-    expect(methodType.typeArguments, isEmpty);
-  }
-
   void test_getMethod_parameterized_usesTypeParameter() {
     //
     // class A<E> { E m(E p) {} }