Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

CtNewConstructor.java 12KB

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