You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CtNewConstructor.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist;
  17. import javassist.CtMethod.ConstParameter;
  18. import javassist.bytecode.Bytecode;
  19. import javassist.bytecode.ConstPool;
  20. import javassist.compiler.CompileError;
  21. import javassist.compiler.Javac;
  22. /**
  23. * A collection of static methods for creating a <code>CtConstructor</code>.
  24. * An instance of this class does not make any sense.
  25. *
  26. * <p>A class initializer (static constructor) cannot be created by the
  27. * methods in this class. Call <code>makeClassInitializer()</code> in
  28. * <code>CtClass</code> and append code snippet to the body of the class
  29. * initializer obtained by <code>makeClassInitializer()</code>.
  30. *
  31. * @see CtClass#addConstructor(CtConstructor)
  32. * @see CtClass#makeClassInitializer()
  33. */
  34. public class CtNewConstructor {
  35. /**
  36. * Specifies that no parameters are passed to a super-class'
  37. * constructor. That is, the default constructor is invoked.
  38. */
  39. public static final int PASS_NONE = 0; // call super()
  40. /**
  41. * Specifies that parameters are converted into an array of
  42. * <code>Object</code> and passed to a super-class'
  43. * constructor.
  44. */
  45. public static final int PASS_ARRAY = 1; // an array of parameters
  46. /**
  47. * Specifies that parameters are passed <i>as is</i>
  48. * to a super-class' constructor. The signature of that
  49. * constructor must be the same as that of the created constructor.
  50. */
  51. public static final int PASS_PARAMS = 2;
  52. /**
  53. * Compiles the given source code and creates a constructor.
  54. * The source code must include not only the constructor body
  55. * but the whole declaration.
  56. *
  57. * @param src the source text.
  58. * @param declaring the class to which the created constructor is added.
  59. */
  60. public static CtConstructor make(String src, CtClass declaring)
  61. throws CannotCompileException
  62. {
  63. Javac compiler = new Javac(declaring);
  64. try {
  65. CtMember obj = compiler.compile(src);
  66. if (obj instanceof CtConstructor) {
  67. // a stack map table has been already created.
  68. return (CtConstructor)obj;
  69. }
  70. }
  71. catch (CompileError e) {
  72. throw new CannotCompileException(e);
  73. }
  74. throw new CannotCompileException("not a constructor");
  75. }
  76. /**
  77. * Creates a public constructor.
  78. *
  79. * @param parameters a list of the parameter types.
  80. * @param exceptions a list of the exception types.
  81. * @param body the source text of the constructor body.
  82. * It must be a block surrounded by <code>{}</code>.
  83. * If it is <code>null</code>, the substituted
  84. * constructor body does nothing except calling
  85. * <code>super()</code>.
  86. * @param declaring the class to which the created method is added.
  87. */
  88. public static CtConstructor make(CtClass[] parameters,
  89. CtClass[] exceptions,
  90. String body, CtClass declaring)
  91. throws CannotCompileException
  92. {
  93. try {
  94. CtConstructor cc = new CtConstructor(parameters, declaring);
  95. cc.setExceptionTypes(exceptions);
  96. cc.setBody(body);
  97. return cc;
  98. }
  99. catch (NotFoundException e) {
  100. throw new CannotCompileException(e);
  101. }
  102. }
  103. /**
  104. * Creates a copy of a constructor.
  105. * This is a convenience method for calling
  106. * {@link CtConstructor#CtConstructor(CtConstructor, CtClass, ClassMap) this constructor}.
  107. * See the description of the constructor for particular behavior of the copying.
  108. *
  109. * @param c the copied constructor.
  110. * @param declaring the class to which the created method is added.
  111. * @param map the hash table associating original class names
  112. * with substituted names.
  113. * It can be <code>null</code>.
  114. *
  115. * @see CtConstructor#CtConstructor(CtConstructor,CtClass,ClassMap)
  116. */
  117. public static CtConstructor copy(CtConstructor c, CtClass declaring,
  118. ClassMap map) throws CannotCompileException {
  119. return new CtConstructor(c, declaring, map);
  120. }
  121. /**
  122. * Creates a default (public) constructor.
  123. *
  124. * <p>The created constructor takes no parameter. It calls
  125. * <code>super()</code>.
  126. */
  127. public static CtConstructor defaultConstructor(CtClass declaring)
  128. throws CannotCompileException
  129. {
  130. CtConstructor cons = new CtConstructor((CtClass[])null, declaring);
  131. ConstPool cp = declaring.getClassFile2().getConstPool();
  132. Bytecode code = new Bytecode(cp, 1, 1);
  133. code.addAload(0);
  134. try {
  135. code.addInvokespecial(declaring.getSuperclass(),
  136. "<init>", "()V");
  137. }
  138. catch (NotFoundException e) {
  139. throw new CannotCompileException(e);
  140. }
  141. code.add(Bytecode.RETURN);
  142. // no need to construct a stack map table.
  143. cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
  144. return cons;
  145. }
  146. /**
  147. * Creates a public constructor that only calls a constructor
  148. * in the super class. The created constructor receives parameters
  149. * specified by <code>parameters</code> but calls the super's
  150. * constructor without those parameters (that is, it calls the default
  151. * constructor).
  152. *
  153. * <p>The parameters passed to the created constructor should be
  154. * used for field initialization. <code>CtField.Initializer</code>
  155. * objects implicitly insert initialization code in constructor
  156. * bodies.
  157. *
  158. * @param parameters parameter types
  159. * @param exceptions exception types
  160. * @param declaring the class to which the created constructor
  161. * is added.
  162. * @see CtField.Initializer#byParameter(int)
  163. */
  164. public static CtConstructor skeleton(CtClass[] parameters,
  165. CtClass[] exceptions, CtClass declaring)
  166. throws CannotCompileException
  167. {
  168. return make(parameters, exceptions, PASS_NONE,
  169. null, null, declaring);
  170. }
  171. /**
  172. * Creates a public constructor that only calls a constructor
  173. * in the super class. The created constructor receives parameters
  174. * specified by <code>parameters</code> and calls the super's
  175. * constructor with those parameters.
  176. *
  177. * @param parameters parameter types
  178. * @param exceptions exception types
  179. * @param declaring the class to which the created constructor
  180. * is added.
  181. */
  182. public static CtConstructor make(CtClass[] parameters,
  183. CtClass[] exceptions, CtClass declaring)
  184. throws CannotCompileException
  185. {
  186. return make(parameters, exceptions, PASS_PARAMS,
  187. null, null, declaring);
  188. }
  189. /**
  190. * Creates a public constructor.
  191. *
  192. * <p>If <code>howto</code> is <code>PASS_PARAMS</code>,
  193. * the created constructor calls the super's constructor with the
  194. * same signature. The superclass must contain
  195. * a constructor taking the same set of parameters as the created one.
  196. *
  197. * <p>If <code>howto</code> is <code>PASS_NONE</code>,
  198. * the created constructor calls the super's default constructor.
  199. * The superclass must contain a constructor taking no parameters.
  200. *
  201. * <p>If <code>howto</code> is <code>PASS_ARRAY</code>,
  202. * the created constructor calls the super's constructor
  203. * with the given parameters in the form of an array of
  204. * <code>Object</code>. The signature of the super's constructor
  205. * must be:
  206. *
  207. * <pre>constructor(Object[] params, &lt;type&gt; cvalue)
  208. * </pre>
  209. *
  210. * <p>Here, <code>cvalue</code> is the constant value specified
  211. * by <code>cparam</code>.
  212. *
  213. * <p>If <code>cparam</code> is <code>null</code>, the signature
  214. * must be:
  215. *
  216. * <pre>constructor(Object[] params)</pre>
  217. *
  218. * <p>If <code>body</code> is not null, a copy of that method is
  219. * embedded in the body of the created constructor.
  220. * The embedded method is executed after
  221. * the super's constructor is called and the values of fields are
  222. * initialized. Note that <code>body</code> must not
  223. * be a constructor but a method.
  224. *
  225. * <p>Since the embedded method is wrapped
  226. * in parameter-conversion code
  227. * as in <code>CtNewMethod.wrapped()</code>,
  228. * the constructor parameters are
  229. * passed in the form of an array of <code>Object</code>.
  230. * The method specified by <code>body</code> must have the
  231. * signature shown below:
  232. *
  233. * <pre>Object method(Object[] params, &lt;type&gt; cvalue)</pre>
  234. *
  235. * <p>If <code>cparam</code> is <code>null</code>, the signature
  236. * must be:
  237. *
  238. * <pre>Object method(Object[] params)</pre>
  239. *
  240. * <p>Although the type of the returned value is <code>Object</code>,
  241. * the value must be always <code>null</code>.
  242. *
  243. * <p><i>Example:</i>
  244. *
  245. * <pre>
  246. * ClassPool pool = ... ;
  247. * CtClass xclass = pool.makeClass("X");
  248. * CtMethod method = pool.getMethod("Sample", "m");
  249. * xclass.setSuperclass(pool.get("Y"));
  250. * CtClass[] argTypes = { CtClass.intType };
  251. * ConstParameter cparam = ConstParameter.string("test");
  252. * CtConstructor c = CtNewConstructor.make(argTypes, null,
  253. * PASS_PARAMS, method, cparam, xclass);
  254. * xclass.addConstructor(c);</pre>
  255. *
  256. * <p>where the class <code>Sample</code> is as follows:
  257. *
  258. * <pre>
  259. * public class Sample {
  260. * public Object m(Object[] args, String msg) {
  261. * System.out.println(msg);
  262. * return null;
  263. * }
  264. * }</pre>
  265. *
  266. * <p>This program produces the following class:
  267. *
  268. * <pre>
  269. * public class X extends Y {
  270. * public X(int p0) {
  271. * super(p0);
  272. * String msg = "test";
  273. * Object[] args = new Object[] { p0 };
  274. * // begin of copied body
  275. * System.out.println(msg);
  276. * Object result = null;
  277. * // end
  278. * }
  279. * }</pre>
  280. *
  281. * @param parameters a list of the parameter types
  282. * @param exceptions a list of the exceptions
  283. * @param howto how to pass parameters to the super-class'
  284. * constructor (<code>PASS_NONE</code>,
  285. * <code>PASS_ARRAY</code>,
  286. * or <code>PASS_PARAMS</code>)
  287. * @param body appended body (may be <code>null</code>).
  288. * It must be not a constructor but a method.
  289. * @param cparam constant parameter (may be <code>null</code>.)
  290. * @param declaring the class to which the created constructor
  291. * is added.
  292. *
  293. * @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass)
  294. */
  295. public static CtConstructor make(CtClass[] parameters,
  296. CtClass[] exceptions, int howto,
  297. CtMethod body, ConstParameter cparam,
  298. CtClass declaring)
  299. throws CannotCompileException
  300. {
  301. return CtNewWrappedConstructor.wrapped(parameters, exceptions,
  302. howto, body, cparam, declaring);
  303. }
  304. }