Home > Uncategorized > as3parser-framework :: AST creation now possible (as3 code creation)

as3parser-framework :: AST creation now possible (as3 code creation)

Hi,

Well I have been hard at work getting this framework going to the point where I could show an example of AST creation; AKA ActionScript3 code creation in an ActionScript3 class/application. :)

I designed this framework to be used with applications that enhance the development of ActionScript. Mainly targeting AIR applications but, since I have made sure to put zero dependencies on AIR libraries in the core framework, browser application can also make use of the parser AST.

Since last week I have divided this project into 2 repositories;

as3parser-framework

This framework is the core parsers and AST goodies. Any as3 SWF (Flash, Flex, etc.) application can utilize this library.

as3builder-framework

This framework is dependent on AIR libraries for now. I might shave the builder classes back into the parser library sooner than later so there is no requirement on AIR when wanting to create what is displayed below.

So, if you want to create code you need to checkout both repositories and put them in your source paths.

This library also houses to as3book package that contains the processor and accessor for an as3 book. This is the API where after a full project parse you can find subclasses, superclasses, inherting members, superinterfaces etc.

AST Code creation

NOTE: This is very alpha, so all creation implementation is not set, but I am well on the way of getting major parts done soon.

With the following code, it is possible to create the following source code;

// where the project will be output
var output:File = File.desktopDirectory.resolvePath("project/src");
 
// create a factory that will create AST
var factory:AS3Factory = new AS3Factory();
// create a new project to hold .as files
var project:IAS3Project = factory.newASProject(output.nativePath);
 
// create a public class with package 'com.acme.core'
var file:ISourceFile = project.newClass("com.acme.core.HelloWorld");
var typeNode:IClassTypeNode = file.compilationNode.typeNode as IClassTypeNode;
// mark he class final (can do the same for IsDynamic)
typeNode.isFinal = true;
//add metadata to the class
var event:IMetaDataNode = typeNode.newMetaData("Event");
event.addNamedStringParameter("name", "myEvent");
event.addNamedStringParameter("type", "flash.events.Event");
 
var style:IMetaDataNode = typeNode.newMetaData("Style");
style.addNamedStringParameter("name", "myStyle");
style.addNamedStringParameter("type", "Number");
style.addNamedStringParameter("inherit", "no");
 
var bindable:IMetaDataNode = typeNode.newMetaData("Bindable");
 
// add class comment
typeNode.description = "A class comment.\n " +
	"<p>Long description documentation.</p>";
 
typeNode.addDocTag("author", "Michael Schmalle");
typeNode.addDocTag("copyright", "Teoti Graphix, LLC");
typeNode.addDocTag("productversion", "1.0");
typeNode.addDocTag("see", "MyOtherClass More details here.");
 
// add a method
var method:IMethodNode = typeNode.newMethod(
	"helloTest", Modifier.PUBLIC, IdentifierNode.createType("String"));
// add a parameter
var param:IParameterNode = method.addParameter(
	"arg0", IdentifierNode.createType("String"), "''");
// add a comment to the method
method.description = "A hello test method.\n <p>Long description.</p>";
method.addDocTag("since", "1.0");
// add a description to the parameter
param.description = "The String argument at 0";
// add a return tag to the method
method.addReturnDescription("A String indicating the result.");
 
// add a method with rest
// add a method
var methodRest:IMethodNode = typeNode.newMethod(
	"helloRestTest", Modifier.create("mx_internal"), 
	IdentifierNode.createType("my.domain.ITest"));
 
// add a parameter
var arg0:IParameterNode = methodRest.addParameter(
	"arg0", IdentifierNode.createType("int"));
var rest:IParameterNode = methodRest.addRestParameter("theRest");
 
var result:String = BuilderFactory.instance.buildFile(file);
 
trace(result);

converts to;

package com.acme.core {
    [Event(name="myEvent",type="flash.events.Event")]
    [Style(name="myStyle",type="Number",inherit="no")]
    [Bindable]
    /**
     * A class comment.
     * 
     * <p>Long description documentation.</p> 
     * 
     * @author Michael Schmalle
     * @copyright Teoti Graphix, LLC
     * @productversion 1.0
     * @see MyOtherClass More details here.
     */
    public final class HelloWorld {
        /**
         * A hello test method.
         * 
         * <p>Long description.</p> 
         * 
         * @since 1.0
         * @param arg0 The String argument at 0
         * @return A String indicating the result.
         */
        public function helloTest(arg0:String = ''):String {
        }
        mx_internal function helloRestTest(arg0:int, ...theRest):ITest {
        }
    }
}

That’s all for now,
Mike

Please feel free to contact me if you are at all interested in this project or contributing!

mschmalle at teotigraphix.com

Categories: Uncategorized Tags:
  1. August 10th, 2010 at 09:40 | #1

    Absolutely amazing stuff Mike!
    Using your library in combination with as3commons-bytecode (http://code.google.com/p/as3-commons/source/browse/#svn/trunk/as3-commons-bytecode/src/main/actionscript/org/as3commons/bytecode) and as3swf (http://github.com/claus/as3swf) could actually yield an actionscript3 based compiler :)

  2. August 10th, 2010 at 12:22 | #2

    Mike, this is really cool! Danny and I (Aerial Project) are going to start figuring out ways we can begin implementing this to clean up some of the code gen we’re doing. Looking forward to the next releases!

  3. August 27th, 2010 at 16:55 | #3

    Did you happen to use metass as a reference, its a java library that seems to have the same api
    http://www.badgers-in-foil.co.uk/projects/metaas/, IN anycase, great work

  4. August 27th, 2010 at 17:18 | #4

    Hi,

    Yes, David’s metaas was a major inspiration for this. I give him due credit on the wiki and more whenever someone asks me about the API. I am actually in the process of porting the linked list implementation which allows for tremendous control of the AST after processing and when creating the AST.

    Metaas uses antlr, so his implementation was geared towards antlrs impl of the node tree. Since this parser I used came from PMD there was a lot of merging. The new iteration of the parser brings my vision to both sides (dom and parser). Don’t get me wrong, I have a very clear understanding of how this all works and the parsers and scanners I can definitely tweak in the future.

    Another thing to note is metaas DOM is very efficient, I am making some drastic changes on the internals to use his lazy loading of AST DOM decorators, I love that part.

    Mike

    Mike

  5. August 27th, 2010 at 17:33 | #5

    Great work none the less, maybe down the line GreenThread support may be implemented, I’m aware that this may make the project more complex then needed but its a thought to cut-down on the screen lockups and to provide some progress ( to fulfill some use cases). Adobe should really adding threading alteast a separation from data processing and ui displaying.

    Will be watching this project for sure.

*