| 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..e4f926f32c2d99a151bb0974e20fbee38a1a849f 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,17 @@ 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),
|
| new TypeSystemImpl().instantiateToBounds);
|
| }
|
|
|
| @@ -966,17 +970,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 +1019,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 +1069,21 @@ 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 +1104,10 @@ 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 +1973,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
|
| visitedClasses.remove(type.element);
|
| }
|
| }
|
| +
|
| recurse(this);
|
| return result;
|
| }
|
| @@ -1959,7 +1997,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.
|
|
|