mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:10:27 +00:00
fix #27454, prune FunctionTypeImpl.parameters
without this, using ".parameters" resulted in inconsistent types compared with ".returnType" ".*parameterTypes" and other APIs. R=vsm@google.com Review URL: https://codereview.chromium.org/2378243004 .
This commit is contained in:
parent
b281cb4f2d
commit
2e80071cfe
|
@ -742,34 +742,6 @@ class ParameterMember extends VariableMember
|
|||
super.visitChildren(visitor);
|
||||
safelyVisitChildren(parameters, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given [parameter]'s type is different when any type parameters from
|
||||
* the defining type's declaration are replaced with the actual type
|
||||
* arguments from the [definingType], create a parameter member representing
|
||||
* the given parameter. Return the member that was created, or the base
|
||||
* parameter if no member was created.
|
||||
*/
|
||||
static ParameterElement from(
|
||||
ParameterElement parameter, ParameterizedType definingType) {
|
||||
if (parameter == null || definingType.typeArguments.length == 0) {
|
||||
return parameter;
|
||||
}
|
||||
// Check if parameter type depends on defining type type arguments.
|
||||
// It is possible that we did not resolve field formal parameter yet,
|
||||
// so skip this check for it.
|
||||
if (parameter is FieldFormalParameterElement) {
|
||||
return new FieldFormalParameterMember(parameter, definingType);
|
||||
} else {
|
||||
DartType baseType = parameter.type;
|
||||
List<DartType> argumentTypes = definingType.typeArguments;
|
||||
List<DartType> parameterTypes =
|
||||
TypeParameterTypeImpl.getTypes(definingType.typeParameters);
|
||||
DartType substitutedType =
|
||||
baseType.substitute2(argumentTypes, parameterTypes);
|
||||
return new ParameterMember(parameter, definingType, substitutedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -515,13 +515,41 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
|
|||
if (parameterCount == 0) {
|
||||
return baseParameters;
|
||||
}
|
||||
|
||||
// create specialized parameters
|
||||
List<ParameterElement> specializedParameters =
|
||||
new List<ParameterElement>(parameterCount);
|
||||
var specializedParams = new List<ParameterElement>(parameterCount);
|
||||
|
||||
var parameterTypes = TypeParameterTypeImpl.getTypes(typeParameters);
|
||||
for (int i = 0; i < parameterCount; i++) {
|
||||
specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
|
||||
var parameter = baseParameters[i];
|
||||
if (parameter?.type == null) {
|
||||
specializedParams[i] = parameter;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if parameter type depends on defining type type arguments, or
|
||||
// if it needs to be pruned.
|
||||
|
||||
if (parameter is FieldFormalParameterElement) {
|
||||
// TODO(jmesserly): this seems like it won't handle pruning correctly.
|
||||
specializedParams[i] = new FieldFormalParameterMember(parameter, this);
|
||||
continue;
|
||||
}
|
||||
|
||||
var baseType = parameter.type as TypeImpl;
|
||||
TypeImpl type;
|
||||
if (typeArguments.isEmpty ||
|
||||
typeArguments.length != typeParameters.length) {
|
||||
type = baseType.pruned(newPrune);
|
||||
} else {
|
||||
type = baseType.substitute2(typeArguments, parameterTypes, newPrune);
|
||||
}
|
||||
|
||||
specializedParams[i] = identical(type, baseType)
|
||||
? parameter
|
||||
: new ParameterMember(parameter, this, type);
|
||||
}
|
||||
return specializedParameters;
|
||||
return specializedParams;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -634,6 +662,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
|
|||
return instantiate(freshVariables) ==
|
||||
object.instantiate(freshVariables);
|
||||
}
|
||||
|
||||
return returnType == object.returnType &&
|
||||
TypeImpl.equalArrays(
|
||||
normalParameterTypes, object.normalParameterTypes) &&
|
||||
|
|
Loading…
Reference in a new issue