All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javassist.CtNewConstructor Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
/*
 * 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.
 */

package javassist;

import javassist.bytecode.*;
import javassist.compiler.Javac;
import javassist.compiler.CompileError;
import javassist.CtMethod.ConstParameter;

/**
 * A collection of static methods for creating a CtConstructor.
 * An instance of this class does not make any sense.
 *
 * 

A class initializer (static constructor) cannot be created by the * methods in this class. Call makeClassInitializer() in * CtClass and append code snippet to the body of the class * initializer obtained by makeClassInitializer(). * * @see CtClass#addConstructor(CtConstructor) * @see CtClass#makeClassInitializer() */ 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 * Object and passed to a super-class' * constructor. */ public static final int PASS_ARRAY = 1; // an array of parameters /** * Specifies that parameters are passed as is * 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 {}. * If it is null, the substituted * constructor body does nothing except calling * super(). * @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 null. * * @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. * *

The created constructor takes no parameter. It calls * super(). */ 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(), "", "()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 parameters but calls the super's * constructor without those parameters (that is, it calls the default * constructor). * *

The parameters passed to the created constructor should be * used for field initialization. CtField.Initializer * 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 parameters 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. * *

If howto is PASS_PARAMS, * 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. * *

If howto is PASS_NONE, * the created constructor calls the super's default constructor. * The superclass must contain a constructor taking no parameters. * *

If howto is PASS_ARRAY, * the created constructor calls the super's constructor * with the given parameters in the form of an array of * Object. The signature of the super's constructor * must be: * *

constructor(Object[] params, <type> cvalue)
     * 
* *

Here, cvalue is the constant value specified * by cparam. * *

If cparam is null, the signature * must be: * *

constructor(Object[] params)
* *

If body 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 body must not * be a constructor but a method. * *

Since the embedded method is wrapped * in parameter-conversion code * as in CtNewMethod.wrapped(), * the constructor parameters are * passed in the form of an array of Object. * The method specified by body must have the * signature shown below: * *

Object method(Object[] params, <type> cvalue)
* *

If cparam is null, the signature * must be: * *

Object method(Object[] params)
* *

Although the type of the returned value is Object, * the value must be always null. * *

Example: * *

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

where the class Sample is as follows: * *

     * public class Sample {
     *     public Object m(Object[] args, String msg) {
     *         System.out.println(msg);
     *         return null;
     *     }
     * }
* *

This program produces the following class: * *

     * 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
     *     }
     * }
* * @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 (PASS_NONE, * PASS_ARRAY, * or PASS_PARAMS) * @param body appended body (may be null). * It must be not a constructor but a method. * @param cparam constant parameter (may be null.) * @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); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy