asblocks & asbuilder update :: as3 code creation impl complete
September 16th, 2010
3 comments
Hi,
Just thought I would pass along the example below to show where this project is at. I have worked really hard the last week to implement most of the actionscript 3 code creation.
I have also refactored the asdoc parser to use a linked list. This allows complete control over the ast after it is created and during creation with ast utilities.
I’m working on a little turnkey project that will show devs how to implement the libraries. The below code is included in this project;
GIT Repos
Code:
private var factory:ASFactory; protected function createProject():void { factory = new ASBuilderFactory(); var project:IASProject = factory.newEmptyASProject( File.desktopDirectory.resolvePath("test_src").nativePath); var classA:ICompilationUnit = project.newClass("my.domain.ClassA"); var interfaceA:ICompilationUnit = project.newInterface("my.domain.IInterfaceA"); var doc:IDocComment; var tag0:IDocTag; var tag1:IDocTag; var ctype:IClassType = IClassType(classA.typeNode); ctype.superClass = "ClassB"; ctype.addImplementedInterface("IInterfaceA"); ctype.addImplementedInterface("IInterfaceB"); ctype.description = "A class documentation comment\nwith multiple lines."; doc = ctype.documentation; tag0 = doc.newDocTag("see", "my.other.Class"); tag1 = doc.newDocTag("author", "Mike Schmalle <mschmalle@teotigraphix.com>"); // add metadata var event:IMetaData = ctype.newMetaData("Event"); event.description = "A class documentation comment\nwith multiple lines."; tag0 = event.documentation.newDocTag("see", "ClassB#event:myOtherEvent"); event.addNamedStringParameter("name", "myEvent"); event.addNamedStringParameter("type", "flash.events.Event"); var defaultProperty:IMetaData = ctype.newMetaData("DefaultProperty"); defaultProperty.addNamedStringParameter("defaultValue", "dataProvider"); ctype.newMetaData("Bindable"); createField(ctype); createStaticField(ctype); createStaticConstant(ctype); createMethod(ctype); createFinalMethod(ctype); createStaticMethod(ctype); createGetMethod(ctype); createSetMethod(ctype); createComplexMethod(ctype); walkUnit(classA); project.writeAll(); } protected function walkUnit(unit:ICompilationUnit):void { var visitor:IASVisitor = new TestVisitor(); var walker:IASWalker = new ASWalker(visitor); walker.walkCompilationUnit(unit); } protected function createField(type:IClassType):void { var f:IField = type.newField("field", Visibility.PUBLIC, "int"); f.description = "An integer field."; var tag0:IDocTag = f.documentation.newDocTag("productversion", "1.0"); } protected function createStaticField(type:IClassType):void { var f:IField = type.newField("STATIC_FIELD", Visibility.PUBLIC, "int"); f.isStatic = true; f.initializer = exp("42"); } protected function createStaticConstant(type:IClassType):void { var f:IField = type.newField("CONSTANT_FIELD", Visibility.PROTECTED, "int"); // change field to static f.isStatic = true; // change field to a constant f.isConstant = true; // set the initializer f.initializer = exp("42"); } protected function createMethod(type:IClassType):void { var m:IMethod = type.newMethod("method", Visibility.PUBLIC, "void"); // add parameters m.addParameter("arg0", "int"); m.addParameter("arg1", "int", "42"); m.addRestParam("rest"); // change type m.type = "String"; m.addComment("TODO implement method"); // add a return m.newReturn(factory.newExpression("null")); } protected function createFinalMethod(type:IClassType):void { var m:IMethod = type.newMethod("methodFinal", Visibility.PUBLIC, "void"); } protected function createStaticMethod(type:IClassType):void { var m:IMethod = type.newMethod("methodStatic", Visibility.PUBLIC, "void"); m.isStatic = true; } protected function createGetMethod(type:IClassType):void { var m:IMethod = type.newMethod("property", Visibility.PUBLIC, "int"); m.accessorRole = AccessorRole.GETTER; m.newReturn(factory.newNumberLiteral(-1)); } protected function createSetMethod(type:IClassType):void { var m:IMethod = type.newMethod("property", Visibility.PUBLIC, "void"); m.addParameter("value", "int"); m.accessorRole = AccessorRole.SETTER; } protected function createComplexMethod(type:IClassType):void { var m:IMethod = type.newMethod("complex", Visibility.PRIVATE, "void"); // add an if() statement var ifstmt:IIfStatement = m.newIf(exp("i < len && hasNext()")); // add a var declaration var dc:IDeclarationStatement = ifstmt.parseNewDeclaration("len:int = 2"); // make it a constant dc.isConstant = true; // add a for() statement var forstmt:IForStatement = ifstmt.parseNewFor("var i:int = 0", "i < len", "i++"); // add a switch() statement var swstmt:ISwitchStatement = forstmt.newSwitch(exp("name")); // add a case to the switch var cs1:ISwitchCase = swstmt.newCase("\"one\""); cs1.newBreak(); // add a case to the switch var cs2:ISwitchCase = swstmt.newCase("\"two\""); var ifstmt2:IIfStatement = cs2.newIf(exp("i == 2")); // add a single lin comment ifstmt2.addComment("Trace the result"); ifstmt2.addStatement("trace('Hello Two')"); cs2.newBreak(); // add a default to the switch var dfstmt:ISwitchDefault = swstmt.newDefault(); dfstmt.newThrow(exp("new Error('Error here')")); } private function exp(expression:String):IExpression { return factory.newExpression(expression); }
Output:
package my.domain { /** * A class documentation comment * with multiple lines. * @see ClassB#event:myOtherEvent */ [Event(name="myEvent",type="flash.events.Event")] [DefaultProperty(defaultValue="dataProvider")] [Bindable] /** * A class documentation comment * with multiple lines. * @see my.other.Class * @author Mike Schmalle <mschmalle@teotigraphix.com> */ public class ClassA extends ClassB implements IInterfaceA, IInterfaceB { /** * An integer field. * @productversion 1.0 */ public var field:int; public static var STATIC_FIELD:int = 42; protected static const CONSTANT_FIELD:int = 42; public function method(arg0:int, arg1:int = 42):String { //TODO implement method return null; } public function methodFinal():void { } public static function methodStatic():void { } public get function property():int { return -1; } public set function property(value:int):void { } private function complex():void { if (i < len && hasNext()) { const len:int = 2; for (var i:int = 0; i < len; i++) { switch (name) { case "one": break; case "two": if (i == 2) { //Trace the result trace('Hello Two'); } break; default: throw new Error('Error here'); } } } } } }
Mike
Recent Comments