Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
index 7ec9c3d9b75bff0129bc1c2d1c927300562e4b4d..f3c907e8ee937792a8265dc45fae038e7024b957 100644 |
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart |
@@ -487,6 +487,19 @@ class GenericFunctionType extends AbstractFunctionType { |
return _typeFormals; |
} |
+ checkBounds(List typeArgs) { |
+ var bounds = instantiateTypeBounds(typeArgs); |
+ var typeFormals = this.typeFormals; |
+ for (var i = 0; i < typeArgs.length; i++) { |
+ var type = typeArgs[i]; |
+ var bound = bounds[i]; |
+ if (!JS('bool', '#', isSubtype(type, bound))) { |
+ throwStrongModeError('type `$type` does not extend `$bound`' |
+ ' of `${typeFormals[i]}`.'); |
+ } |
+ } |
+ } |
+ |
instantiate(typeArgs) { |
var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs); |
return JS('', '#.create(#, #[0], #[1], #[2])', FunctionType, definite, |
@@ -788,34 +801,28 @@ isFunctionSubtype(ft1, ft2, isCovariant) => JS( |
return true; |
})()'''); |
-/// TODO(leafp): This duplicates code in operations.dart. |
-/// I haven't found a way to factor it out that makes the |
-/// code generator happy though. |
-_subtypeMemo(f) => JS( |
- '', |
- '''(() => { |
- let memo = new Map(); |
- return (t1, t2) => { |
- let map = memo.get(t1); |
- let result; |
- if (map) { |
- result = map.get(t2); |
- if (result !== void 0) return result; |
- } else { |
- memo.set(t1, map = new Map()); |
- } |
- result = $f(t1, t2); |
- map.set(t2, result); |
- return result; |
- }; |
-})()'''); |
- |
/// Returns true if [t1] <: [t2]. |
/// Returns false if [t1] </: [t2] in both spec and strong mode |
/// Returns undefined if [t1] </: [t2] in strong mode, but spec |
/// mode may differ |
-final isSubtype = JS( |
- '', '$_subtypeMemo((t1, t2) => (t1 === t2) || $_isSubtype(t1, t2, true))'); |
+bool isSubtype(t1, t2) { |
+ // TODO(leafp): This duplicates code in operations.dart. |
+ // I haven't found a way to factor it out that makes the |
+ // code generator happy though. |
+ var map = JS('', '#.get(#)', _memo, t1); |
+ bool result; |
+ if (JS('bool', '# !== void 0', map)) { |
+ result = JS('bool', '#.get(#)', map, t2); |
+ if (JS('bool', '# !== void 0', result)) return result; |
+ } else { |
+ JS('', '#.set(#, # = new Map())', _memo, t1, map); |
+ } |
+ result = JS('', '# === # || #(#, #, true)', t1, t2, _isSubtype, t1, t2); |
+ JS('', '#.set(#, #)', map, t2, result); |
+ return result; |
+} |
+ |
+final _memo = JS('', 'new Map()'); |
_isBottom(type) => JS('bool', '# == # || # == #', type, bottom, type, Null); |
@@ -830,7 +837,7 @@ _isTop(type) { |
bool _isFutureOr(type) => |
JS('bool', '# === #', getGenericClass(type), getGenericClass(FutureOr)); |
-_isSubtype(t1, t2, isCovariant) => JS( |
+bool _isSubtype(t1, t2, isCovariant) => JS( |
'', |
'''(() => { |
if ($t1 === $t2) return true; |