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 11KB

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