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.

Getting Started

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');
		}
	}
}

Semicolon Handling

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.

Import Management

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

  1. Add an import statement to the package (in the example, this would be import com.example.util.Debug;)
  2. Contract occurances of the type-name within the code to the unqualified form (in the example, the line would become just Debug.trace('Hello world');)

Importing External Definitions

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")

Syntax Errors

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]"

Code Inspection

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());
}

Documentation Comments

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 {
	}