| Index: sdk/lib/_internal/compiler/implementation/lib/js_rti.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart b/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart
|
| index c6d5727c0044537c9e3251f3c7965cc8fb5db787..2085dc4a64bc31ed6d1642923ed095801bb39d5f 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/lib/js_rti.dart
|
| @@ -119,13 +119,13 @@ substitute(var substitution, var arguments) {
|
| * against.
|
| */
|
| bool checkSubtype(Object object, String isField, List checks, String asField) {
|
| - if (object == null) return false;
|
| + if (object == null) return true;
|
| var arguments = getRuntimeTypeInfo(object);
|
| // Interceptor is needed for JSArray and native classes.
|
| // TODO(sra): It could be a more specialized interceptor since [object] is not
|
| // `null` or a primitive.
|
| // TODO(9586): Move type info for static functions onto an interceptor.
|
| - var interceptor = isJsFunction(object) ? object : getInterceptor(object);
|
| + var interceptor = getInterceptor(object);
|
| bool isSubclass = getField(interceptor, isField);
|
| // When we read the field and it is not there, [isSubclass] will be [:null:].
|
| if (isSubclass == null || !isSubclass) return false;
|
| @@ -134,6 +134,19 @@ bool checkSubtype(Object object, String isField, List checks, String asField) {
|
| return checkArguments(substitution, arguments, checks);
|
| }
|
|
|
| +Object assertSubtype(Object object, String isField, List checks,
|
| + String asField) {
|
| + if (!checkSubtype(object, isField, checks, asField)) {
|
| + // Shorten the field name to the class name and append the textual
|
| + // representation of the type arguments.
|
| + int prefixLength = JS_OPERATOR_IS_PREFIX().length;
|
| + String typeName = '${isField.substring(prefixLength, isField.length)}'
|
| + '${joinArguments(checks, 0)}';
|
| + throw new TypeErrorImplementation(object, typeName);
|
| + }
|
| + return object;
|
| +}
|
| +
|
| /**
|
| * Check that the types in the list [arguments] are subtypes of the types in
|
| * list [checks] (at the respective positions), possibly applying [substitution]
|
| @@ -174,7 +187,7 @@ getField(var object, var name) => JS('var', r'#[#]', object, name);
|
| * representation [t], which is a type representation as described in the
|
| * comment on [isSubtype].
|
| */
|
| -bool objectIsSubtype(Object o, var t) {
|
| +bool checkSubtypeOfRuntimeType(Object o, var t) {
|
| if (JS('bool', '# == null', o) || JS('bool', '# == null', t)) return true;
|
| // Get the runtime type information from the object here, because we may
|
| // overwrite o with the interceptor below.
|
| @@ -199,6 +212,13 @@ bool objectIsSubtype(Object o, var t) {
|
| return isSubtype(type, t);
|
| }
|
|
|
| +Object assertSubtypeOfRuntimeType(Object object, var type) {
|
| + if (!checkSubtypeOfRuntimeType(object, type)) {
|
| + throw new TypeErrorImplementation(object, runtimeTypeToString(type));
|
| + }
|
| + return object;
|
| +}
|
| +
|
| /**
|
| * Check whether the type represented by [s] is a subtype of the type
|
| * represented by [t].
|
| @@ -224,6 +244,10 @@ bool isSubtype(var s, var t) {
|
| // constructed from the type of [t].
|
| var typeOfS = isJsArray(s) ? s[0] : s;
|
| var typeOfT = isJsArray(t) ? t[0] : t;
|
| + // TODO(johnniwinther): replace this with the real function subtype test.
|
| + if (JS('bool', '#.func', s) == true || JS('bool', '#.func', t) == true ) {
|
| + return true;
|
| + }
|
| // Check for a subtyping flag.
|
| var test = '${JS_OPERATOR_IS_PREFIX()}${runtimeTypeToString(typeOfT)}';
|
| if (getField(typeOfS, test) == null) return false;
|
|
|