| java.lang.Object org.quilt.cl.ClassFactory
ClassFactory | public class ClassFactory (Code) | | Class synthesizer. Currently intended for debugging Quilt
development and limited to instantiating classes with a
no-argument constructor and a single method whose bytecode
depends upon the base name of the class.
By default classes whose name begins with test.data.Test
will be synthesized. This can be set to a different string by a
QuiltClassLoader method.
See Also: QuiltClassLoader. author: David Dixon-Peugh author: Jim Dixon -- major author: changes to the original code. |
Method Summary | |
public static ClassFactory | getInstance() Use this method to get to the ClassFactory singleton. | public InputStream | getResourceAsStream(String resName) Get the bytecode for a synthesized class. | public ClassGen | makeClass(String className, String fileName) Generate a class with a single no-arg constructor and a runTest
method. | public MethodGen | makeConstructor(ClassGen clazz) Creates the constructor for the synthesized class. | public MethodGen | makeMethod(ClassGen clazz) Creates a method with bytecode determined by the name of
the class.
If we have class test.data.TestBogus, then we strip off the
"test.data.Test" prefix and call mgBogus() to get an
instruction list.
In the current version, if there is an underscore in the
class name, then the underscore and everything following it
will be ignored. | public MethodGen | mgDefault(ClassGen clazz) Generates bytecode for a method which simply returns 2. | public MethodGen | mgIfThen(ClassGen clazz) Generates instructions for a method consisting of a single
if-then clause. | public MethodGen | mgNPENoCatch(ClassGen clazz) Creates bytecode which will throw a NullPointerException
without a catch block. | public MethodGen | mgNPEWithCatch(ClassGen clazz) Returns bytecode which will throw a NullPointerException,
but it will catch the NPE. | public MethodGen | mgSelect(ClassGen clazz) | public MethodGen | mgWhile(ClassGen clazz) Generates code for a while loop. |
getInstance | public static ClassFactory getInstance()(Code) | | Use this method to get to the ClassFactory singleton.
XXX Is there any benefit to this being a singleton?
|
getResourceAsStream | public InputStream getResourceAsStream(String resName)(Code) | | Get the bytecode for a synthesized class. The name passed
looks like "test/data/TestMyStuff.class". This is
converted to "test.data.TestMyStuff". The "test.data.Test"
prefix will later be stripped off and the base name, "MyStuff"
in this case, used to determine which version of the runTest
method to generate.
Parameters: resName - Name of the class to be synthesized. |
makeClass | public ClassGen makeClass(String className, String fileName)(Code) | | Generate a class with a single no-arg constructor and a runTest
method. By convention, if there is an underscore (_) in the
class name, the underscore and everything after it are
ignored in choosing method code. For example, if the class
name is testWhile_1, then the method code comes from mgWhile
Methods available at this time are:
- mgDefault
- mgIfThen
- mgNPENoCatch
- mgNPEWithCatch
- mgSelect
- mgWhile
Parameters: className - Name of the class to be constructed. Parameters: fileName - Associated file name (??? XXX) |
makeConstructor | public MethodGen makeConstructor(ClassGen clazz)(Code) | | Creates the constructor for the synthesized class. It is a no-arg
constructor that calls super.
Parameters: clazz - Template for the class being synthesized. Method template for the constructor. |
makeMethod | public MethodGen makeMethod(ClassGen clazz)(Code) | | Creates a method with bytecode determined by the name of
the class.
If we have class test.data.TestBogus, then we strip off the
"test.data.Test" prefix and call mgBogus() to get an
instruction list.
In the current version, if there is an underscore in the
class name, then the underscore and everything following it
will be ignored. So test.data.TestBogus_27 would result in a
call to mgBogus(), not mgBogus_27().
If the method (mgBogus in this case) doesn't exist, then we call
mgDefault() to generate the bytecode.
Parameters: clazz - Template for the class being produced. Template method with bytecode. |
mgDefault | public MethodGen mgDefault(ClassGen clazz)(Code) | | Generates bytecode for a method which simply returns 2. This
is the method used if the class name is test.data.TestDefault.
This method is also used if ClassFactory doesn't recognize the name;
for example, if the class name is test.data.TestBogus, because there
is no mgBogus method, this default method is used to generate the
bytecode.
public int runTest( int x ) {
return 2;
}
|
mgIfThen | public MethodGen mgIfThen(ClassGen clazz)(Code) | | Generates instructions for a method consisting of a single
if-then clause.
public int runTest( int x ) {
if (x > 0) {
return 3;
} else {
return 5;
}
}
|
mgNPENoCatch | public MethodGen mgNPENoCatch(ClassGen clazz)(Code) | | Creates bytecode which will throw a NullPointerException
without a catch block.
public int runTest(int x) {
null.runTest( 0 );
return 0;
}
|
mgNPEWithCatch | public MethodGen mgNPEWithCatch(ClassGen clazz)(Code) | | Returns bytecode which will throw a NullPointerException,
but it will catch the NPE.
try {
null.runTest( 0 );
return -1;
} catch (NullPointerException npe) {
return 3;
}
|
mgSelect | public MethodGen mgSelect(ClassGen clazz)(Code) | | Generates bytecode for a switch statement:
int runTest (int x) {
switch (x) {
case 1: return 1;
case 2: return 3;
case 3: return 5;
default: return 2;
}
}
|
mgWhile | public MethodGen mgWhile(ClassGen clazz)(Code) | | Generates code for a while loop. The while loop returns 0 if
the parameter x is greater than or equal to zero, but x
otherwise.
int runTest(int x) {
while (x > 0) {
x --;
}
return x;
}
The actual bytecode produced is:
Label | Instruction | Stack |
---|
| ILOAD | _ -> I |
if: | DUP | I -> II |
| IFLE (ret) | II -> I |
loop: | ICONST_1 | I -> II |
| ISUB | II -> I |
| GOTO (if) | I -> I |
ret: | IRETURN | I -> _ |
|
|
|