Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/type_system.dart |
| diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart |
| index 8826bfb02568bd647c9c5baff5ad75194d40f19b..39bd24b8f152e97ed5dabd68f23987796658a6d7 100644 |
| --- a/pkg/analyzer/lib/src/generated/type_system.dart |
| +++ b/pkg/analyzer/lib/src/generated/type_system.dart |
| @@ -363,7 +363,8 @@ class StrongTypeSystemImpl extends TypeSystem { |
| } |
| // Try to infer and instantiate the resulting type. |
| - var resultType = inferringTypeSystem._infer(fnType); |
| + var resultType = inferringTypeSystem._infer( |
| + fnType, fnType.typeFormals, fnType.returnType); |
| // If the instantiation failed (because some type variable constraints |
| // could not be solved, in other words, we could not find a valid subtype), |
| @@ -393,26 +394,21 @@ class StrongTypeSystemImpl extends TypeSystem { |
| /// As a simplification, we do not actually store all constraints on each type |
| /// parameter Tj. Instead we track Uj and Lj where U is the upper bound and |
| /// L is the lower bound of that type parameter. |
| - FunctionType inferGenericFunctionCall( |
| + /*=T*/ inferGenericFunctionCall/*<T extends ParameterizedType>*/( |
| TypeProvider typeProvider, |
| - FunctionType fnType, |
| - List<DartType> correspondingParameterTypes, |
| + /*=T*/ genericType, |
| + List<DartType> declaredParameterTypes, |
| List<DartType> argumentTypes, |
| + DartType declaredReturnType, |
| DartType returnContextType, |
| {ErrorReporter errorReporter, |
| AstNode errorNode}) { |
| - if (fnType.typeFormals.isEmpty) { |
| - return fnType; |
| - } |
| - |
| - // If we're in a future union context, choose either the Future<T> or the T |
| - // based on the function's return type. |
| - if (returnContextType is FutureUnionType) { |
| - var futureUnion = returnContextType as FutureUnionType; |
| - returnContextType = |
| - isSubtypeOf(fnType.returnType, typeProvider.futureDynamicType) |
| - ? futureUnion.futureOfType |
| - : futureUnion.type; |
| + // TODO(jmesserly): expose typeFormals on ParameterizedType. |
| + List<TypeParameterElement> typeFormals = genericType is FunctionType |
| + ? genericType.typeFormals |
| + : genericType.typeParameters; |
| + if (typeFormals.isEmpty) { |
| + return genericType; |
| } |
| // Create a TypeSystem that will allow certain type parameters to be |
| @@ -420,20 +416,31 @@ class StrongTypeSystemImpl extends TypeSystem { |
| // subtypes (or supertypes) as necessary, and track the constraints that |
| // are implied by this. |
| var inferringTypeSystem = |
| - new _StrongInferenceTypeSystem(typeProvider, this, fnType.typeFormals); |
| + new _StrongInferenceTypeSystem(typeProvider, this, typeFormals); |
| if (returnContextType != null) { |
| - inferringTypeSystem.isSubtypeOf(fnType.returnType, returnContextType); |
| + // If we're in a future union context, choose either the Future<T> |
| + // or the T based on the declared return type. |
| + if (returnContextType is FutureUnionType) { |
| + var futureUnion = returnContextType as FutureUnionType; |
| + returnContextType = |
| + isSubtypeOf(declaredReturnType, typeProvider.futureDynamicType) |
| + ? futureUnion.futureOfType |
| + : futureUnion.type; |
| + } |
| + |
| + inferringTypeSystem.isSubtypeOf(declaredReturnType, returnContextType); |
| } |
| for (int i = 0; i < argumentTypes.length; i++) { |
| // Try to pass each argument to each parameter, recording any type |
| // parameter bounds that were implied by this assignment. |
| inferringTypeSystem.isSubtypeOf( |
| - argumentTypes[i], correspondingParameterTypes[i]); |
| + argumentTypes[i], declaredParameterTypes[i]); |
| } |
| - return inferringTypeSystem._infer(fnType, errorReporter, errorNode); |
| + return inferringTypeSystem._infer( |
| + genericType, typeFormals, declaredReturnType, errorReporter, errorNode); |
| } |
| /** |
| @@ -1511,10 +1518,11 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
| /// Given the constraints that were given by calling [isSubtypeOf], find the |
| /// instantiation of the generic function that satisfies these constraints. |
| - FunctionType _infer(FunctionType fnType, |
| + /*=T*/ _infer/*<T extends ParameterizedType>*/(/*=T*/ genericType, |
| + List<TypeParameterElement> typeFormals, DartType declaredReturnType, |
| [ErrorReporter errorReporter, AstNode errorNode]) { |
| List<TypeParameterType> fnTypeParams = |
| - TypeParameterTypeImpl.getTypes(fnType.typeFormals); |
| + TypeParameterTypeImpl.getTypes(typeFormals); |
| // Initialize the inferred type array. |
| // |
| @@ -1561,7 +1569,7 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
| // |
| // Otherwise we choose the more precise lower bound. |
| _TypeParameterVariance variance = |
| - new _TypeParameterVariance.from(typeParam, fnType.returnType); |
| + new _TypeParameterVariance.from(typeParam, declaredReturnType); |
| _TypeParameterBound bound = _bounds[typeParam]; |
| DartType lowerBound = bound.lower; |
| @@ -1600,7 +1608,7 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl { |
| } |
| // Return the instantiated type. |
| - return fnType.instantiate(inferredTypes); |
| + return genericType.instantiate(inferredTypes) as dynamic/*=T*/; |
|
Leaf
2016/09/14 23:11:35
Does this mean that .instantiate should have a bet
Jennifer Messerly
2016/09/14 23:18:41
Maybe something like:
abstract class Parameterize
|
| } |
| @override |