| Index: pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
|
| index e52d0c9abe94ab4465dc02c1a3a3a5e5051f334e..2607581268d4937a88856faab15e5e47c7f0a7b7 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
|
| @@ -19,7 +19,7 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
|
|
| void generateIsTest(Element other) {
|
| if (other == compiler.objectClass && other != classElement) {
|
| - // Avoid emitting [:$isObject:] on all classes but [Object].
|
| + // Avoid emitting `$isObject` on all classes but [Object].
|
| return;
|
| }
|
| builder.addProperty(namer.operatorIs(other), js('true'));
|
| @@ -64,13 +64,25 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
| }
|
| }
|
|
|
| + void generateTypeCheck(TypeCheck check) {
|
| + ClassElement checkedClass = check.cls;
|
| + // We must not call [generateIsTest] since we also want is$Object.
|
| + builder.addProperty(namer.operatorIs(checkedClass), js('true'));
|
| + Substitution substitution = check.substitution;
|
| + if (substitution != null) {
|
| + jsAst.Expression body = substitution.getCode(backend.rti);
|
| + builder.addProperty(namer.substitutionName(checkedClass), body);
|
| + }
|
| + }
|
| +
|
| generateIsTestsOn(classElement, generateIsTest,
|
| generateFunctionTypeSignature,
|
| - generateSubstitution);
|
| + generateSubstitution,
|
| + generateTypeCheck);
|
| }
|
|
|
| /**
|
| - * Generate "is tests" for [cls]: itself, and the "is tests" for the
|
| + * Generate "is tests" for [cls] itself, and the "is tests" for the
|
| * classes it implements and type argument substitution functions for these
|
| * tests. We don't need to add the "is tests" of the super class because
|
| * they will be inherited at runtime, but we may need to generate the
|
| @@ -79,10 +91,26 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
| void generateIsTestsOn(ClassElement cls,
|
| void emitIsTest(Element element),
|
| FunctionTypeSignatureEmitter emitFunctionTypeSignature,
|
| - SubstitutionEmitter emitSubstitution) {
|
| + SubstitutionEmitter emitSubstitution,
|
| + void emitTypeCheck(TypeCheck check)) {
|
| + Setlet<Element> generated = new Setlet<Element>();
|
| +
|
| if (checkedClasses.contains(cls)) {
|
| emitIsTest(cls);
|
| emitSubstitution(cls);
|
| + generated.add(cls);
|
| + }
|
| +
|
| + // Precomputed is checks.
|
| + TypeChecks typeChecks = backend.rti.requiredChecks;
|
| + Iterable<TypeCheck> classChecks = typeChecks[cls];
|
| + if (classChecks != null) {
|
| + for (TypeCheck check in classChecks) {
|
| + if (!generated.contains(check.cls)) {
|
| + emitTypeCheck(check);
|
| + generated.add(check.cls);
|
| + }
|
| + }
|
| }
|
|
|
| RuntimeTypes rti = backend.rti;
|
| @@ -100,19 +128,18 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
| // substitutions for all checks and make emitSubstitution a NOP for the
|
| // rest of this function.
|
|
|
| - Setlet<ClassElement> emitted = new Setlet<ClassElement>();
|
| // TODO(karlklose): move the computation of these checks to
|
| // RuntimeTypeInformation.
|
| while (superclass != null) {
|
| if (backend.classNeedsRti(superclass)) {
|
| emitSubstitution(superclass, emitNull: true);
|
| - emitted.add(superclass);
|
| + generated.add(superclass);
|
| }
|
| superclass = superclass.superclass;
|
| }
|
| for (DartType supertype in cls.allSupertypes) {
|
| ClassElement superclass = supertype.element;
|
| - if (emitted.contains(superclass)) continue;
|
| + if (generated.contains(superclass)) continue;
|
|
|
| if (classesUsingTypeVariableTests.contains(superclass) ||
|
| checkedClasses.contains(superclass)) {
|
| @@ -128,7 +155,6 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
| emitSubstitution = emitNothing;
|
| }
|
|
|
| - Setlet<Element> generated = new Setlet<Element>();
|
| // A class that defines a `call` method implicitly implements
|
| // [Function] and needs checks for all typedefs that are used in is-checks.
|
| if (checkedClasses.contains(compiler.functionClass) ||
|
| @@ -190,59 +216,4 @@ class TypeTestEmitter extends CodeEmitterHelper {
|
| alreadyGenerated);
|
| }
|
| }
|
| -
|
| - void emitRuntimeTypeSupport(CodeBuffer buffer, OutputUnit outputUnit) {
|
| - emitter.addComment('Runtime type support', buffer);
|
| - RuntimeTypes rti = backend.rti;
|
| - TypeChecks typeChecks = rti.requiredChecks;
|
| -
|
| - // Add checks to the constructors of instantiated classes.
|
| - // TODO(sigurdm): We should avoid running through this list for each
|
| - // output unit.
|
| -
|
| - jsAst.Statement variables = js.statement('var TRUE = !0, _;');
|
| - List<jsAst.Statement> statements = <jsAst.Statement>[];
|
| -
|
| - for (ClassElement cls in typeChecks) {
|
| - OutputUnit destination =
|
| - compiler.deferredLoadTask.outputUnitForElement(cls);
|
| - if (destination != outputUnit) continue;
|
| - // TODO(9556). The properties added to 'holder' should be generated
|
| - // directly as properties of the class object, not added later.
|
| -
|
| - // Each element is a pair: [propertyName, valueExpression]
|
| - List<List> properties = <List>[];
|
| -
|
| - for (TypeCheck check in typeChecks[cls]) {
|
| - ClassElement checkedClass = check.cls;
|
| - properties.add([namer.operatorIs(checkedClass), js('TRUE')]);
|
| - Substitution substitution = check.substitution;
|
| - if (substitution != null) {
|
| - jsAst.Expression body = substitution.getCode(rti);
|
| - properties.add([namer.substitutionName(checkedClass), body]);
|
| - }
|
| - }
|
| -
|
| - jsAst.Expression holder = backend.emitter.classAccess(cls);
|
| - if (properties.length > 1) {
|
| - // Use temporary shortened reference.
|
| - statements.add(js.statement('_ = #;', holder));
|
| - holder = js('#', '_');
|
| - }
|
| - for (List nameAndValue in properties) {
|
| - statements.add(
|
| - js.statement('#.# = #',
|
| - [holder, nameAndValue[0], nameAndValue[1]]));
|
| - }
|
| - }
|
| -
|
| - if (statements.isNotEmpty) {
|
| - buffer.write(';');
|
| - buffer.write(
|
| - jsAst.prettyPrint(
|
| - js.statement('(function() { #; #; })()', [variables, statements]),
|
| - compiler));
|
| - buffer.write('$N');
|
| - }
|
| - }
|
| }
|
|
|