metaas provides Java applications with a 'Document Object Model' for ActionScript 3 code. Its primary function is generating code, but it allows existing .as source files to be loaded, and simple modifications to be made.
Here is a minimal example that generates a simple file in the current directory:
ActionScriptFactory fact = new ActionScriptFactory(); ActionScriptProject proj = fact.newEmptyASProject("."); ASCompilationUnit unit = proj.newClass("Test"); ASClassType clazz = (ASClassType)unit.getType(); ASMethod meth = clazz.newMethod("test", Visibility.PUBLIC, "void"); meth.addStmt("trace('Hello world')"); proj.writeAll();
The expression proj.newClass("Test")
generates the
following ActionScript code,
package { public class Test { } }
Then, the expression clazz.newMethod("test", Visibility.PUBLIC, "void")
adds a method definition to the body of the class as follows,
public function test():void { }The statement
meth.addStatement("trace('Hello world')")
then
adds a line of ActionScript code to the method body (notice that a ';' was
added),
trace('Hello world');
Finally, proj.writeAll()
cases a file called Test.as to be
written to the current folder, containing the complete code,
package { public class Test { public function test():void { trace('Hello world'); } } }
The addStatement()
method can be passed an ActionScript
statement with or without a final semicolon, and one will be added to the
output if required. Standard metaas usage is to skip the implied semicolon
at the end of statements created with addStatement()
, as this
makes the resulting Java code look nicer.
The standard facility for dealing with imports is via the methods available in {@link uk.co.badgersinfoil.metaas.dom.ASPackage}.
When code is being contributed to a file by disparate parts of your
application, arranging for addImport()
to be called for everthing
required can be fiddly. Therefore, metaas provides an 'auto import' feature
to try and simplify this task.
To make use of auto-imports, ensure that all code is generated with 'fully qualified' references to other types (i.e. include the package-prefix on all references to class names). For instance,
meth.addStatement("com.example.util.Debug.trace('Hello world')");
When you call the method {@link uk.co.badgersinfoil.metaas.ActionScriptProject#performAutoImport()}, all compilation units in the project will be inspected for references like this and where metaas can find a type defined within the project which has a matching name, it will
import com.example.util.Debug;
)Debug.trace('Hello world');
)If you want to handle references to elements outside the project classes
(being generated), you will need to add a reference to this exteral code into
the project's 'classpath'. Classpath elements can be source folders or
.swc
files, and are added to the project using
{@link uk.co.badgersinfoil.metaas.ActionScriptProject#addClasspathEntry(String)}.
For example, to allow the auto-import process to see the definitions of the standard Flash classes, add a reference to the standard library component provided with Flex 2 (using the proper path to the Flex installation on your system):
project.addClasspathEntry("/opt/flex_sdk_2/frameworks/libs/playerglobal.swc")
metaas tries to enforce ActionScript syntax rules. For instance, the following code,
meth.addStmt("trace(i]");
Will raise the a {@link uk.co.badgersinfoil.metaas.SyntaxException}:
uk.co.badgersinfoil.metaas.SyntaxException: Unexpected token RBRACK (expecting RPAREN) in "trace(i]"
To read code from the file 'Test.as' you can use the following snippet of Java:
FileInputStream in = new FileInputStream("Test.as"); InputStreamReader reader = new InputStreamReader(in); ActionScriptFactory fact = new ActionScriptFactory(); ActionScriptParser parser = fact.newParser(); ASCompilationUnit unit = parser.parse(reader);
You can then use the methods of {@link uk.co.badgersinfoil.metaas.dom.ASCompilationUnit} to explore the types, fields and methods the source code defines.
For example, to list all the methods defined by the type in 'Test.as', you could add the following lines to the above example:
ASPackage pkg = unit.getPackage(); ASType type = pkg.getType(); List methods = type.getMethods(); for (Iterator i=methods.iterator(); i.hasNext(); ) { ASMethod meth = (ASMethod)i.next(); System.out.println(meth.getName()); }
metaas supports JavaDoc-style comments preceeding API elements tagged with the {@link uk.co.badgersinfoil.metaas.dom.Documentable} interface. Documentable elements provide the simple description from the comment, and access to other, structured information from 'tagged paragraphs', via a {@link uk.co.badgersinfoil.metaas.dom.DocComment} object.
For instance, to attach a descriptive comment to a class definition, use the following code,
ASCompilationUnit unit = proj.newClass("Test"); ASClassType clazz = (ASClassType)unit.getType(); clazz.setDescription("Really very useful.");
The result is ActionScript code like this,
package { /** * Really very useful. */ public class Test { } }
Several elements also supply their own shortcut methods to access relevent structures in the doc-comment. For instance, ASArg allows manipulation of @param sections in the enclosing method's documentation,
ASMethod meth = clazz.newMethod("test", Visibility.PUBLIC, "void"); ASArg t = meth.addParam("t", "String"); t.setDescription("must not be null");
This will result in ActionScript code like,
/** * @param t must not be null */ public functinon test(t:String):void { }