Return-Path: X-Original-To: apmail-incubator-flex-dev-archive@minotaur.apache.org Delivered-To: apmail-incubator-flex-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ACF9DEB00 for ; Thu, 29 Nov 2012 18:16:07 +0000 (UTC) Received: (qmail 67513 invoked by uid 500); 29 Nov 2012 18:16:06 -0000 Delivered-To: apmail-incubator-flex-dev-archive@incubator.apache.org Received: (qmail 67447 invoked by uid 500); 29 Nov 2012 18:16:06 -0000 Mailing-List: contact flex-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: flex-dev@incubator.apache.org Delivered-To: mailing list flex-dev@incubator.apache.org Received: (qmail 67438 invoked by uid 99); 29 Nov 2012 18:16:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Nov 2012 18:16:06 +0000 X-ASF-Spam-Status: No, hits=-1.3 required=5.0 tests=FRT_ADOBE2,RCVD_IN_DNSWL_MED,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of aharui@adobe.com designates 64.18.1.39 as permitted sender) Received: from [64.18.1.39] (HELO exprod6og117.obsmtp.com) (64.18.1.39) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Nov 2012 18:16:00 +0000 Received: from outbound-smtp-2.corp.adobe.com ([193.104.215.16]) by exprod6ob117.postini.com ([64.18.5.12]) with SMTP ID DSNKULemSl6AmbSh7HZHZC2EFshP3Gsq90nN@postini.com; Thu, 29 Nov 2012 10:15:39 PST Received: from inner-relay-4.eur.adobe.com (inner-relay-4b [10.128.4.237]) by outbound-smtp-2.corp.adobe.com (8.12.10/8.12.10) with ESMTP id qATIFbHP020021 for ; Thu, 29 Nov 2012 10:15:37 -0800 (PST) Received: from nacas03.corp.adobe.com (nacas03.corp.adobe.com [10.8.189.121]) by inner-relay-4.eur.adobe.com (8.12.10/8.12.9) with ESMTP id qATIFPXO010152 for ; Thu, 29 Nov 2012 10:15:37 -0800 (PST) Received: from NAMBX02.corp.adobe.com ([10.8.127.96]) by nacas03.corp.adobe.com ([10.8.189.121]) with mapi; Thu, 29 Nov 2012 10:15:27 -0800 From: Alex Harui To: "flex-dev@incubator.apache.org" Date: Thu, 29 Nov 2012 10:15:22 -0800 Subject: Re: [FlaconJS] pseudo emitter algorithm Thread-Topic: [FlaconJS] pseudo emitter algorithm Thread-Index: Ac3OW7ogrGMmFDZPTi6iri+yeF16HwAAcTFa Message-ID: In-Reply-To: <20121129130212.32361hztrzm60dno@teotigraphix.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Microsoft-Entourage/13.13.0.120411 acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Virus-Checked: Checked by ClamAV on apache.org OK, I think I get it now. Sounds like it is worth exploring. On 11/29/12 10:02 AM, "Michael Schmalle" wrote: > Quoting Alex Harui : >=20 >> So if I understand you, the notion of traits is a SWF thing? The AST ha= s >> different representations maybe like member, variable, function? >=20 > Well yes and no. >=20 > Traits IS an SWF thing. The AST is represented by like IClassNode, > IPackageNode etc. >=20 > Than we have an even more fun framework in the IDefinition like > IClassDefinition which basically wraps the INode ast. >=20 > We also have the IScopeNode which then blocks our code into the scope chu= nks. >=20 > If we eliminate the SWF traits stuff and use IASNode or IDefinition > API we would be solid and developers could easily get involved down > the road. >=20 > PS i know there might be things I am over looking but Jangroo uses > this method, we just have to have some analyzers and such I would > imagine. >=20 > Theoretically using the IDefinition interfaces I could create that > same MainCode.js output, which I am going to try and to. >=20 > The IDefinition API is were you get your supers, resolving classes, > getting super class members etc. >=20 > Mike >=20 >=20 >=20 >>=20 >> On 11/29/12 9:42 AM, "Michael Schmalle" wrote: >>=20 >>> Quoting Alex Harui : >>>=20 >>>> Very nice. Have you figured out the role of the generated CMCEmitter = in >>>> this process? >>>=20 >>> Yes, >>>=20 >>> The CmcJSEmitter (autogenerated by cmc-js.jbg) is used to traverse the >>> ISWF that is created. >>>=20 >>> The CmcJSEmitter and JSGeneratingReducer are created in the >>> JSGenerator constructor. >>>=20 >>> The actual CmcJSEmitter is used during the >>> JSClassDirectiveProcessor.delcareVariable() etc. methods. >>>=20 >>> Basically the processor is using the emitter to create SWF >>> instructions that ultimately end up creating class traits. Once the >>> tratis are created, they just keep getting recursively visited and >>> more instructions created. >>>=20 >>> So it's like >>>=20 >>> - JSCompilationUnit.processABCBytesRequest() >>> - handleABCBytesRequest() >>> - JSGenerator.generate() >>> - then see below .... >>>=20 >>> When it gets to methods called declarePackage() for instance, block >>> code instructions are created using the cmc emitter. Traits are then >>> created based of them. >>>=20 >>> For FalconJS this process is totally bound to SWF format. >>>=20 >>> This was my point. For any developer to fix bugs here they have to >>> know the SWF format. Which I don't. >>>=20 >>> This is why I propsed another solution using pure AST like Jangaroo doe= s. >>>=20 >>> I am not skilled enough to understand the trade offs currently. But I >>> am going to try and see if I can create the same JS code using a >>> different algorithm. >>>=20 >>> Mike >>>=20 >>>=20 >>>=20 >>>>=20 >>>> On 11/29/12 7:30 AM, "Michael Schmalle" wrot= e: >>>>=20 >>>>> Hi, >>>>>=20 >>>>> For those asking question about "where to alter" code, it's not prett= y >>>>> but I think I know exactly what is going on now. >>>>>=20 >>>>> If you can understand below, you will now have some insight to where >>>>> and how the JS code actually gets created. >>>>>=20 >>>>>=20 >>>>> ! Call the compiler load config compile(). >>>>>=20 >>>>>=20 >>>>> JSGenerator.generate() - creates the package, class, member traits >>>>>=20 >>>>> - DirectiveProcessor.processNode(IFileNode) >>>>> - recusrsivly fill traits >>>>>=20 >>>>> ----------------------------------------------------- >>>>>=20 >>>>> Basically a snippet of the recursion; >>>>>=20 >>>>> DirectiveProcessor.processNode(IFileNode) >>>>> - declarePackage(PackageNode) >>>>> - emitter.visitPackage(packageName) >>>>> - data.registerPackage(packageName) >>>>> - super.declarePackage(PackageNode) >>>>> - DirectiveProcessor.traverse(p.getScopedNode()) <- >>>>> ClassNode (class >>>>> {}) >>>>> - for each ClassNode.getChild(i) >>>>> - processNode(ScopedBlockNode) >>>>> - JSGlobalDirectiveProcessor.declareClass(ClassNode) >>>>> - verifyClassModifiers(ClassNode) >>>>> - skins >>>>> - JSClassDirectiveProcessor cp =3D >>>>> backend.createClassDirectiveProcessor() >>>>> - cp.traverse(ClassNode.getScopedNode()) <- TypeScope >>>>> - for each TypeScope.getChild(i) >>>>> - processNode(TypeScope) >>>>> - >>>>> JSGlobalDirectiveProcessor.declareFunction(FunctionNode) >>>>>=20 >>>>>=20 >>>>> -------------------------------------------------------- >>>>>=20 >>>>> !!!! >>>>> JavaScript source code creation after class traits have been traverse= d >>>>> and created; >>>>>=20 >>>>>=20 >>>>> JSEmiter.emit() >>>>> - emitClass(EmitterClassVisitor) >>>>> - IClassDefinition =3D getDefinition(ii.name) >>>>> - write class JSDoc >>>>>=20 >>>>>=20 >>>>>=20 >>>>> - JSEmitter.emitClass() >>>>> - Line: 3267 - 3269 is What creates a class >>>>> - "MainCode=3Dadobe.extend("MainCode",Object,{ ... });" >>>>>=20 >>>>>=20 >>>>>=20 >>>>> - JSEmitter.emitInstanceTraits() is then called to write out the >>>>> class traits >>>>> - emitTraits() is then called to do the specific if the closure >>>>> compiler flag is not set >>>>> 1. emitCtor() emit constructor >>>>> - emit comma >>>>> 2. emit all variables before methods >>>>> - assembles the code "MainCode.foo" >>>>> - warns if there is a private namespace collision >>>>> - >>>>> 3. emit all methods other than constructor >>>>> - emit ",\n" >>>>> - emitMethod() >>>>> - emitJSDocForMethod() >>>>> - write("\tget_baz") >>>>> - write(" : ") <- assignmentOp >>>>> - write("function(") >>>>> - emitParameters(methodInfo) >>>>> - write("baz") >>>>> - write(")") >>>>> - if (returnType !=3D null) >>>>> - write(JSDoc for return type) >>>>> - if interface method >>>>> - write(" {};\n") >>>>> - else >>>>> - write("\n") >>>>> - write(" {") >>>>> - write("\n") >>>>> - emitMethodBody() >>>>> ... you get the drift >>>>> - write(" }") >>>>>=20 >>>>> - After all traits are written, control flow goes back to >>>>> JSEmitter.emitClass() line 3269 >>>>> - write("\n});\n\n") // end class >>>>> - add _CLASS member to instance >>>>> - add JSDoc for prototype._CLASS >>>>> - write("MainCode.prototype._CLASS =3D MainCode;\n") >>>>>=20 >>>>> It will then go onto >>>>> - emitClassInfo() >>>>> - emitNamespaceInfo() >>>>> - emitJSONInfo() >>>>>=20 >>>>> if (JSSharedData.JS_FRAMEWORK_NAME) >>>>> - emitFrameworkInit(); >>>>>=20 >>>>> It will then finally emit register class >>>>> - "adobe.classes.MainCode=3DMainCode;" >>>>>=20 >>>>> --------------- >>>>> MainCode._PACKAGE=3Dadobe.globals;MainCode._NAME=3D"MainCode"; >>>>> MainCode._FULLNAME=3D"MainCode"; >>>>> MainCode._SUPER=3DObject; >>>>> MainCode._NAMESPACES=3D{"foo::2":!0,"bar::7:MainCode":!0,"baz::2":!0,= "baz::2 >>>>> ": >>>>> !0 >>>>> }; >>>>> adobe.classes.MainCode=3DMainCode; >>>>> --------------- >>>>>=20 >>>>> Mike >>>>>=20 >>>>>=20 >>>>>=20 >>>>>=20 >>>>=20 >>>> -- >>>> Alex Harui >>>> Flex SDK Team >>>> Adobe Systems, Inc. >>>> http://blogs.adobe.com/aharui >>>>=20 >>>>=20 >>=20 >> -- >> Alex Harui >> Flex SDK Team >> Adobe Systems, Inc. >> http://blogs.adobe.com/aharui >>=20 >>=20 --=20 Alex Harui Flex SDK Team Adobe Systems, Inc. http://blogs.adobe.com/aharui