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

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