private JsExpression generateRawInterfaceTypeComparison( JsExpression lhs, DartTypeNode typeNode, SourceInfo src) { ClassElement element = (ClassElement) typeNode.getType().getElement(); if (element.equals(typeProvider.getObjectType().getElement())) { // Everything is an object, including null return this.translationContext.getProgram().getTrueLiteral(); } String builtin = builtInTypeChecks.get(element); if (builtin != null) { return call(src, nameref(src, builtin), lhs); } // Due to implementing implied interfaces of classes, we always have to // use $implements$ rather than using JS instanceof for classes. // Inject: !!(tmp = target, tmp && tmp.$implements$type) JsProgram program = translationContext.getProgram(); JsName tmp = context.createTemporary(); String mangledClass = translationContext.getMangler().mangleClassName(element); return not( src, not( src, comma( src, assign(src, tmp.makeRef(), lhs), and( src, neq(src, tmp.makeRef().setSourceRef(src), program.getNullLiteral()), nameref(src, tmp, "$implements$" + mangledClass))))); }
private void injectInterfaceMarkers(ClassElement classElement, SourceInfo srcRef) { JsProgram program = translationContext.getProgram(); JsName classJsName = translationContext.getNames().getName(classElement); for (InterfaceType iface : getAllInterfaces(classElement)) { JsStatement assignment = (JsStatement) newAssignment( newNameRef( newNameRef(new JsNameRef(classJsName), "prototype"), "$implements$" + translationContext .getMangler() .mangleClassName(iface.getElement())), program.getNumberLiteral(1)) .makeStmt() .setSourceRef(srcRef); globalBlock.getStatements().add(assignment); } }