| Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| index c7b57180345c52a334056562f02a5b89a16c61ca..d93901a54171f71e714a5bf55d49942ca438abbc 100644
|
| --- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| +++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| @@ -129,7 +129,7 @@ flattenFutures(builder) => JS('', '''(() => {
|
| })()''');
|
|
|
| /// Memoize a generic type constructor function.
|
| -generic(typeConstructor, [setBaseClass]) => JS('', '''(() => {
|
| +generic(typeConstructor, setBaseClass) => JS('', '''(() => {
|
| let length = $typeConstructor.length;
|
| if (length < 1) {
|
| $throwInternalError('must have at least one generic type argument');
|
| @@ -561,3 +561,67 @@ defineEnumValues(enumClass, names) {
|
| }
|
| JS('', '#.values = #', enumClass, constList(values, enumClass));
|
| }
|
| +
|
| +/// Adds type test predicates to a class/interface type [ctor], using the
|
| +/// provided [isClass] JS Symbol.
|
| +///
|
| +/// This will operate quickly for non-generic types, native extension types,
|
| +/// as well as matching exact generic type arguments:
|
| +///
|
| +/// class C<T> {}
|
| +/// class D extends C<int> {}
|
| +/// main() { dynamic d = new D(); d as C<int>; }
|
| +///
|
| +addTypeTests(ctor, isClass) {
|
| + if (isClass == null) isClass = JS('', 'Symbol("_is_" + ctor.name)');
|
| + // TODO(jmesserly): since we know we're dealing with class/interface types,
|
| + // we can optimize this rather than go through the generic `dart.is` helpers.
|
| + JS('', '#.prototype[#] = true', ctor, isClass);
|
| + JS(
|
| + '',
|
| + '''#.is = function is_C(obj) {
|
| + if (obj != null && obj[#]) return true;
|
| + return #(obj, this);
|
| + }''',
|
| + ctor,
|
| + isClass,
|
| + instanceOf);
|
| + JS(
|
| + '',
|
| + '''#.as = function as_C(obj) {
|
| + if (obj == null || obj[#]) return obj;
|
| + return #(obj, this, false);
|
| + }''',
|
| + ctor,
|
| + isClass,
|
| + cast);
|
| + JS(
|
| + '',
|
| + '''#._check = function check_C(obj) {
|
| + if (obj == null || obj[#]) return obj;
|
| + return #(obj, this, true);
|
| + }''',
|
| + ctor,
|
| + isClass,
|
| + cast);
|
| +}
|
| +
|
| +// TODO(jmesserly): should we do this for all interfaces?
|
| +
|
| +/// The well known symbol for testing `is Future`
|
| +final isFuture = JS('', 'Symbol("_is_Future")');
|
| +
|
| +/// The well known symbol for testing `is Iterable`
|
| +final isIterable = JS('', 'Symbol("_is_Iterable")');
|
| +
|
| +/// The well known symbol for testing `is List`
|
| +final isList = JS('', 'Symbol("_is_List")');
|
| +
|
| +/// The well known symbol for testing `is Map`
|
| +final isMap = JS('', 'Symbol("_is_Map")');
|
| +
|
| +/// The well known symbol for testing `is Stream`
|
| +final isStream = JS('', 'Symbol("_is_Stream")');
|
| +
|
| +/// The well known symbol for testing `is StreamSubscription`
|
| +final isStreamSubscription = JS('', 'Symbol("_is_StreamSubscription")');
|
|
|