123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 |
- /*******************************************************************************
- * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying
- * materials are made available under the terms of the Eclipse Public License
- * v1.0 which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Andy Clement - initial implementation
- ******************************************************************************/
-
- package org.aspectj.apache.bcel.classfile.tests;
-
- import java.io.File;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
-
- import org.aspectj.apache.bcel.Constants;
- import org.aspectj.apache.bcel.classfile.JavaClass;
- import org.aspectj.apache.bcel.classfile.Method;
- import org.aspectj.apache.bcel.classfile.annotation.Annotation;
- import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
- import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
- import org.aspectj.apache.bcel.generic.ALOAD;
- import org.aspectj.apache.bcel.generic.ASTORE;
- import org.aspectj.apache.bcel.generic.ArrayType;
- import org.aspectj.apache.bcel.generic.ClassGen;
- import org.aspectj.apache.bcel.generic.ConstantPoolGen;
- import org.aspectj.apache.bcel.generic.GOTO;
- import org.aspectj.apache.bcel.generic.InstructionConstants;
- import org.aspectj.apache.bcel.generic.InstructionFactory;
- import org.aspectj.apache.bcel.generic.InstructionHandle;
- import org.aspectj.apache.bcel.generic.InstructionList;
- import org.aspectj.apache.bcel.generic.LocalVariableGen;
- import org.aspectj.apache.bcel.generic.MethodGen;
- import org.aspectj.apache.bcel.generic.ObjectType;
- import org.aspectj.apache.bcel.generic.PUSH;
- import org.aspectj.apache.bcel.generic.Type;
- import org.aspectj.apache.bcel.generic.annotation.AnnotationElementValueGen;
- import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
- import org.aspectj.apache.bcel.generic.annotation.ArrayElementValueGen;
- import org.aspectj.apache.bcel.generic.annotation.ElementNameValuePairGen;
- import org.aspectj.apache.bcel.generic.annotation.ElementValueGen;
- import org.aspectj.apache.bcel.generic.annotation.SimpleElementValueGen;
- import org.aspectj.apache.bcel.util.SyntheticRepository;
-
- /**
- * The program that some of the tests generate looks like this:
- public class HelloWorld {
- public static void main(String[] argv) {
- BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
- String name = null;
- try {
- name = "Andy";
- } catch(IOException e) { return; }
- System.out.println("Hello, " + name);
- }
- }
- *
- */
- public class GeneratingAnnotatedClassesTest extends BcelTestCase {
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
-
- /*
- * Steps in the test:
- * 1) Programmatically construct the HelloWorld program
- * 2) Add two simple annotations at the class level
- * 3) Save the class to disk
- * 4) Reload the class using the 'static' variant of the BCEL classes
- * 5) Check the attributes are OK
- */
- public void testGenerateClassLevelAnnotations() throws ClassNotFoundException {
-
- // Create HelloWorld
- ClassGen cg = createClassGen("HelloWorld");
- ConstantPoolGen cp = cg.getConstantPool();
- InstructionList il = new InstructionList();
-
- cg.addAnnotation(createSimpleVisibleAnnotation(cp));
- cg.addAnnotation(createSimpleInvisibleAnnotation(cp));
-
- buildClassContents(cg, cp, il);
-
- dumpClass(cg, "HelloWorld.class");
-
- JavaClass jc = getClassFrom(".","HelloWorld");
-
- Annotation[] as = jc.getAnnotations();
- assertTrue("Should be two annotations but found "+as.length,as.length==2);
- Annotation one = as[0];
- Annotation two = as[1];
- assertTrue("Name of annotation 1 should be SimpleAnnotation but it is "+as[0].getTypeName(),
- as[0].getTypeName().equals("SimpleAnnotation"));
- assertTrue("Name of annotation 2 should be SimpleAnnotation but it is "+as[1].getTypeName(),
- as[1].getTypeName().equals("SimpleAnnotation"));
- List vals = as[0].getValues();
- ElementNameValuePair nvp = (ElementNameValuePair) vals.get(0);
- assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+
- nvp.getNameString(),nvp.getNameString().equals("id"));
- ElementValue ev = nvp.getValue();
- assertTrue("Type of element value should be int but it is "+ev.getElementValueType(),
- ev.getElementValueType()==ElementValue.PRIMITIVE_INT);
- assertTrue("Value of element should be 4 but it is "+ev.stringifyValue(),
- ev.stringifyValue().equals("4"));
- assertTrue(createTestdataFile("HelloWorld.class").delete());
- }
-
-
-
- /**
- * Just check that we can dump a class that has a method
- * annotation on it and it is still there when we read it back in
- */
- public void testGenerateMethodLevelAnnotations1() throws ClassNotFoundException {
- // Create HelloWorld
- ClassGen cg = createClassGen("HelloWorld");
- ConstantPoolGen cp = cg.getConstantPool();
- InstructionList il = new InstructionList();
-
- buildClassContentsWithAnnotatedMethods(cg, cp, il);
-
- // Check annotation is OK
- int i = cg.getMethods()[0].getAnnotations().length;
- assertTrue("Prior to dumping, main method should have 1 annotation but has "+i,i==1);
-
- dumpClass(cg, "temp1"+File.separator+"HelloWorld.class");
-
- JavaClass jc2 = getClassFrom("temp1","HelloWorld");
-
- // Check annotation is OK
- i = jc2.getMethods()[0].getAnnotations().length;
- assertTrue("JavaClass should say 1 annotation on main method but says "+i,i==1);
-
-
- ClassGen cg2 = new ClassGen(jc2);
-
- // Check it now it is a ClassGen
- Method[] m = cg2.getMethods();
- i = m[0].getAnnotations().length;
- assertTrue("The main 'Method' should have one annotation but has "+i,i==1);
- MethodGen mg = new MethodGen(m[0],cg2.getClassName(),cg2.getConstantPool());
-
- // Check it finally when the Method is changed to a MethodGen
- i = mg.getAnnotations().length;
- assertTrue("The main 'MethodGen' should have one annotation but has "+i,i==1);
-
- assertTrue(wipe("temp1"+File.separator+"HelloWorld.class"));
-
- }
-
- /**
- * Going further than the last test - when we reload the method back in, let's change it (adding a new
- * annotation) and then store that, read it back in and verify both annotations are there !
- */
- public void testGenerateMethodLevelAnnotations2() throws ClassNotFoundException {
- // Create HelloWorld
- ClassGen cg = createClassGen("HelloWorld");
- ConstantPoolGen cp = cg.getConstantPool();
- InstructionList il = new InstructionList();
-
- buildClassContentsWithAnnotatedMethods(cg, cp, il);
-
- dumpClass(cg,"temp2","HelloWorld.class");
-
- JavaClass jc2 = getClassFrom("temp2","HelloWorld");
-
- ClassGen cg2 = new ClassGen(jc2);
-
- // Main method after reading the class back in
- Method mainMethod1 = jc2.getMethods()[0];
- assertTrue("The 'Method' should have one annotations but has "+mainMethod1.getAnnotations().length,
- mainMethod1.getAnnotations().length==1);
-
- MethodGen mainMethod2 = new MethodGen(mainMethod1,cg2.getClassName(),cg2.getConstantPool());
-
- assertTrue("The 'MethodGen' should have one annotations but has "+mainMethod2.getAnnotations().length,
- mainMethod2.getAnnotations().length==1);
-
- mainMethod2.addAnnotation(createFruitAnnotation(cg2.getConstantPool(),"Pear"));
-
- cg2.removeMethod(mainMethod1);
- cg2.addMethod(mainMethod2.getMethod());
-
- dumpClass(cg2,"temp3","HelloWorld.class");
-
- JavaClass jc3 = getClassFrom("temp3","HelloWorld");
-
- ClassGen cg3 = new ClassGen(jc3);
-
- Method mainMethod3 = cg3.getMethods()[1];
- int i = mainMethod3.getAnnotations().length;
- assertTrue("The 'Method' should now have two annotations but has "+i,i==2);
-
- assertTrue(wipe("temp2","HelloWorld.class"));
- assertTrue(wipe("temp3","HelloWorld.class"));
- }
-
-
-
- //J5TODO: Need to add deleteFile calls to many of these tests
-
- /**
- * Transform simple class from an immutable to a mutable object.
- */
- public void testTransformClassToClassGen_SimpleTypes() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","SimpleAnnotatedClass");
- ClassGen cgen = new ClassGen(jc);
-
- // Check annotations are correctly preserved
- AnnotationGen[] annotations = cgen.getAnnotations();
- assertTrue("Expected one annotation but found "+annotations.length,
- annotations.length==1);
- }
-
- /**
- * Transform simple class from an immutable to a mutable object. The class is
- * annotated with an annotation that uses an enum.
- */
- public void testTransformClassToClassGen_EnumType() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","AnnotatedWithEnumClass");
- ClassGen cgen = new ClassGen(jc);
-
- // Check annotations are correctly preserved
- AnnotationGen[] annotations = cgen.getAnnotations();
- assertTrue("Expected one annotation but found "+annotations.length,
- annotations.length==1);
- }
-
- /**
- * Transform simple class from an immutable to a mutable object. The class is
- * annotated with an annotation that uses an array of SimpleAnnotations.
- */
- public void testTransformClassToClassGen_ArrayAndAnnotationTypes() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","AnnotatedWithCombinedAnnotation");
- ClassGen cgen = new ClassGen(jc);
-
- // Check annotations are correctly preserved
- AnnotationGen[] annotations = cgen.getAnnotations();
- assertTrue("Expected one annotation but found "+annotations.length,
- annotations.length==1);
- AnnotationGen a = annotations[0];
- assertTrue("That annotation should only have one value but has "+a.getValues().size(),a.getValues().size()==1);
- ElementNameValuePairGen nvp = (ElementNameValuePairGen)a.getValues().get(0);
- ElementValueGen value = (ElementValueGen)nvp.getValue();
- assertTrue("Value should be ArrayElementValueGen but is "+value,value instanceof ArrayElementValueGen);
- ArrayElementValueGen arrayValue = (ArrayElementValueGen)value;
- assertTrue("Array value should be size one but is "+arrayValue.getElementValuesSize(),
- arrayValue.getElementValuesSize()==1);
- ElementValueGen innerValue = (ElementValueGen)arrayValue.getElementValues().get(0);
- assertTrue("Value in the array should be AnnotationElementValueGen but is "+innerValue,
- innerValue instanceof AnnotationElementValueGen);
- AnnotationElementValueGen innerAnnotationValue = (AnnotationElementValueGen)innerValue;
- assertTrue("Should be called LSimpleAnnotation; but is called: "+innerAnnotationValue.getAnnotation().getTypeName(),
- innerAnnotationValue.getAnnotation().getTypeSignature().equals("LSimpleAnnotation;"));
- }
-
- /**
- * Transform complex class from an immutable to a mutable object.
- */
- public void testTransformComplexClassToClassGen() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","ComplexAnnotatedClass");
- ClassGen cgen = new ClassGen(jc);
-
- // Check annotations are correctly preserved
- AnnotationGen[] annotations = cgen.getAnnotations();
- assertTrue("Expected one annotation but found "+annotations.length,
- annotations.length==1);
- List l = annotations[0].getValues();
- boolean found = false;
- for (Iterator iter = l.iterator(); iter.hasNext();) {
- ElementNameValuePairGen element = (ElementNameValuePairGen) iter.next();
- if (element.getNameString().equals("dval")) {
- if (((SimpleElementValueGen)element.getValue()).stringifyValue().equals("33.4"))
- found = true;
- }
- }
- assertTrue("Did not find double annotation value with value 33.4",found);
- }
-
-
- /**
- * Load a class in and modify it with a new attribute - A SimpleAnnotation annotation
- */
- public void testModifyingClasses1() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","SimpleAnnotatedClass");
- ClassGen cgen = new ClassGen(jc);
- ConstantPoolGen cp = cgen.getConstantPool();
- cgen.addAnnotation(createFruitAnnotation(cp,"Pineapple"));
- assertTrue("Should now have two annotations but has "+cgen.getAnnotations().length,
- cgen.getAnnotations().length==2);
- dumpClass(cgen,"SimpleAnnotatedClass.class");
- assertTrue(wipe("SimpleAnnotatedClass.class"));
- }
-
- /**
- * Load a class in and modify it with a new attribute - A ComplexAnnotation annotation
- */
- public void testModifyingClasses2() throws ClassNotFoundException {
- JavaClass jc = getClassFrom("testcode.jar","SimpleAnnotatedClass");
- ClassGen cgen = new ClassGen(jc);
- ConstantPoolGen cp = cgen.getConstantPool();
- cgen.addAnnotation(createCombinedAnnotation(cp));
- assertTrue("Should now have two annotations but has "+cgen.getAnnotations().length,
- cgen.getAnnotations().length==2);
- dumpClass(cgen,"SimpleAnnotatedClass.class");
- JavaClass jc2 = getClassFrom(".","SimpleAnnotatedClass");
- jc2.getAnnotations();
- assertTrue(wipe("SimpleAnnotatedClass.class"));
- // System.err.println(jc2.toString());
- }
-
-
- private void dumpClass(ClassGen cg, String fname) {
- try {
- File f = createTestdataFile(fname);
- cg.getJavaClass().dump(f);
- } catch (java.io.IOException e) {
- System.err.println(e);
- }
- }
-
-
- private void dumpClass(ClassGen cg, String dir, String fname) {
- dumpClass(cg,dir+File.separator+fname);
- }
-
- private void buildClassContentsWithAnnotatedMethods(ClassGen cg, ConstantPoolGen cp, InstructionList il) {
- // Create method 'public static void main(String[]argv)'
- MethodGen mg = createMethodGen("main",il,cp);
- InstructionFactory factory = new InstructionFactory(cg);
- mg.addAnnotation(createSimpleVisibleAnnotation(mg.getConstantPool()));
- // We now define some often used types:
-
- ObjectType i_stream = new ObjectType("java.io.InputStream");
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- // Create variables in and name : We call the constructors, i.e.,
- // execute BufferedReader(InputStreamReader(System.in)) . The reference
- // to the BufferedReader object stays on top of the stack and is stored
- // in the newly allocated in variable.
-
- il.append(factory.createNew("java.io.BufferedReader"));
- il.append(InstructionConstants.DUP); // Use predefined constant
- il.append(factory.createNew("java.io.InputStreamReader"));
- il.append(InstructionConstants.DUP);
- il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC));
- il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",
- Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL));
- il.append(factory.createInvoke("java.io.BufferedReader", "<init>",
- Type.VOID, new Type[] { new ObjectType("java.io.Reader") },
- Constants.INVOKESPECIAL));
-
- LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType(
- "java.io.BufferedReader"), null, null);
- int in = lg.getIndex();
- lg.setStart(il.append(new ASTORE(in))); // "in" valid from here
-
- // Create local variable name and initialize it to null
-
- lg = mg.addLocalVariable("name", Type.STRING, null, null);
- int name = lg.getIndex();
- il.append(InstructionConstants.ACONST_NULL);
- lg.setStart(il.append(new ASTORE(name))); // "name" valid from here
-
- // Create try-catch block: We remember the start of the block, read a
- // line from the standard input and store it into the variable name .
-
- // InstructionHandle try_start = il.append(factory.createFieldAccess(
- // "java.lang.System", "out", p_stream, Constants.GETSTATIC));
-
- // il.append(new PUSH(cp, "Please enter your name> "));
- // il.append(factory.createInvoke("java.io.PrintStream", "print",
- // Type.VOID, new Type[] { Type.STRING },
- // Constants.INVOKEVIRTUAL));
- // il.append(new ALOAD(in));
- // il.append(factory.createInvoke("java.io.BufferedReader", "readLine",
- // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
- InstructionHandle try_start = il.append(new PUSH(cp,"Andy"));
- il.append(new ASTORE(name));
-
- // Upon normal execution we jump behind exception handler, the target
- // address is not known yet.
-
- GOTO g = new GOTO(null);
- InstructionHandle try_end = il.append(g);
-
- // We add the exception handler which simply returns from the method.
-
- LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null);
- int var_ex_slot = var_ex.getIndex();
-
- InstructionHandle handler = il.append(new ASTORE(var_ex_slot));
- var_ex.setStart(handler);
- var_ex.setEnd(il.append(InstructionConstants.RETURN));
-
- mg.addExceptionHandler(try_start, try_end, handler,
- new ObjectType("java.io.IOException"));
-
- // "Normal" code continues, now we can set the branch target of the GOTO
- // .
-
- InstructionHandle ih = il.append(factory.createFieldAccess(
- "java.lang.System", "out", p_stream, Constants.GETSTATIC));
- g.setTarget(ih);
-
- // Printing "Hello": String concatenation compiles to StringBuffer
- // operations.
-
- il.append(factory.createNew(Type.STRINGBUFFER));
- il.append(InstructionConstants.DUP);
- il.append(new PUSH(cp, "Hello, "));
- il
- .append(factory.createInvoke("java.lang.StringBuffer",
- "<init>", Type.VOID, new Type[] { Type.STRING },
- Constants.INVOKESPECIAL));
- il.append(new ALOAD(name));
- il.append(factory.createInvoke("java.lang.StringBuffer", "append",
- Type.STRINGBUFFER, new Type[] { Type.STRING },
- Constants.INVOKEVIRTUAL));
- il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
- Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
-
- il.append(factory.createInvoke("java.io.PrintStream", "println",
- Type.VOID, new Type[] { Type.STRING },
- Constants.INVOKEVIRTUAL));
- il.append(InstructionConstants.RETURN);
-
- // Finalization: Finally, we have to set the stack size, which normally
- // would have to be computed on the fly and add a default constructor
- // method to the class, which is empty in this case.
-
- mg.setMaxStack();
- mg.setMaxLocals();
- cg.addMethod(mg.getMethod());
- il.dispose(); // Allow instruction handles to be reused
- cg.addEmptyConstructor(Constants.ACC_PUBLIC);
- }
-
- private void buildClassContents(ClassGen cg, ConstantPoolGen cp, InstructionList il) {
- // Create method 'public static void main(String[]argv)'
- MethodGen mg = createMethodGen("main",il,cp);
- InstructionFactory factory = new InstructionFactory(cg);
- // We now define some often used types:
-
- ObjectType i_stream = new ObjectType("java.io.InputStream");
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- // Create variables in and name : We call the constructors, i.e.,
- // execute BufferedReader(InputStreamReader(System.in)) . The reference
- // to the BufferedReader object stays on top of the stack and is stored
- // in the newly allocated in variable.
-
- il.append(factory.createNew("java.io.BufferedReader"));
- il.append(InstructionConstants.DUP); // Use predefined constant
- il.append(factory.createNew("java.io.InputStreamReader"));
- il.append(InstructionConstants.DUP);
- il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC));
- il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",
- Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL));
- il.append(factory.createInvoke("java.io.BufferedReader", "<init>",
- Type.VOID, new Type[] { new ObjectType("java.io.Reader") },
- Constants.INVOKESPECIAL));
-
- LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType(
- "java.io.BufferedReader"), null, null);
- int in = lg.getIndex();
- lg.setStart(il.append(new ASTORE(in))); // "in" valid from here
-
- // Create local variable name and initialize it to null
-
- lg = mg.addLocalVariable("name", Type.STRING, null, null);
- int name = lg.getIndex();
- il.append(InstructionConstants.ACONST_NULL);
- lg.setStart(il.append(new ASTORE(name))); // "name" valid from here
-
- // Create try-catch block: We remember the start of the block, read a
- // line from the standard input and store it into the variable name .
-
- // InstructionHandle try_start = il.append(factory.createFieldAccess(
- // "java.lang.System", "out", p_stream, Constants.GETSTATIC));
-
- // il.append(new PUSH(cp, "Please enter your name> "));
- // il.append(factory.createInvoke("java.io.PrintStream", "print",
- // Type.VOID, new Type[] { Type.STRING },
- // Constants.INVOKEVIRTUAL));
- // il.append(new ALOAD(in));
- // il.append(factory.createInvoke("java.io.BufferedReader", "readLine",
- // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
- InstructionHandle try_start = il.append(new PUSH(cp,"Andy"));
- il.append(new ASTORE(name));
-
- // Upon normal execution we jump behind exception handler, the target
- // address is not known yet.
-
- GOTO g = new GOTO(null);
- InstructionHandle try_end = il.append(g);
-
- // We add the exception handler which simply returns from the method.
-
- LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null);
- int var_ex_slot = var_ex.getIndex();
-
- InstructionHandle handler = il.append(new ASTORE(var_ex_slot));
- var_ex.setStart(handler);
- var_ex.setEnd(il.append(InstructionConstants.RETURN));
-
- mg.addExceptionHandler(try_start, try_end, handler,
- new ObjectType("java.io.IOException"));
-
- // "Normal" code continues, now we can set the branch target of the GOTO
- // .
-
- InstructionHandle ih = il.append(factory.createFieldAccess(
- "java.lang.System", "out", p_stream, Constants.GETSTATIC));
- g.setTarget(ih);
-
- // Printing "Hello": String concatenation compiles to StringBuffer
- // operations.
-
- il.append(factory.createNew(Type.STRINGBUFFER));
- il.append(InstructionConstants.DUP);
- il.append(new PUSH(cp, "Hello, "));
- il
- .append(factory.createInvoke("java.lang.StringBuffer",
- "<init>", Type.VOID, new Type[] { Type.STRING },
- Constants.INVOKESPECIAL));
- il.append(new ALOAD(name));
- il.append(factory.createInvoke("java.lang.StringBuffer", "append",
- Type.STRINGBUFFER, new Type[] { Type.STRING },
- Constants.INVOKEVIRTUAL));
- il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
- Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
-
- il.append(factory.createInvoke("java.io.PrintStream", "println",
- Type.VOID, new Type[] { Type.STRING },
- Constants.INVOKEVIRTUAL));
- il.append(InstructionConstants.RETURN);
-
- // Finalization: Finally, we have to set the stack size, which normally
- // would have to be computed on the fly and add a default constructor
- // method to the class, which is empty in this case.
-
- mg.setMaxStack();
- mg.setMaxLocals();
- cg.addMethod(mg.getMethod());
- il.dispose(); // Allow instruction handles to be reused
- cg.addEmptyConstructor(Constants.ACC_PUBLIC);
- }
-
- private JavaClass getClassFrom(String where,String clazzname) throws ClassNotFoundException {
- SyntheticRepository repos = createRepos(where);
- return repos.loadClass(clazzname);
- }
-
-
-
-
- // helper methods
-
-
- private ClassGen createClassGen(String classname) {
- return new ClassGen(classname, "java.lang.Object",
- "<generated>", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
- }
-
- private MethodGen createMethodGen(String methodname,InstructionList il,ConstantPoolGen cp) {
- return new MethodGen(
- Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags
- Type.VOID, // return type
- new Type[] { new ArrayType(Type.STRING, 1) }, // argument types
- new String[] { "argv" }, // arg names
- methodname, "HelloWorld", // method, class
- il, cp);
- }
-
-
- public AnnotationGen createSimpleVisibleAnnotation(ConstantPoolGen cp) {
- SimpleElementValueGen evg = new SimpleElementValueGen(
- ElementValueGen.PRIMITIVE_INT, cp, 4);
-
- ElementNameValuePairGen nvGen = new ElementNameValuePairGen("id", evg,cp);
-
- ObjectType t = new ObjectType("SimpleAnnotation");
-
- List elements = new ArrayList();
- elements.add(nvGen);
-
- AnnotationGen a = new AnnotationGen(t, elements,true, cp);
- return a;
- }
-
- public AnnotationGen createFruitAnnotation(ConstantPoolGen cp,String aFruit) {
- SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.STRING,cp,aFruit);
- ElementNameValuePairGen nvGen = new ElementNameValuePairGen("fruit",evg,cp);
- ObjectType t = new ObjectType("SimpleStringAnnotation");
- List elements = new ArrayList();
- elements.add(nvGen);
- return new AnnotationGen(t,elements,true,cp);
- }
-
- public AnnotationGen createCombinedAnnotation(ConstantPoolGen cp) {
- // Create an annotation instance
- AnnotationGen a = createSimpleVisibleAnnotation(cp);
- ArrayElementValueGen array = new ArrayElementValueGen(cp);
- array.addElement(new AnnotationElementValueGen(a,cp));
- ElementNameValuePairGen nvp = new ElementNameValuePairGen("value",array,cp);
- List elements = new ArrayList();
- elements.add(nvp);
- return new AnnotationGen(new ObjectType("CombinedAnnotation"),elements,true,cp);
- }
-
- public AnnotationGen createSimpleInvisibleAnnotation(ConstantPoolGen cp) {
- SimpleElementValueGen evg = new SimpleElementValueGen(
- ElementValueGen.PRIMITIVE_INT, cp, 4);
-
- ElementNameValuePairGen nvGen = new ElementNameValuePairGen("id", evg,cp);
-
- ObjectType t = new ObjectType("SimpleAnnotation");
-
- List elements = new ArrayList();
- elements.add(nvGen);
-
- AnnotationGen a = new AnnotationGen(t, elements,false, cp);
- return a;
- }
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- }
|