| Index: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
|
| index b1cb9eb7124910b4b1212e918ee9e8a854de975f..30947c4c6ef94528288339f8d49b327bc684f3fe 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
|
| @@ -21,13 +21,62 @@ class RuntimeTypeInformation {
|
| /// instantiations and checks.
|
| Set<ClassElement> allArguments;
|
|
|
| - bool isJsNative(Element element) {
|
| - return (element == compiler.intClass ||
|
| - element == compiler.boolClass ||
|
| - element == compiler.numClass ||
|
| - element == compiler.doubleClass ||
|
| - element == compiler.stringClass ||
|
| - element == compiler.listClass);
|
| + Collection<ClassElement> cachedJsNatives;
|
| + Collection<ClassElement> get jsNatives {
|
| + if (cachedJsNatives == null) {
|
| + cachedJsNatives = <ClassElement>[compiler.intClass,
|
| + compiler.boolClass,
|
| + compiler.numClass,
|
| + compiler.doubleClass,
|
| + compiler.stringClass];
|
| + }
|
| + return cachedJsNatives;
|
| + }
|
| +
|
| + bool isJsNative(Element element) => jsNatives.contains(element);
|
| +
|
| + bool needsNativeCheck(Element element) {
|
| + return element == compiler.objectClass || isJsNative(element);
|
| + }
|
| +
|
| + /**
|
| + * Constructs the native check function for the class [element].
|
| + *
|
| + * This function will be put on the type representation for native classes
|
| + * (and Object) and is called by the helper function [:objectIsSubtype:], if
|
| + * it is on the object that represents the type to test against. We have to
|
| + * put a trivial native check on object when it is used as a type argument in
|
| + * a check because the native objects cannot have [:$isObject:] bits set on
|
| + * them.
|
| + */
|
| + jsAst.Expression getNativeCheck(Element element) {
|
| + final String parameterName = 'object';
|
| + final jsAst.VariableUse variable = new jsAst.VariableUse(parameterName);
|
| +
|
| + jsAst.Expression typeTest(String typeName) {
|
| + return js.strictEquals(
|
| + new jsAst.LiteralExpression.withData('typeof #', [variable]),
|
| + new jsAst.LiteralString("'$typeName'"));
|
| + }
|
| +
|
| + jsAst.Expression test;
|
| + if (element == compiler.objectClass) {
|
| + test = new jsAst.LiteralBool(true);
|
| + } else if (element == compiler.intClass) {
|
| + final jsAst.Expression zero = new jsAst.LiteralNumber('0');
|
| + test = js.strictEquals(variable, new jsAst.Binary('|', variable, zero));
|
| + } else if (element == compiler.boolClass) {
|
| + test = typeTest('boolean');
|
| + } else if (element == compiler.numClass) {
|
| + test = typeTest('number');
|
| + } else if (element == compiler.doubleClass) {
|
| + test = typeTest('number');
|
| + } else if (element == compiler.stringClass) {
|
| + test = typeTest('string');
|
| + } else {
|
| + return null;
|
| + }
|
| + return js.fun([parameterName], js.block(js.return_(test)));
|
| }
|
|
|
| TypeChecks cachedRequiredChecks;
|
| @@ -294,4 +343,14 @@ class TypeCheckMapping implements TypeChecks {
|
| }
|
|
|
| Iterator<ClassElement> get iterator => map.keys.iterator;
|
| +
|
| + String toString() {
|
| + StringBuffer sb = new StringBuffer();
|
| + for (ClassElement holder in this) {
|
| + for (ClassElement check in [holder]) {
|
| + sb.add('${holder.name.slowToString()}.${check.name.slowToString()}, ');
|
| + }
|
| + }
|
| + return '[$sb]';
|
| + }
|
| }
|
|
|