| Index: compiler/java/com/google/dart/compiler/type/Types.java
|
| ===================================================================
|
| --- compiler/java/com/google/dart/compiler/type/Types.java (revision 638)
|
| +++ compiler/java/com/google/dart/compiler/type/Types.java (working copy)
|
| @@ -158,6 +158,9 @@
|
| * covariant, and paramter types are contravariant), in Dart they must just be assignable.
|
| */
|
| private boolean isSubtypeOfFunction(FunctionType t, FunctionType s) {
|
| + if (s.getKind() == TypeKind.DYNAMIC || t.getKind() == TypeKind.DYNAMIC) {
|
| + return true;
|
| + }
|
| // Classic: return type is covariant; Dart: assignable.
|
| if (!isAssignable(t.getReturnType(), s.getReturnType())) {
|
| // A function that returns a value can be used as a function where you ignore the value.
|
| @@ -178,25 +181,34 @@
|
| }
|
| Map<String, Type> tNamed = t.getNamedParameterTypes();
|
| Map<String, Type> sNamed = s.getNamedParameterTypes();
|
| - if ((tNamed == null) != (sNamed == null)) {
|
| + if (tNamed.isEmpty() && !sNamed.isEmpty()) {
|
| return false;
|
| }
|
| - if (tNamed != null) {
|
| - Map<String,Type> tMap = new LinkedHashMap<String, Type>(tNamed);
|
| - for (Entry<String, Type> sEntry : sNamed.entrySet()) {
|
| - Type type = tMap.remove(sEntry.getKey());
|
| - if (type == null) {
|
| +
|
| + // T's named parameters must be in the same order and assignable to S's but
|
| + // maybe a superset.
|
| + if (!sNamed.isEmpty()) {
|
| + LinkedHashMap<String,Type> tMap = (LinkedHashMap<String, Type>)(tNamed);
|
| + LinkedHashMap<String,Type> sMap = (LinkedHashMap<String, Type>)(sNamed);
|
| + Iterator<Entry<String, Type>> tList = tMap.entrySet().iterator();
|
| + Iterator<Entry<String, Type>> sList = sMap.entrySet().iterator();
|
| + // t named parameters must start with the named parameters of s
|
| + while (sList.hasNext()) {
|
| + if (!tList.hasNext()) {
|
| return false;
|
| }
|
| + Entry<String, Type> sEntry = sList.next();
|
| + Entry<String, Type> tEntry = tList.next();
|
| + if (!sEntry.getKey().equals(tEntry.getKey())) {
|
| + return false;
|
| + }
|
| // Classic: parameter types are contravariant; Dart: assignable.
|
| - if (!isAssignable(sEntry.getValue(), type)) {
|
| + if (!isAssignable(tEntry.getValue(), sEntry.getValue())) {
|
| return false;
|
| }
|
| }
|
| - if (!tMap.isEmpty()) {
|
| - return false;
|
| - }
|
| }
|
| +
|
| // Classic: parameter types are contravariant; Dart: assignable.
|
| return areAssignable(s.getParameterTypes().iterator(), t.getParameterTypes().iterator());
|
| }
|
|
|