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

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