protected void generateBindableImpl() { if (classDefinition.needsEventDispatcher(classScope.getProject())) { // Generate a EventDispatcher member, equivalent to: // private var _bindingEventDispatcher : flash.events.EventDispatcher; // // Note that it is in a separate private namespace, so it won't conflict with user defined // private members // Add init code for the _bindingEventDispatcher to the ctor // this is the equivalent of: // _bindingEventDispatcher = new flash.events.EventDispatcher(this); iinitInsns.addAll(BindableHelper.generateBindingEventDispatcherInit(itraits, false)); BindableHelper.generateAddEventListener(classScope); BindableHelper.generateDispatchEvent(classScope); BindableHelper.generateHasEventListener(classScope); BindableHelper.generateRemoveEventListener(classScope); BindableHelper.generateWillTrigger(classScope); } if (classDefinition.needsStaticEventDispatcher(classScope.getProject())) { cinitInsns.addAll(BindableHelper.generateBindingEventDispatcherInit(ctraits, true)); BindableHelper.generateStaticEventDispatcherGetter(classStaticScope); } }
/** Finish the class' definition. */ void finishClassDefinition() { // the generation of instructions for variable initialization is delayed // until now, so we can add that initialization to the front of // the cinit instruction list. if (!staticVariableInitializers.isEmpty()) { InstructionList exisitingCinitInsns = null; if (!this.cinitInsns.isEmpty()) { exisitingCinitInsns = new InstructionList(); exisitingCinitInsns.addAll(this.cinitInsns); this.cinitInsns = new InstructionList(); } for (VariableNode var : staticVariableInitializers) generateInstructions(var, true); if (exisitingCinitInsns != null) this.cinitInsns.addAll(exisitingCinitInsns); } // add "goto_definition_help" metadata to user defined metadata. ITraitVisitor tv = classScope.getGlobalScope().traitsVisitor.visitClassTrait(TRAIT_Class, className, 0, cinfo); IMetaInfo[] metaTags = getAllMetaTags(classDefinition); // Add "goto definition help" metadata for the constructor. if (this.ctorFunction != null) { FunctionDefinition ctorDef = this.ctorFunction.getDefinition(); MetaTag metaTag = MetaTag.createGotoDefinitionHelp( classDefinition, classDefinition.getContainingFilePath(), Integer.toString(ctorDef.getNameStart()), true); if (metaTag != null) metaTags = MetaTag.addMetaTag(metaTags, metaTag); } this.classScope.processMetadata(tv, metaTags); tv.visitEnd(); // Need to do this before generating the CTOR as the generated code may result in insns that // need to be added to the ctor. generateBindableImpl(); generateRequiredContingentDefinitions(); addAnyEmbeddedAsset(); // Make any vistEnd method calls // that were deferred. // callVisitEnds must be called on the same thread // that started code generation. Since we don't generate // classes in parallel yet, we know that we are on the thread // that started code generation here. classScope.callVisitEnds(); classStaticScope.callVisitEnds(); // Create the class' constructor function. if (this.ctorFunction != null) { MethodInfo mi = classScope .getGenerator() .generateFunction(this.ctorFunction, classScope, this.iinitInsns); if (mi != null) this.iinfo.iInit = mi; } else if (!this.iinitInsns.isEmpty()) { // Synthesize a constructor. this.iinfo.iInit = new MethodInfo(); MethodBodyInfo iinit = new MethodBodyInfo(); iinit.setMethodInfo(this.iinfo.iInit); IMethodVisitor mv = emitter.visitMethod(this.iinfo.iInit); mv.visit(); IMethodBodyVisitor mbv = mv.visitBody(iinit); InstructionList ctor_insns = new InstructionList(); ctor_insns.addInstruction(OP_getlocal0); ctor_insns.addInstruction(OP_pushscope); ctor_insns.addAll(this.iinitInsns); // Call the superclass' constructor after the instance // init instructions; this doesn't seem like an abstractly // correct sequence, but it's what ASC does. ctor_insns.addInstruction(OP_getlocal0); ctor_insns.addInstruction(OP_constructsuper, 0); ctor_insns.addInstruction(OP_returnvoid); mbv.visit(); mbv.visitInstructionList(ctor_insns); mbv.visitEnd(); mv.visitEnd(); } // If the class has static initialization // logic, emit a cinit routine. if (!this.cinitInsns.isEmpty()) { InstructionList cinit_insns = new InstructionList(); cinit_insns.addInstruction(OP_getlocal0); cinit_insns.addInstruction(OP_pushscope); // TODO: Examine other end-of-function processing // and ensure it's completed. this.classStaticScope.finishClassStaticInitializer(this.cinitInsns); cinit_insns.addAll(this.cinitInsns); cinit_insns.addInstruction(OP_returnvoid); this.classStaticScope.methodBodyVisitor.visitInstructionList(cinit_insns); this.classStaticScope.methodBodyVisitor.visitEnd(); this.classStaticScope.methodVisitor.visitEnd(); } else { // Ensure nothing got dropped. assert (this.classStaticScope.methodBodyVisitor == null); } itraits.visitEnd(); ctraits.visitEnd(); cv.visitEnd(); }