/*
* 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);
// }
}