The supported language is best thought of as a subset of Java 1.0.2. The following features from Java 5 and earlier are currently NOT supported:
As much as possible, this class uses standard Java keywords prefixed by "_" as method names. This helps to remember what the method name is for creating an if statement (_if of course). All public methods are static, and using static imports for this class is advisable: simple use
import static org.glassfish.dynamic.codegen.spi.Wrapper.*to get easy access to all of the _xxx methods.
A typical use of this class looks something like:
_clear() ; // clean up any state from previous uses
// optional:
_setClassLoader(cl) ; // If you need a specific ClassLoader, set it early
// so that your generated code can be checked against
// those classes that it references.
_package( "YYY" ) ; // set the package to use for the generated code
_import( "AAA.BBB" ) ; // repeat as needed. As in Java, this makes "BBB"
// a synonym for "AAA.BBB". Collisions are not
// permitted.
_class( ... ) ; // _interface is used for interfaces.
_data( ... ) ; // define the class data members (repeat as needed)
_initializer() ; // define a static initializer
_method( ... ) ; // define a method (use _constructor for a constructor)
_arg( ... ) ; // repeat as needed for the method arguments.
_body() ; // begin the method body definition.
// define the contents of the body using any of the available
// statements.
_end() ; // of method
_end() ; // of class
_end() ; // of package
Class<?> newClass = _generate( ... ) ;
Alternatively, the last line could be
GenericClass<T> gc = _generate( T.class, props ) ;
which makes it easy to create an instance of the generated class
by calling:
T instance = gc.create( <constructor args> ) ;
Currently only one class can be defined at a time. There is a grammar defined below that gives more detail. One small note: it is necessary to call _expr( expr ) in order to convert expr into a statement that is incorporated into a body. If this call is omitted, the generated code will NOT contain expr, leading to a difficult to find bug. I will probably fix this eventually, and treat all dangling expressions as errors.
This class provides many short utility methods that operate against a current context that is maintained in a ThreadLocal. This removes the bookkeeping that would otherwise be needed to keep track of various internal factories needed for generating statements and expressions. Note that this class is designed to be statically imported.
The point of view of the API of this class is that calls to create expressions are nested, while calls to create statements are not. That is, constructing an expression will often lead to nested method calls, but constructing a statement is done with a sequence of method calls. Note that everything could be done as a single nested method call per class, but this is unnatural and hard to debug in Java (Java is not Lisp, but you could make it look sort of like Lisp if you tried hard enough).
All of the expression methods can be called any place where an expression is valid, which basically means anywhere a statement can be defined. The other methods can only be called if the sequence of method calls is contained in the language defined by the following grammar:
START : _package IMPORTS CLASS _end ; IMPORTS : _import IMPORTS | empty ; CLASS : _class CDECLS _end ; CDECLS : CDECL CDECLS | empty ; CDECL : _data | _initializer STMTS _end | METHOD | CONSTRUCTOR ; METHOD : _method ARGS _body STMTS _end ; CONSTRUCTOR : _constructor ARGS _body STMTS _end ; ARGS : _arg ARGS | empty ; STMTS : STMT STMTS | empty ; STMT : IF | TRY | SWITCH | WHILE | SIMPLE ; IF : _if STMTS _end | _if STMTS _else STMTS _end ; TRY : _try STMTS CATCHES _end | _try STMTS _finally STMTS _end | _try STMTS CATCHES _finally STMTS _end ; CATCHES : _catch STMTS CATCHES | empty ; SWITCH : _switch CASES | _switch CASES _default STMTS _end ; CASES : _case STMTS CASES | empty ; XXX modify this to support multiple case labels per statement list WHILE : _while STMTS _end ; SIMPLE : _assign | _define | _return | _throw | _expr ;
Any method that requires an expression can use any expression so long as all variables references in the expression are still in scope. This means that:
The _classGenerator() method is used here to get the ClassGeneratorImpl, which can then be used in the CodeGenerator API to create source code or byte code directly. Also note that Util.display can be used to dump the contents of the ClassGeneratorImpl for debugging purposes.
For convenience, methods are provided to display the AST _displayAST,
generate source code _sourceCode, and generate byteCode
_byteCode.
| Modifier and Type | Class and Description |
|---|---|
| private static class | |
| private static class | |
| private abstract static class | |
| private static class | |
| private static class | |
| private static class | |
| private static enum | |
| private static class | |
| private static class | |
| private static class | |
| private static class |
| Modifier and Type | Field and Description |
|---|---|
| public static final String | CLASS_GENERATION_DIRECTORY
Set this to enable dumping the generated byte codes to a class file in the given directory. |
| private static final String | |
| private static final String | |
| public static final String | DUMP_AFTER_SETUP_VISITOR
Debugging option used to dump the contents of the AST after the setup visitor runs. |
| public static final String | DUMP_CONSTANT_POOL
Causes contents of constant pool to be dumped. |
| private static final StateEngine | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| private static final State | |
| public static final String | SOURCE_GENERATION_DIRECTORY
Option used to enable generation of source files while generating bytecode. |
| private static ThreadLocal | |
| public static final String | TRACE_BYTE_CODE_GENERATION
Debugging option used to trace the byte code generation. |
| public static final String | USE_ASM_VERIFIER
Debugging option used to enable the ASM verifier, which can be helpful for debugging errors in the code generation. |
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| public static Expression | |
| public static void | |
| private static Expression | |
| public static void | |
| public static Type | |
| pack-priv static Type | |
| public static byte[] | |
| public static byte[] | _byteCode(ClassGenerator cgen, ClassLoader cl, Properties options)
Generate byte codes for the ClassGenerator. |
| public static Expression | _call(Expression target, String ident, Signature signature, Expression... args)
Generate a call to an instance method. |
| public static Expression | _call(Expression target, String ident, Signature signature, List<Expression> args)
Generate a call to an instance method. |
| public static Expression | _call(Expression target, String ident, Expression... args)
Generate a call to an instance method, using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _call(Expression target, String ident, List<Expression> args)
Generate a call to an instance method, using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _call(Type target, String ident, Signature signature, Expression... args)
Generate a call to a static method. |
| public static Expression | |
| public static Expression | _call(Type target, String ident, Expression... args)
Generate a call to a static method, using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _call(Type target, String ident, List<Expression> args)
Generate a call to a static method, using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | |
| public static Expression | |
| pack-priv static Type | |
| public static Type | |
| public static void | |
| public static void | |
| public static ClassGenerator | |
| public static void | _clear()
Discard the current Class generated by Wrapper calls, so that another Class may be generated. |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static Expression | |
| public static void | |
| public static void | _constructor(int modifiers, List<Type> exceptions)
Begin defining a constructor in the current class. |
| public static Expression | |
| public static Expression | _define(Type type, String name, Expression expr)
Indicates the introduction of a new local variable initialized to the given expression. |
| public static void | _displayAST(ClassGenerator cg, PrintStream ps)
Dump the contents of the AST for the current Class defined by Wrapper calls. |
| pack-priv static Type | |
| public static void | |
| public static void | _end()
Terminates the definition of the current statement, method, constructor, initializer, class, or package. |
| public static void | |
| public static Expression | _field(Expression expr, String fieldName)
Return an expression used to access a field in an object given by expr. |
| public static Expression | |
| public static void | |
| pack-priv static Type | |
| public static Class | _generate(Class<?>
an existing class used as a reference for the new one. anchorClass, Properties options to control some aspects of the code generation, such as debugging. props, PrintStream a stream to which debug messages should be written, if any ps)Generate a class for the current ClassGenerator, in the same classloader and package as a specified "anchor" class to which the caller has access. |
| public static Class | _generate(Class<?>
an existing class used as a reference for the new one. anchorClass, Properties options to control some aspects of the code generation, such as debugging. props)Generate a class for the current ClassGenerator, in the same classloader and package as a specified "anchor" class to which the caller has access. |
| private static Class | _generate(ClassGenerator cg, Class<?> anchorClass, Properties props, PrintStream ps)
Generate a class for the current ClassGenerator. |
| public static void | _if(Expression expr)
Indicate the start of an if statement with the given expression as the condition. |
| public static Type | |
| public static ImportList | |
| public static void | |
| public static Expression | _index(Expression expr, Expression index)
Return an expression used to access an element in an array given by expr. |
| public static Type | |
| public static void | |
| public static void | |
| pack-priv static Type | |
| public static void | |
| public static void | |
| public static Expression | _ne(Expression left, Expression right)
Create an expression representing the application of the != operator to the left and right expressions in the form (left op right). |
| public static Expression | _new(Type type, Signature signature, Expression... args)
Create an expression representing the construction of a new instance of the given type using the constructor with the given signature and the list of expressions as arguments. |
| public static Expression | _new(Type type, Signature signature, List<Expression> args)
Create an expression representing the construction of a new instance of the given type using the constructor with the given signature and the list of expressions as arguments. |
| public static Expression | _new(Type type, Expression... args)
Create an expression representing the construction of a new instance of the given type using the constructor with the signature determined by the Java method overload resolution algorithm and the list of expressions as arguments. |
| public static Expression | _new(Type type, List<Expression> args)
Create an expression representing the construction of a new instance of the given type using the constructor with the signature determined by the Java method overload resolution algorithm and the list of expressions as arguments. |
| public static Expression | _new_array_init(Type type, Expression... args)
Create an expression representing the construction of a new array with the given component type using the given expressions to initialize the array. |
| public static Expression | _new_array_init(Type type, List<Expression> args)
Create an expression representing the construction of a new array with the given component type using the given expressions to initialize the array. |
| public static Expression | |
| public static Type | |
| public static void | |
| public static void | |
| public static void | |
| public static void | _return(Expression expr)
Indicates the end of execution in a method with a return of the value of the expression. |
| public static Signature | |
| public static Signature | |
| public static void | _setClassLoader(ClassLoader cl)
Set the ClassLoader for this thread that will be used for validating references to pre-existing classes from generated code. |
| pack-priv static Type | |
| public static void | _sourceCode(PrintStream ps, Properties options)
Generate the Java source code for the current Class defined by Wrapper calls. |
| public static void | _sourceCode(ClassGenerator cg, PrintStream ps, Properties options)
Generate the Java source code for the ClassGenerator. |
| public static void | |
| public static void | _sourceCode(ClassGenerator cg, Properties options)
Generate source code into a specified output directory. |
| public static Type | |
| public static Expression | _super(String ident, Signature signature, Expression... exprs)
Generate a call to an instance method in the current super class. |
| public static Expression | _super(String ident, Signature signature, List<Expression> exprs)
Generate a call to an instance method in the current super class. |
| public static Expression | _super(String ident, Expression... exprs)
Generate a call to an instance method in the current super class using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _super(String ident, List<Expression> exprs)
Generate a call to an instance method in the current super class using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _super(Signature signature, Expression... exprs)
Invoke a superclass constructor as the first statement in a constructor for a class. |
| public static Expression | _super(Signature signature, List<Expression> exprs)
Invoke a superclass constructor as the first statement in a constructor for a class. |
| public static Expression | _super(List<Expression> exprs)
Invoke a superclass constructor as the first statement in a constructor for a class using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _super(Expression... exprs)
Invoke a superclass constructor as the first statement in a constructor for a class using the Java method overload resolution algorithm to determine the signature. |
| public static Type | |
| public static Expression | _this(Signature signature, Expression... exprs)
Invoke another constructor as the first statement in a constructor for a class. |
| public static Expression | _this(Signature signature, List<Expression> exprs)
Invoke another constructor as the first statement in a constructor for a class. |
| public static Expression | _this(Expression... exprs)
Invoke another constructor as the first statement in a constructor for a class using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | _this(List<Expression> exprs)
Invoke another constructor as the first statement in a constructor for a class using the Java method overload resolution algorithm to determine the signature. |
| public static Expression | |
| public static Type | |
| public static void | |
| public static void | |
| public static Expression | |
| public static Type | |
| private static void | |
| private static Wrapper. | |
| public static Pair | splitClassName(String name)
Split the class name into a pair of the package name and the unqualified class name. |