Chromium Code Reviews| Index: pkg/analyzer/lib/src/dart/element/type.dart |
| diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart |
| index 2c59228796fe5cf96fea8c7be536a8a734ec750f..b39ffddd04388e16757dc1d9816e6f5b6b002168 100644 |
| --- a/pkg/analyzer/lib/src/dart/element/type.dart |
| +++ b/pkg/analyzer/lib/src/dart/element/type.dart |
| @@ -711,6 +711,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| needsComma = true; |
| } |
| } |
| + |
| void startOptionalParameters() { |
| if (needsComma) { |
| buffer.write(", "); |
| @@ -797,14 +798,14 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| return relate( |
| this, |
| type, |
| - (DartType t, DartType s) => |
| + (DartType t, DartType s, _, __) => |
| (t as TypeImpl).isMoreSpecificThan(s, withDynamic), |
| new TypeSystemImpl().instantiateToBounds); |
| } |
| @override |
| bool isSubtypeOf(DartType type) { |
| - return relate(this, type, (DartType t, DartType s) => t.isAssignableTo(s), |
| + return relate(this, type, (DartType t, DartType s, _, __) => t.isAssignableTo(s), |
|
Leaf
2016/09/12 23:42:37
length
Jennifer Messerly
2016/09/13 00:16:21
Done.
|
| new TypeSystemImpl().instantiateToBounds); |
| } |
| @@ -966,17 +967,18 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| * |
| * Used for the various relations on function types which have the same |
| * structural rules for handling optional parameters and arity, but use their |
| - * own relation for comparing corresponding paramaters or return types. |
| + * own relation for comparing corresponding parameters or return types. |
| * |
| * If [returnRelation] is omitted, uses [parameterRelation] for both. |
| */ |
| static bool relate( |
| FunctionType t, |
| DartType other, |
| - bool parameterRelation(DartType t, DartType s), |
| + bool parameterRelation( |
| + DartType t, DartType s, bool tIsCovariant, bool sIsCovariant), |
| DartType instantiateToBounds(DartType t), |
| {bool returnRelation(DartType t, DartType s)}) { |
| - returnRelation ??= parameterRelation; |
| + returnRelation ??= (t, s) => parameterRelation(t, s, false, false); |
| // Trivial base cases. |
| if (other == null) { |
| @@ -1014,12 +1016,39 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| } |
| // Test the parameter types. |
| - List<DartType> tRequired = t.normalParameterTypes; |
| - List<DartType> sRequired = s.normalParameterTypes; |
| - List<DartType> tOptional = t.optionalParameterTypes; |
| - List<DartType> sOptional = s.optionalParameterTypes; |
| - Map<String, DartType> tNamed = t.namedParameterTypes; |
| - Map<String, DartType> sNamed = s.namedParameterTypes; |
| + |
| + // TODO(jmesserly): this could be implemented with less allocation if we |
| + // wanted, by taking advantage of the fact that positional arguments must |
| + // appear before named ones. |
| + var tRequired = <ParameterElement>[]; |
| + var tOptional = <ParameterElement>[]; |
| + var tNamed = <String, ParameterElement>{}; |
| + for (var p in t.parameters) { |
| + var kind = p.parameterKind; |
| + if (kind == ParameterKind.REQUIRED) { |
| + tRequired.add(p); |
| + } else if (kind == ParameterKind.POSITIONAL) { |
| + tOptional.add(p); |
| + } else { |
| + assert(kind == ParameterKind.NAMED); |
| + tNamed[p.name] = p; |
| + } |
| + } |
| + |
| + var sRequired = <ParameterElement>[]; |
| + var sOptional = <ParameterElement>[]; |
| + var sNamed = <String, ParameterElement>{}; |
| + for (var p in s.parameters) { |
| + var kind = p.parameterKind; |
| + if (kind == ParameterKind.REQUIRED) { |
| + sRequired.add(p); |
| + } else if (kind == ParameterKind.POSITIONAL) { |
| + sOptional.add(p); |
| + } else { |
| + assert(kind == ParameterKind.NAMED); |
| + sNamed[p.name] = p; |
| + } |
| + } |
| // If one function has positional and the other has named parameters, |
| // they don't relate. |
| @@ -1037,19 +1066,20 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| // For each named parameter in s, make sure we have a corresponding one |
| // that relates. |
| for (String key in sNamed.keys) { |
| - var tParamType = tNamed[key]; |
| - if (tParamType == null) { |
| + var tParam = tNamed[key]; |
| + if (tParam == null) { |
| return false; |
| } |
| - if (!parameterRelation(tParamType, sNamed[key])) { |
| + var sParam = sNamed[key]; |
| + if (!parameterRelation(tParam.type, sParam.type, tParam.isCovariant, sParam.isCovariant)) { |
| return false; |
| } |
| } |
| // Make sure all of the positional parameters (both required and optional) |
| // relate to each other. |
| - List<DartType> tPositional = tRequired; |
| - List<DartType> sPositional = sRequired; |
| + var tPositional = tRequired; |
| + var sPositional = sRequired; |
| if (tOptional.isNotEmpty) { |
| tPositional = tPositional.toList()..addAll(tOptional); |
| @@ -1070,7 +1100,9 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
| } |
| for (int i = 0; i < sPositional.length; i++) { |
| - if (!parameterRelation(tPositional[i], sPositional[i])) { |
| + var tParam = tPositional[i]; |
| + var sParam = sPositional[i]; |
| + if (!parameterRelation(tParam.type, sParam.type, tParam.isCovariant, sParam.isCovariant)) { |
| return false; |
| } |
| } |
| @@ -1936,6 +1968,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { |
| visitedClasses.remove(type.element); |
| } |
| } |
| + |
| recurse(this); |
| return result; |
| } |
| @@ -1959,7 +1992,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { |
| List<InterfaceType> s = _intersection(si, sj); |
| return computeTypeAtMaxUniqueDepth(s); |
| } |
| - |
| + |
| /** |
| * Return the type from the [types] list that has the longest inheritence path |
| * to Object of unique length. |