Top Description Inners Fields Constructors Methods
org.glassfish.pfl.dynamic.codegen.spi

public final Class Wrapper

extends Object
Class Inheritance
Annotations
@SuppressWarnings:unused, WeakerAccess
Imports
java.io.IOException, .PrintStream, java.util.List, .Properties, .Stack, org.glassfish.pfl.basic.contain.Pair, org.glassfish.pfl.basic.fsm.FSM, .FSMImpl, .Input, .Runner, .State, .StateEngine, org.glassfish.pfl.dynamic.codegen.impl.BlockStatement, .ClassGeneratorImpl, .CodeGenerator, .CodeGeneratorUtil, .CurrentClassLoader, .ExpressionFactory, .FieldGenerator, .Identifier, .IfStatement, .ImportListImpl, .MethodGenerator, .SwitchStatement, .TryStatement, .Util, .WhileStatement

Main API for runtime code generation. This API generates bytecode dynamically at runtime, allowing direct construction of Class instances from the generated bytecodes. Such classes can then be instantiated and used in a running program. This can be used for a variety of advanced applications aimed at extending the Java language or providing significant performance enhancements.

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:

The intent is that dynamically generated code should be a simplified form of Java, much like the original Java 1.0 definition. This moves dynamic code generation to a level much closer to Java than to raw bytecode manipulation.

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:

  1. Variables representing data members can be referenced anywhere between the _class _body and _end.
  2. Variables representing method parameters can be referenced anywhere between the _method _body and _end.
  3. Variables representing _define statements can be referenced with in the scope of their block (that is, until the corresponding "}" in java. Here we don't use "{}" to delimit scope in the generated code).
  4. Variables representing _catch statements can be referenced until the next corresponding _catch, _finally, or _end. Any attempt to use an Expression that references a Variable that is out of scope will result in an IllegalStateException.

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.

Nested and Inner Type Summary

Modifier and TypeClass 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

Field Summary

Modifier and TypeField 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<Wrapper.Environment>
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.

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public static Expression
_arg(Type type, String name)

Add an argument to the current method.

public static void
_assign(Expression var, Expression expr)

Indicates an assignment statement of the form var = expr.

private static Expression
public static void
_body()

Indicates the start of the definition of the body of a method.

public static Type
_boolean()

Return a representation of the boolean type.

pack-priv static Type
_byte()

Return a representation of the byte type.

public static byte[]
_byteCode(ClassLoader cl, Properties options)

Generate byte codes for the current ClassGenerator.

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
_call(Type target, String ident, Signature signature, List<Expression> args)

Generate a call to a static method.

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
_cast(Type type, Expression expr)

Create an expression representing the type cast of expr to type.

public static Expression
_catch(Type type, String name)

Indicate the start of a catch clause in a try statement.

pack-priv static Type
_char()

Return a representation of the char type.

public static Type
_Class()

Return a representation of the java.lang.Class type.

public static void
_class(int modifiers, String name, Type superClass, Type... impls)

Define a class.

public static void
_class(int modifiers, String name, Type superClass, List<Type> impls)

Define a class.

public static ClassGenerator
_classGenerator()

Obtain the ClassGeneratorImpl that is constructed by the Wrapper methods.

public static void
_clear()

Discard the current Class generated by Wrapper calls, so that another Class may be generated.

public static Expression
_const(boolean c)

Return a constant expression representing the value c.

public static Expression
_const(char c)

Return a constant expression representing the value c.

public static Expression
_const(byte c)

Return a constant expression representing the value c.

public static Expression
_const(short c)

Return a constant expression representing the value c.

public static Expression
_const(int c)

Return a constant expression representing the value c.

public static Expression
_const(long c)

Return a constant expression representing the value c.

public static Expression
_const(float c)

Return a constant expression representing the value c.

public static Expression
_const(double c)

Return a constant expression representing the value c.

public static Expression
_const(String c)

Return a constant expression representing the value c.

public static Expression
_const(Type c)

Return a constant expression representing the value c.

public static void
_constructor(int modifiers, Type... exceptions)

Begin defining a constructor in the current class.

public static void
_constructor(int modifiers, List<Type> exceptions)

Begin defining a constructor in the current class.

public static Expression
_data(int modifiers, Type type, String name)

Define a data member in a class.

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
_double()

Return a representation of the double type.

public static void
_else()

Indicate the start of the false branch of an if statement.

public static void
_end()

Terminates the definition of the current statement, method, constructor, initializer, class, or package.

public static void
_expr(Expression expr)

Indicate that expr should be executed as a statement for its side effects.

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
_field(Type type, String fieldName)

Return an expression used to access a static data member in a class given by the type.

public static void
_finally()

Indicate the start of a finally clause in a try statement.

pack-priv static Type
_float()

Return a representation of the float 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
_import(String name)

Used to create short names for types.

public static ImportList
_import()

Return an ImportList that can be shared across multiple class generations.

public static void
_import(ImportList ilist)

Set the ImportList for the current class generation.

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
_int()

Return a representation of the int type.

public static void
_interface(int modifiers, String name, Type... impls)

Define an interface.

public static void
_interface(int modifiers, String name, List<Type> impls)

Define an interface.

pack-priv static Type
_long()

Return a representation of the long type.

public static void
_method(int modifiers, Type type, String name, Type... exceptions)

Begin defining a method in the current class.

public static void
_method(int modifiers, Type type, String name, List<Type> exceptions)

Begin defining a method in the current class.

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
_null()

Return the null expression.

public static Type
_Object()

Return a representation of the java.lang.Object type.

public static void
_package(String name)

_package must be called first to set the package name for this class.

public static void
_package()

Same as _package( "" ).

public static void
_return()

Indicates the end of execution in a method.

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
_s(Type rtype, Type... types)

Create a signature that may be used for calling a method or constructor.

public static Signature
_s(Type rtype, List<Type> types)

Create a signature that may be used for calling a method or constructor.

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
_short()

Return a representation of the short 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
_sourceCode(Properties options)

Generate source code into a specified output directory.

public static void
_sourceCode(ClassGenerator cg, Properties options)

Generate source code into a specified output directory.

public static Type
_String()

Return a representation of the java.lang.String 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
_t(String name)

Return the reference type for the given class name.

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
_this()

Return an expression representing "this".

public static Type
_thisClass()

Return the type of the current class.

public static void
_throw(Expression expr)

Indicates a throw statement that throws the given expression.

public static void
_try()

Indicate the start of a try statement.

public static Expression
_v(String name)

Construct the expression that refers to the variable named name.

public static Type
_void()

Return a representation of the void type.

private static void
private static Wrapper.Environment
env()

public static Pair<String, String>
splitClassName(String name)

Split the class name into a pair of the package name and the unqualified class name.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait