/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later, * or the Apache License Version 2.0. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * MODIFIED BY James Nelson of We The Internet, 2013. * Repackaged to avoid conflicts with different versions of Javassist, * and modified Javassist APIs to make them more accessible to outside code. */ package xapi.bytecode; public class CtNewConstructor { /** * Specifies that no parameters are passed to a super-class' * constructor. That is, the default constructor is invoked. */ public static final int PASS_NONE = 0; // call super() /** * Specifies that parameters are converted into an array of * <code>Object</code> and passed to a super-class' * constructor. */ public static final int PASS_ARRAY = 1; // an array of parameters /** * Specifies that parameters are passed <i>as is</i> * to a super-class' constructor. The signature of that * constructor must be the same as that of the created constructor. */ public static final int PASS_PARAMS = 2; // /** // * Compiles the given source code and creates a constructor. // * The source code must include not only the constructor body // * but the whole declaration. // * // * @param src the source text. // * @param declaring the class to which the created constructor is added. // */ // public static CtConstructor make(String src, CtClass declaring) // throws CannotCompileException // { // Javac compiler = new Javac(declaring); // try { // CtMember obj = compiler.compile(src); // if (obj instanceof CtConstructor) { // // a stack map table has been already created. // return (CtConstructor)obj; // } // } // catch (CompileError e) { // throw new CannotCompileException(e); // } // // throw new CannotCompileException("not a constructor"); // } /** * Creates a public constructor. * * @param parameters a list of the parameter types. * @param exceptions a list of the exception types. * @param body the source text of the constructor body. * It must be a block surrounded by <code>{}</code>. * If it is <code>null</code>, the substituted * constructor body does nothing except calling * <code>super()</code>. * @param declaring the class to which the created method is added. */ public static CtConstructor make(CtClass[] parameters, CtClass[] exceptions, String body, CtClass declaring) throws CannotCompileException { try { CtConstructor cc = new CtConstructor(parameters, declaring); cc.setExceptionTypes(exceptions); cc.setBody(body); return cc; } catch (NotFoundException e) { throw new CannotCompileException(e); } } /** * Creates a copy of a constructor. * This is a convenience method for calling * {@link CtConstructor#CtConstructor(CtConstructor, CtClass, ClassMap) this constructor}. * See the description of the constructor for particular behavior of the copying. * * @param c the copied constructor. * @param declaring the class to which the created method is added. * @param map the hash table associating original class names * with substituted names. * It can be <code>null</code>. * * @see CtConstructor#CtConstructor(CtConstructor,CtClass,ClassMap) */ public static CtConstructor copy(CtConstructor c, CtClass declaring, ClassMap map) throws CannotCompileException { return new CtConstructor(c, declaring, map); } /** * 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; } // /** // * Creates a public constructor that only calls a constructor // * in the super class. The created constructor receives parameters // * specified by <code>parameters</code> but calls the super's // * constructor without those parameters (that is, it calls the default // * constructor). // * // * <p>The parameters passed to the created constructor should be // * used for field initialization. <code>CtField.Initializer</code> // * objects implicitly insert initialization code in constructor // * bodies. // * // * @param parameters parameter types // * @param exceptions exception types // * @param declaring the class to which the created constructor // * is added. // * @see CtField.Initializer#byParameter(int) // */ // public static CtConstructor skeleton(CtClass[] parameters, // CtClass[] exceptions, CtClass declaring) // throws CannotCompileException // { // return make(parameters, exceptions, PASS_NONE, // null, null, declaring); // } // // /** // * Creates a public constructor that only calls a constructor // * in the super class. The created constructor receives parameters // * specified by <code>parameters</code> and calls the super's // * constructor with those parameters. // * // * @param parameters parameter types // * @param exceptions exception types // * @param declaring the class to which the created constructor // * is added. // */ // public static CtConstructor make(CtClass[] parameters, // CtClass[] exceptions, CtClass declaring) // throws CannotCompileException // { // return make(parameters, exceptions, PASS_PARAMS, // null, null, declaring); // } // // /** // * Creates a public constructor. // * // * <p>If <code>howto</code> is <code>PASS_PARAMS</code>, // * the created constructor calls the super's constructor with the // * same signature. The superclass must contain // * a constructor taking the same set of parameters as the created one. // * // * <p>If <code>howto</code> is <code>PASS_NONE</code>, // * the created constructor calls the super's default constructor. // * The superclass must contain a constructor taking no parameters. // * // * <p>If <code>howto</code> is <code>PASS_ARRAY</code>, // * the created constructor calls the super's constructor // * with the given parameters in the form of an array of // * <code>Object</code>. The signature of the super's constructor // * must be: // * // * <ul><code>constructor(Object[] params, <type> cvalue) // * </code></ul> // * // * <p>Here, <code>cvalue</code> is the constant value specified // * by <code>cparam</code>. // * // * <p>If <code>cparam</code> is <code>null</code>, the signature // * must be: // * // * <ul><code>constructor(Object[] params)</code></ul> // * // * <p>If <code>body</code> is not null, a copy of that method is // * embedded in the body of the created constructor. // * The embedded method is executed after // * the super's constructor is called and the values of fields are // * initialized. Note that <code>body</code> must not // * be a constructor but a method. // * // * <p>Since the embedded method is wrapped // * in parameter-conversion code // * as in <code>CtNewMethod.wrapped()</code>, // * the constructor parameters are // * passed in the form of an array of <code>Object</code>. // * The method specified by <code>body</code> must have the // * signature shown below: // * // * <ul><code>Object method(Object[] params, <type> cvalue) // * </code></ul> // * // * <p>If <code>cparam</code> is <code>null</code>, the signature // * must be: // * // * <ul><code>Object method(Object[] params)</code></ul> // * // * <p>Although the type of the returned value is <code>Object</code>, // * the value must be always <code>null</code>. // * // * <p><i>Example:</i> // * // * <ul><pre>ClassPool pool = ... ; // * CtClass xclass = pool.makeClass("X"); // * CtMethod method = pool.getMethod("Sample", "m"); // * xclass.setSuperclass(pool.get("Y")); // * CtClass[] argTypes = { CtClass.intType }; // * ConstParameter cparam = ConstParameter.string("test"); // * CtConstructor c = CtNewConstructor.make(argTypes, null, // * PASS_PARAMS, method, cparam, xclass); // * xclass.addConstructor(c);</pre></ul> // * // * <p>where the class <code>Sample</code> is as follows: // * // * <ul><pre>public class Sample { // * public Object m(Object[] args, String msg) { // * System.out.println(msg); // * return null; // * } // * }</pre></ul> // * // * <p>This program produces the following class: // * // * <ul><pre>public class X extends Y { // * public X(int p0) { // * super(p0); // * String msg = "test"; // * Object[] args = new Object[] { p0 }; // * // begin of copied body // * System.out.println(msg); // * Object result = null; // * // end // * } // * }</pre></ul> // * // * @param parameters a list of the parameter types // * @param exceptions a list of the exceptions // * @param howto how to pass parameters to the super-class' // * constructor (<code>PASS_NONE</code>, // * <code>PASS_ARRAY</code>, // * or <code>PASS_PARAMS</code>) // * @param body appended body (may be <code>null</code>). // * It must be not a constructor but a method. // * @param cparam constant parameter (may be <code>null</code>.) // * @param declaring the class to which the created constructor // * is added. // * // * @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass) // */ // public static CtConstructor make(CtClass[] parameters, // CtClass[] exceptions, int howto, // CtMethod body, ConstParameter cparam, // CtClass declaring) // throws CannotCompileException // { // return CtNewWrappedConstructor.wrapped(parameters, exceptions, // howto, body, cparam, declaring); // } }