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

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