Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/dart_types.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
| index 9639b3d3c5130421451f63e249b5ab7965e71588..fd08d0c93ef5969a6fdb59340171091af6002818 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/dart_types.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
| @@ -999,6 +999,10 @@ class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
| if (s is !FunctionType) return false; |
| FunctionType tf = t; |
| FunctionType sf = s; |
| + if (!identical(sf.returnType, voidType) && |
| + !isAssignable(tf.returnType, sf.returnType)) { |
| + return false; |
| + } |
| Link<DartType> tps = tf.parameterTypes; |
| Link<DartType> sps = sf.parameterTypes; |
| while (!tps.isEmpty && !sps.isEmpty) { |
| @@ -1006,12 +1010,17 @@ class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
| tps = tps.tail; |
| sps = sps.tail; |
| } |
| - if (!tps.isEmpty || !sps.isEmpty) return false; |
| - if (!identical(sf.returnType, voidType) && |
| - !isAssignable(tf.returnType, sf.returnType)) { |
| + if (!tps.isEmpty) { |
| + // We must have |
| + // t.parameterTypes.length <= s.parameterTypes.length |
| return false; |
| } |
| if (!sf.namedParameters.isEmpty) { |
| + if (!sps.isEmpty) { |
| + // We must have |
| + // t.parameterTypes.length == s.parameterTypes.length |
|
karlklose
2013/04/24 11:59:20
Perhaps you could define abbreviations for t/s.par
Johnni Winther
2013/04/25 07:54:12
Done.
|
| + return false; |
| + } |
| // Since named parameters are globally ordered we can determine the |
| // subset relation with a linear search for [:sf.NamedParameters:] |
| // within [:tf.NamedParameters:]. |
| @@ -1033,23 +1042,44 @@ class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
| // We didn't find all names. |
| return false; |
| } |
| - } |
| - if (!sf.optionalParameterTypes.isEmpty) { |
| - Link<DartType> tOptionalParameterType = tf.optionalParameterTypes; |
| - Link<DartType> sOptionalParameterType = sf.optionalParameterTypes; |
| - while (!tOptionalParameterType.isEmpty && |
| - !sOptionalParameterType.isEmpty) { |
| - if (!isAssignable(tOptionalParameterType.head, |
| - sOptionalParameterType.head)) { |
| - return false; |
| - } |
| - sOptionalParameterType = sOptionalParameterType.tail; |
| - tOptionalParameterType = tOptionalParameterType.tail; |
| + } else { |
| + // Check the remaining required parameters of [s] against the optional |
| + // parameters of [t]. |
| + tps = tf.optionalParameterTypes; |
| + while (!tps.isEmpty && !sps.isEmpty) { |
| + if (!isAssignable(tps.head, sps.head)) return false; |
| + tps = tps.tail; |
| + sps = sps.tail; |
| } |
| - if (!sOptionalParameterType.isEmpty) { |
| - // We didn't find enough optional parameters. |
| + if (!sps.isEmpty) { |
|
karlklose
2013/04/24 11:59:20
It would be nicer to check the number of arguments
Johnni Winther
2013/04/25 07:54:12
Added a TODO for a more readable implementation.
|
| + // We must have |
| + // t.parameterTypes.length + t.optionalParameterTypes.length |
| + // >= s.parameterTypes.length |
| return false; |
| } |
| + if (!sf.optionalParameterTypes.isEmpty) { |
| + // Check the remaining optional parameters of [s] against the remaining |
| + // optional parameters of [t]. |
| + sps = sf.optionalParameterTypes; |
| + while (!tps.isEmpty && !sps.isEmpty) { |
| + if (!isAssignable(tps.head, sps.head)) return false; |
| + tps = tps.tail; |
| + sps = sps.tail; |
| + } |
| + if (!sps.isEmpty) { |
| + // We didn't find enough parameters: |
| + // We must have |
| + // t.parameterTypes.length + t.optionalParameterTypes.length |
| + // <= s.parameterTypes.length + s.optionalParameterTypes.length |
| + return false; |
| + } |
| + } else { |
| + if (!sps.isEmpty) { |
| + // We must have |
| + // t.parameterTypes.length == s.parameterTypes.length |
| + return false; |
| + } |
| + } |
| } |
| return true; |
| } |