OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart_types; | 5 library dart_types; |
6 | 6 |
7 import 'dart:math' show min; | 7 import 'dart:math' show min; |
8 | 8 |
9 import 'common/resolution.dart' show Resolution; | 9 import 'common/resolution.dart' show Resolution; |
10 import 'common.dart'; | 10 import 'common.dart'; |
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 } | 1020 } |
1021 | 1021 |
1022 bool invalidTypeArguments(DartType t, DartType s); | 1022 bool invalidTypeArguments(DartType t, DartType s); |
1023 | 1023 |
1024 bool invalidFunctionReturnTypes(DartType t, DartType s); | 1024 bool invalidFunctionReturnTypes(DartType t, DartType s); |
1025 | 1025 |
1026 bool invalidFunctionParameterTypes(DartType t, DartType s); | 1026 bool invalidFunctionParameterTypes(DartType t, DartType s); |
1027 | 1027 |
1028 bool invalidTypeVariableBounds(DartType bound, DartType s); | 1028 bool invalidTypeVariableBounds(DartType bound, DartType s); |
1029 | 1029 |
| 1030 bool invalidCallableType(DartType callType, DartType s); |
| 1031 |
1030 /// Handle as dynamic for both subtype and more specific relation to avoid | 1032 /// Handle as dynamic for both subtype and more specific relation to avoid |
1031 /// spurious errors from malformed types. | 1033 /// spurious errors from malformed types. |
1032 bool visitMalformedType(MalformedType t, DartType s) => true; | 1034 bool visitMalformedType(MalformedType t, DartType s) => true; |
1033 | 1035 |
1034 bool visitInterfaceType(InterfaceType t, DartType s) { | 1036 bool visitInterfaceType(InterfaceType t, DartType s) { |
1035 // TODO(johnniwinther): Currently needed since literal types like int, | 1037 // TODO(johnniwinther): Currently needed since literal types like int, |
1036 // double, bool etc. might not have been resolved yet. | 1038 // double, bool etc. might not have been resolved yet. |
1037 t.element.ensureResolved(resolution); | 1039 t.element.ensureResolved(resolution); |
1038 | 1040 |
1039 bool checkTypeArguments(InterfaceType instance, InterfaceType other) { | 1041 bool checkTypeArguments(InterfaceType instance, InterfaceType other) { |
1040 List<DartType> tTypeArgs = instance.typeArguments; | 1042 List<DartType> tTypeArgs = instance.typeArguments; |
1041 List<DartType> sTypeArgs = other.typeArguments; | 1043 List<DartType> sTypeArgs = other.typeArguments; |
1042 assert(tTypeArgs.length == sTypeArgs.length); | 1044 assert(tTypeArgs.length == sTypeArgs.length); |
1043 for (int i = 0; i < tTypeArgs.length; i++) { | 1045 for (int i = 0; i < tTypeArgs.length; i++) { |
1044 if (invalidTypeArguments(tTypeArgs[i], sTypeArgs[i])) { | 1046 if (invalidTypeArguments(tTypeArgs[i], sTypeArgs[i])) { |
1045 return false; | 1047 return false; |
1046 } | 1048 } |
1047 } | 1049 } |
1048 return true; | 1050 return true; |
1049 } | 1051 } |
1050 | 1052 |
1051 if (s is InterfaceType) { | 1053 if (s is InterfaceType) { |
1052 InterfaceType instance = t.asInstanceOf(s.element); | 1054 InterfaceType instance = t.asInstanceOf(s.element); |
1053 return instance != null && checkTypeArguments(instance, s); | 1055 if (instance != null && checkTypeArguments(instance, s)) { |
1054 } else { | 1056 return true; |
1055 return false; | 1057 } |
1056 } | 1058 } |
| 1059 |
| 1060 if (s == coreTypes.functionType && t.element.callType != null) { |
| 1061 return true; |
| 1062 } else if (s is FunctionType) { |
| 1063 FunctionType callType = t.callType; |
| 1064 return callType != null && !invalidCallableType(callType, s); |
| 1065 } |
| 1066 |
| 1067 return false; |
1057 } | 1068 } |
1058 | 1069 |
1059 bool visitFunctionType(FunctionType t, DartType s) { | 1070 bool visitFunctionType(FunctionType t, DartType s) { |
1060 if (s == coreTypes.functionType) { | 1071 if (s == coreTypes.functionType) { |
1061 return true; | 1072 return true; |
1062 } | 1073 } |
1063 if (s is! FunctionType) return false; | 1074 if (s is! FunctionType) return false; |
1064 FunctionType tf = t; | 1075 FunctionType tf = t; |
1065 FunctionType sf = s; | 1076 FunctionType sf = s; |
1066 if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) { | 1077 if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 return !s.isVoid && !isMoreSpecific(t, s); | 1227 return !s.isVoid && !isMoreSpecific(t, s); |
1217 } | 1228 } |
1218 | 1229 |
1219 bool invalidFunctionParameterTypes(DartType t, DartType s) { | 1230 bool invalidFunctionParameterTypes(DartType t, DartType s) { |
1220 return !isMoreSpecific(t, s); | 1231 return !isMoreSpecific(t, s); |
1221 } | 1232 } |
1222 | 1233 |
1223 bool invalidTypeVariableBounds(DartType bound, DartType s) { | 1234 bool invalidTypeVariableBounds(DartType bound, DartType s) { |
1224 return !isMoreSpecific(bound, s); | 1235 return !isMoreSpecific(bound, s); |
1225 } | 1236 } |
| 1237 |
| 1238 bool invalidCallableType(DartType callType, DartType s) { |
| 1239 return !isMoreSpecific(callType, s); |
| 1240 } |
1226 } | 1241 } |
1227 | 1242 |
1228 /** | 1243 /** |
1229 * Type visitor that determines the subtype relation two types. | 1244 * Type visitor that determines the subtype relation two types. |
1230 */ | 1245 */ |
1231 class SubtypeVisitor extends MoreSpecificVisitor { | 1246 class SubtypeVisitor extends MoreSpecificVisitor { |
1232 SubtypeVisitor(Resolution resolution) : super(resolution); | 1247 SubtypeVisitor(Resolution resolution) : super(resolution); |
1233 | 1248 |
1234 bool isSubtype(DartType t, DartType s) { | 1249 bool isSubtype(DartType t, DartType s) { |
1235 return t.treatAsDynamic || isMoreSpecific(t, s); | 1250 return t.treatAsDynamic || isMoreSpecific(t, s); |
(...skipping 12 matching lines...) Expand all Loading... |
1248 } | 1263 } |
1249 | 1264 |
1250 bool invalidFunctionParameterTypes(DartType t, DartType s) { | 1265 bool invalidFunctionParameterTypes(DartType t, DartType s) { |
1251 return !isAssignable(t, s); | 1266 return !isAssignable(t, s); |
1252 } | 1267 } |
1253 | 1268 |
1254 bool invalidTypeVariableBounds(DartType bound, DartType s) { | 1269 bool invalidTypeVariableBounds(DartType bound, DartType s) { |
1255 return !isSubtype(bound, s); | 1270 return !isSubtype(bound, s); |
1256 } | 1271 } |
1257 | 1272 |
1258 bool visitInterfaceType(InterfaceType t, DartType s) { | 1273 bool invalidCallableType(DartType callType, DartType s) { |
1259 if (super.visitInterfaceType(t, s)) return true; | 1274 return !isSubtype(callType, s); |
1260 | |
1261 if (s == coreTypes.functionType && t.element.callType != null) { | |
1262 return true; | |
1263 } else if (s is FunctionType) { | |
1264 FunctionType callType = t.callType; | |
1265 return callType != null && isSubtype(callType, s); | |
1266 } | |
1267 return false; | |
1268 } | 1275 } |
1269 } | 1276 } |
1270 | 1277 |
1271 /** | 1278 /** |
1272 * Callback used to check whether the [typeArgument] of [type] is a valid | 1279 * Callback used to check whether the [typeArgument] of [type] is a valid |
1273 * substitute for the bound of [typeVariable]. [bound] holds the bound against | 1280 * substitute for the bound of [typeVariable]. [bound] holds the bound against |
1274 * which [typeArgument] should be checked. | 1281 * which [typeArgument] should be checked. |
1275 */ | 1282 */ |
1276 typedef void CheckTypeVariableBound(GenericType type, DartType typeArgument, | 1283 typedef void CheckTypeVariableBound(GenericType type, DartType typeArgument, |
1277 TypeVariableType typeVariable, DartType bound); | 1284 TypeVariableType typeVariable, DartType bound); |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2012 sb.write(', '); | 2019 sb.write(', '); |
2013 } | 2020 } |
2014 namedParameterTypes[index].accept(this, namedParameters[index]); | 2021 namedParameterTypes[index].accept(this, namedParameters[index]); |
2015 needsComma = true; | 2022 needsComma = true; |
2016 } | 2023 } |
2017 sb.write('}'); | 2024 sb.write('}'); |
2018 } | 2025 } |
2019 sb.write(')'); | 2026 sb.write(')'); |
2020 } | 2027 } |
2021 } | 2028 } |
OLD | NEW |