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:
John Messerly 2016-09-29 15:54:25 -07:00
parent b281cb4f2d
commit 2e80071cfe
2 changed files with 33 additions and 32 deletions

View file

@ -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);
}
}
}
/**

View file

@ -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) &&