Good day to all of you :) Hold on, I think this is going to be a long message...
Moving on from the latest discussion between Erik and Frank about the ideal implementation of AS->JS cross-compilation, I think its perhaps an interesting venture to talk a little bit about some possible changes we could make to Falcon itself. Let me preface this with giving my opinion about both Erik's and Frank's proposed solution. I believe both gentlemen know their business and are passionate about their respective solution. I'm not going to abuse this thread by choosing sides. I also believe the discussion actually shouldn't have to take place. I believe there should be place for both solutions so that potential users of Apache Flex can choose the output that best fits their project. For instance, Frank's solution might be interesting for folks who don't want to go through the process of installing Closure, or who simply don't like Closure (for whatever reason, valid or not). Whereas Erik's implementation might even make sense in a larger project where multiple parties are adding Javascript to a shared codebase, but all of them use different technologies to generate that Javascript. If all of them make sure that the JS they provide is in the form that Closure expects it, all of their output could be part of a larger build system that involves Closure at the end of the line. (Just thinking out loud here) So therefore I believe that both avenues need to be explored and quite probably both avenues ought to find their place in a future release of Apache Flex. Right, using this introduction I'd like to start some sort of discussion about the design of Falcon at the moment. (And what I understand of it at the moment, so Michael, Alex, Gordon, if I start talking out of m y a**, please correct me). Currently there seem to be three compilers: MXMLC, COMPC and ASC. All three (and now a fourth called 'ASJS' I guess) are a kind of monolithic class that creates all of its dependencies internally. So, if we want to compile mxml/as we invoke MXMLC and if we want to compile pure as3 we invoke ASC, etc. Come to think of it, there's even a fifth one, if we count Michael Schmalle's ASDoc compiler implementation. I think it might make more sense to create a single point of entry for all types of compilation. Let's call this point of entry FLEXC (credit: Michael Schmalle). Wouldn't it be cleaner to use this FLEXC compiler as a sort of factory for all the different types of compilers that make up the Falcon framework? FLEXC could use an XML configuration file that describes the various compilers and could create a fully configured instance. (Essentially FLEXC would be a specialised DI container for Falcon compilers). The XML configuration for FLEXC could look like this (very simplified): <falcon default-target="swf" default-frontend="AS3Frontend-Plugin-Identifier"> <target name="swf" backend="SWFBackend-Plugin-Identifier"/> <target name="js" backend="JSBackend-Plugin-Identifier"/> <target name="asdoc" backend="ASDocBackend-Plugin-Identifier"/> </falcon> This way FLEXC could invoked with a *-swf* parameter so that FLEXC knows it has to return an instance of the swf target. All parameters coming *after* the *-swf* param would be ignored by FLEXC and instead passed on to the instance that it created. This way the frontends and/or backends could receive additional configuration: <falcon default-target="swf" default-frontend="AS3Frontend-Plugin-Identifier"> <plugin id="AOP-AST-PostProcessor" uri="PATH_TO_JAR_FILE" type="ast-postprocesser"/> <plugin id="Guice-AST-PostProcessor" uri="PATH_TO_JAR_FILE" type="ast-postprocesser"/> <plugin id="Randori-Emit-PostProcessor" uri="PATH_TO_JAR_FILE" type="emit-postprocesser"/> <frontend id="AS3Frontend-Plugin-Identifier" uri="PATH_TO_JAR_FILE"> <plugin id="AOPASTPostProcessor"/> </frontend> <backend id="SWFBackend-Plugin-Identifier" uri="PATH_TO_JAR_FILE"/> <backend id="JSBackend-Plugin-Identifier" uri="PATH_TO_JAR_FILE"> <plugin id="Randori-Emit-PostProcessor"> </backend> <target name="swf" backend="SWFBackend-Plugin-Identifier"/> <target name="js" backend="JSBackend-Plugin-Identifier"/> <target name="asdoc" backend="ASDocBackend-Plugin-Identifier"/> </falcon> Obviously the configuration doesn't HAVE to be XML, I'm just using it as an example. So, by way of the configurability/modularity of Falcon and the examples above, I come to the notion of extensibility. Currently there is no plugin architecture in place in the Falcon framework (at least, not that I'm aware, please correct me if I'm wrong). Now, IMHO, things would become extremely interesting if we do identify a number of hooks into the compiler process where a potential plugin could add or manipulate functionality. In the best case, I even believe that ALL functionality should basically be viewed as pluggable. As the configuration example shows, in theory it ought to be possible to override the entire frontend and plug your own custom AS3 parser. (Not a lot of folks would choose to do so, but in the spirit of clean design I think it would make sense :)) Coming back to the case of Erik's and Frank's proposal of Javascript emission. If the Falcon backends will be designed (and I believe Michael Schmalle has already done so in his ASJS implementation) then we don't need to fight over which implementation Apache Flex should officially choose. Folks can build both and offer them to the Apache Flex community as a configurable option. I haven't looked very deeply into the ABC backend yet, so I have no clear picture how different Michael Schmalle's backend is from the ABC backend, but ideally there would be some consolidation between the two (if necessary). That way a standardized way of configuring the emitter implementations for a specific backend could be defined. (Because, if I recall correctly, currently Erik's and Frank's solutions are basically different implementations of an emitter, right?) As you can read in my example configuration, I also added this entry: <backend id="JSBackend-Plugin-Identifier" uri="PATH_TO_JAR_FILE"> <plugin id="Randori-Emit-PostProcessor"> </backend> I know that Michael Labriola would need access to the emiited Javascript string to further manipulate it for his Randori system. Therefore this would be an additional hook that we might want to define as an 'official' pluggable entry point. So, emitters should have a plugin hook as well. Essentially giving plugins their own plugins. Hehehe. Looking at the frontend, a hook into the AST generation is definitely desired as well. This with things like AOP and other types of class generation (mocks for instance) in mind. So, this hook would basically have to enable a plugin to manipulate the generated AST by changing and adding to it. Now, especially the AST bit is a bit of a dark area for me, since I don't know yet much about its structure, so any input from Gordon about the feasibility of these ideas would be very welcome :) I have already brainstormed about these ideas with Michale Schmalle and Michael Labrioloa off-list, so these ideas don't come popping out of nowhere, but I thought now would be a good time to start a mailinglist discussion. Especially while looking at Frank's and Erik's work. Both of which deserve merit, IMHO, and therefore I was hoping that the ideas I wrote down here would contribute to both of their causes :) I'd love to hear some opinions, so let the games begin :) cheers, Roland Zwaga Senior Consultant | Stack & Heap BVBA +32 (0)486 16 12 62 | rol...@stackandheap.com | http://www.stackandheap.com http://zwaga.blogspot.com http://www.springactionscript.org http://www.as3commons.org