/** * Constructs a compiler. * * @param thisClass the class that a compiled method/field * belongs to. */ public Javac(CtClass thisClass) { this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0), thisClass); }
/** * Main method. * * @param args <code>args[0]</code> is the class file name. */ public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java Dump <class file name>"); return; } DataInputStream in = new DataInputStream( new FileInputStream(args[0])); ClassFile w = new ClassFile(in); PrintWriter out = new PrintWriter(System.out, true); out.println("*** constant pool ***"); w.getConstPool().print(out); out.println(); out.println("*** members ***"); ClassFilePrinter.print(w, out); } }
private CtField(String typeDesc, String name, CtClass clazz) throws CannotCompileException { super(clazz); ClassFile cf = clazz.getClassFile2(); if (cf == null) throw new CannotCompileException("bad declaring class: " + clazz.getName()); fieldInfo = new FieldInfo(cf.getConstPool(), name, typeDesc); }
public void instrument(CodeConverter converter) throws CannotCompileException { checkModify(); ClassFile cf = getClassFile2(); ConstPool cp = cf.getConstPool(); List list = cf.getMethods(); int n = list.size(); for (int i = 0; i < n; ++i) { MethodInfo minfo = (MethodInfo)list.get(i); converter.doit(this, minfo, cp); } }
/** * Constructs a compiler. * * @param thisClass the class that a compiled method/field * belongs to. */ public Javac(CtClass thisClass) { this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0), thisClass); }
public void setGenericSignature(String sig) { ClassFile cf = getClassFile(); SignatureAttribute sa = new SignatureAttribute(cf.getConstPool(), sig); cf.addAttribute(sa); }
private CtField(String typeDesc, String name, CtClass clazz) throws CannotCompileException { super(clazz); ClassFile cf = clazz.getClassFile2(); if (cf == null) throw new CannotCompileException("bad declaring class: " + clazz.getName()); fieldInfo = new FieldInfo(cf.getConstPool(), name, typeDesc); }
@Override public void instrument(CodeConverter converter) throws CannotCompileException { checkModify(); ClassFile cf = getClassFile2(); ConstPool cp = cf.getConstPool(); List<MethodInfo> methods = cf.getMethods(); for (MethodInfo minfo: methods.toArray(new MethodInfo[methods.size()])) converter.doit(this, minfo, cp); }
public void setAttribute(String name, byte[] data) { checkModify(); ClassFile cf = getClassFile2(); cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data)); }
@Override public void setGenericSignature(String sig) { ClassFile cf = getClassFile(); SignatureAttribute sa = new SignatureAttribute(cf.getConstPool(), sig); cf.addAttribute(sa); }
/** * Creates a method from a <code>MethodInfo</code> object. * * @param declaring the class declaring the method. * @throws CannotCompileException if the the <code>MethodInfo</code> * object and the declaring class have different * <code>ConstPool</code> objects * @since 3.6 */ public static CtMethod make(MethodInfo minfo, CtClass declaring) throws CannotCompileException { if (declaring.getClassFile2().getConstPool() != minfo.getConstPool()) throw new CannotCompileException("bad declaring class"); return new CtMethod(minfo, declaring); }
/** * Creates a public abstract method. The created method must be * added to a class with <code>CtClass.addMethod()</code>. * * @param declaring the class to which the created method is added. * @param returnType the type of the returned value * @param mname the method name * @param parameters a list of the parameter types * * @see CtClass#addMethod(CtMethod) */ public CtMethod(CtClass returnType, String mname, CtClass[] parameters, CtClass declaring) { this(null, declaring); ConstPool cp = declaring.getClassFile2().getConstPool(); String desc = Descriptor.ofMethod(returnType, parameters); methodInfo = new MethodInfo(cp, mname, desc); setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT); }
@Override public void setAttribute(String name, byte[] data) { checkModify(); ClassFile cf = getClassFile2(); cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data)); }
/** * Creates a constructor with no constructor body. * The created constructor * must be added to a class with <code>CtClass.addConstructor()</code>. * * <p>The created constructor does not include a constructor body, * which must be specified with <code>setBody()</code>. * * @param declaring the class to which the created method is added. * @param parameters a list of the parameter types * * @see CtClass#addConstructor(CtConstructor) * @see CtConstructor#setBody(String) * @see CtConstructor#setBody(CtConstructor,ClassMap) */ public CtConstructor(CtClass[] parameters, CtClass declaring) { this((MethodInfo)null, declaring); ConstPool cp = declaring.getClassFile2().getConstPool(); String desc = Descriptor.ofConstructor(parameters); methodInfo = new MethodInfo(cp, "<init>", desc); setModifiers(Modifier.PUBLIC); }
public CtClass makeNestedClass(String name, boolean isStatic) { if (!isStatic) throw new RuntimeException( "sorry, only nested static class is supported"); checkModify(); CtClass c = classPool.makeNestedClass(getName() + "$" + name); ClassFile cf = getClassFile2(); ClassFile cf2 = c.getClassFile2(); InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( InnerClassesAttribute.tag); if (ica == null) { ica = new InnerClassesAttribute(cf.getConstPool()); cf.addAttribute(ica); } ica.append(c.getName(), this.getName(), name, (cf2.getAccessFlags() & ~AccessFlag.SUPER) | AccessFlag.STATIC); cf2.addAttribute(ica.copy(cf2.getConstPool(), null)); return c; }
public CtConstructor makeClassInitializer() throws CannotCompileException { CtConstructor clinit = getClassInitializer(); if (clinit != null) return clinit; checkModify(); ClassFile cf = getClassFile2(); Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); modifyClassConstructor(cf, code, 0, 0); return getClassInitializer(); }
static Bytecode makeBody(CtClass clazz, ClassFile classfile, CtMethod wrappedBody, CtClass[] parameters, CtClass returnType, ConstParameter cparam) throws CannotCompileException { boolean isStatic = Modifier.isStatic(wrappedBody.getModifiers()); Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0); int stacksize = makeBody0(clazz, classfile, wrappedBody, isStatic, parameters, returnType, cparam, code); code.setMaxStack(stacksize); code.setMaxLocals(isStatic, parameters, 0); return code; }
@Override public CtConstructor makeClassInitializer() throws CannotCompileException { CtConstructor clinit = getClassInitializer(); if (clinit != null) return clinit; checkModify(); ClassFile cf = getClassFile2(); Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); modifyClassConstructor(cf, code, 0, 0); return getClassInitializer(); }
private void modifyClassConstructor(ClassFile cf) throws CannotCompileException, NotFoundException { if (fieldInitializers == null) return; Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); Javac jv = new Javac(code, this); int stacksize = 0; boolean doInit = false; for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) { CtField f = fi.field; if (Modifier.isStatic(f.getModifiers())) { doInit = true; int s = fi.init.compileIfStatic(f.getType(), f.getName(), code, jv); if (stacksize < s) stacksize = s; } } if (doInit) // need an initializer for static fileds. modifyClassConstructor(cf, code, stacksize, 0); }
/** * Creates a default (public) constructor. * * <p>The created constructor takes no parameter. It calls * <code>super()</code>. */ public static CtConstructor defaultConstructor(CtClass declaring) throws CannotCompileException { CtConstructor cons = new CtConstructor((CtClass[])null, declaring); ConstPool cp = declaring.getClassFile2().getConstPool(); Bytecode code = new Bytecode(cp, 1, 1); code.addAload(0); try { code.addInvokespecial(declaring.getSuperclass(), "<init>", "()V"); } catch (NotFoundException e) { throw new CannotCompileException(e); } code.add(Bytecode.RETURN); // no need to construct a stack map table. cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute()); return cons; }