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) {} }