36 /** |
36 /** |
37 * Java method. |
37 * Java method. |
38 */ |
38 */ |
39 public class JMethod extends JGenerifiableImpl implements JDeclaration, JAnnotatable { |
39 public class JMethod extends JGenerifiableImpl implements JDeclaration, JAnnotatable { |
40 |
40 |
41 /** |
41 /** |
42 * Modifiers for this method |
42 * Modifiers for this method |
43 */ |
43 */ |
44 private JMods mods; |
44 private JMods mods; |
45 |
45 |
46 /** |
46 /** |
47 * Return type for this method |
47 * Return type for this method |
48 */ |
48 */ |
49 private JType type = null; |
49 private JType type = null; |
50 |
50 |
51 /** |
51 /** |
52 * Name of this method |
52 * Name of this method |
53 */ |
53 */ |
54 private String name = null; |
54 private String name = null; |
55 |
55 |
56 /** |
56 /** |
57 * List of parameters for this method's declaration |
57 * List of parameters for this method's declaration |
58 */ |
58 */ |
59 private final List<JVar> params = new ArrayList<JVar>(); |
59 private final List<JVar> params = new ArrayList<JVar>(); |
60 |
60 |
61 /** |
61 /** |
62 * Set of exceptions that this method may throw. |
62 * Set of exceptions that this method may throw. |
63 * A set instance lazily created. |
63 * A set instance lazily created. |
64 */ |
64 */ |
65 private Set<JClass> _throws; |
65 private Set<JClass> _throws; |
66 |
66 |
67 /** |
67 /** |
68 * JBlock of statements that makes up the body this method |
68 * JBlock of statements that makes up the body this method |
69 */ |
69 */ |
70 private JBlock body = null; |
70 private JBlock body = null; |
71 |
71 |
72 private JDefinedClass outer; |
72 private JDefinedClass outer; |
73 |
73 |
74 /** |
74 /** |
75 * javadoc comments for this JMethod |
75 * javadoc comments for this JMethod |
76 */ |
76 */ |
77 private JDocComment jdoc = null; |
77 private JDocComment jdoc = null; |
78 |
78 |
79 /** |
79 /** |
80 * Variable parameter for this method's varargs declaration |
80 * Variable parameter for this method's varargs declaration |
81 * introduced in J2SE 1.5 |
81 * introduced in J2SE 1.5 |
82 */ |
82 */ |
83 private JVar varParam = null; |
83 private JVar varParam = null; |
84 |
84 |
85 /** |
85 /** |
86 * Annotations on this variable. Lazily created. |
86 * Annotations on this variable. Lazily created. |
87 */ |
87 */ |
88 private List<JAnnotationUse> annotations = null; |
88 private List<JAnnotationUse> annotations = null; |
89 |
89 |
90 |
90 |
91 private boolean isConstructor() { |
91 private boolean isConstructor() { |
92 return type == null; |
92 return type == null; |
93 } |
93 } |
94 |
94 |
95 /** To set the default value for the |
95 /** To set the default value for the |
96 * annotation member |
96 * annotation member |
97 */ |
97 */ |
98 private JExpression defaultValue = null; |
98 private JExpression defaultValue = null; |
99 |
99 |
100 |
100 |
101 /** |
101 /** |
102 * JMethod constructor |
102 * JMethod constructor |
103 * |
103 * |
104 * @param mods |
104 * @param mods |
105 * Modifiers for this method's declaration |
105 * Modifiers for this method's declaration |
106 * |
106 * |
107 * @param type |
107 * @param type |
108 * Return type for the method |
108 * Return type for the method |
109 * |
109 * |
110 * @param name |
110 * @param name |
111 * Name of this method |
111 * Name of this method |
112 */ |
112 */ |
113 JMethod(JDefinedClass outer, int mods, JType type, String name) { |
113 JMethod(JDefinedClass outer, int mods, JType type, String name) { |
114 this.mods = JMods.forMethod(mods); |
114 this.mods = JMods.forMethod(mods); |
115 this.type = type; |
115 this.type = type; |
116 this.name = name; |
116 this.name = name; |
117 this.outer = outer; |
117 this.outer = outer; |
118 } |
118 } |
119 |
119 |
120 /** |
120 /** |
121 * Constructor constructor |
121 * Constructor constructor |
122 * |
122 * |
123 * @param mods |
123 * @param mods |
124 * Modifiers for this constructor's declaration |
124 * Modifiers for this constructor's declaration |
125 * |
125 * |
126 * @param _class |
126 * @param _class |
127 * JClass containing this constructor |
127 * JClass containing this constructor |
128 */ |
128 */ |
129 JMethod(int mods, JDefinedClass _class) { |
129 JMethod(int mods, JDefinedClass _class) { |
130 this.mods = JMods.forMethod(mods); |
130 this.mods = JMods.forMethod(mods); |
131 this.type = null; |
131 this.type = null; |
132 this.name = _class.name(); |
132 this.name = _class.name(); |
133 this.outer = _class; |
133 this.outer = _class; |
134 } |
134 } |
135 |
135 |
136 private Set<JClass> getThrows() { |
136 private Set<JClass> getThrows() { |
137 if(_throws==null) |
137 if(_throws==null) |
138 _throws = new TreeSet<JClass>(ClassNameComparator.theInstance); |
138 _throws = new TreeSet<JClass>(ClassNameComparator.theInstance); |
139 return _throws; |
139 return _throws; |
140 } |
140 } |
141 |
141 |
142 /** |
142 /** |
143 * Add an exception to the list of exceptions that this |
143 * Add an exception to the list of exceptions that this |
144 * method may throw. |
144 * method may throw. |
145 * |
145 * |
146 * @param exception |
146 * @param exception |
147 * Name of an exception that this method may throw |
147 * Name of an exception that this method may throw |
148 */ |
148 */ |
149 public JMethod _throws(JClass exception) { |
149 public JMethod _throws(JClass exception) { |
150 getThrows().add(exception); |
150 getThrows().add(exception); |
151 return this; |
151 return this; |
152 } |
152 } |
153 |
153 |
154 public JMethod _throws(Class exception) { |
154 public JMethod _throws(Class exception) { |
155 return _throws(outer.owner().ref(exception)); |
155 return _throws(outer.owner().ref(exception)); |
156 } |
156 } |
157 |
157 |
158 /** |
158 /** |
159 * Add the specified variable to the list of parameters |
159 * Add the specified variable to the list of parameters |
160 * for this method signature. |
160 * for this method signature. |
161 * |
161 * |
162 * @param type |
162 * @param type |
163 * JType of the parameter being added |
163 * JType of the parameter being added |
164 * |
164 * |
165 * @param name |
165 * @param name |
166 * Name of the parameter being added |
166 * Name of the parameter being added |
167 * |
167 * |
168 * @return New parameter variable |
168 * @return New parameter variable |
169 */ |
169 */ |
170 public JVar param(int mods, JType type, String name) { |
170 public JVar param(int mods, JType type, String name) { |
171 JVar v = new JVar(JMods.forVar(mods), type, name, null); |
171 JVar v = new JVar(JMods.forVar(mods), type, name, null); |
172 params.add(v); |
172 params.add(v); |
173 return v; |
173 return v; |
174 } |
174 } |
175 |
175 |
176 public JVar param(JType type, String name) { |
176 public JVar param(JType type, String name) { |
177 return param(JMod.NONE, type, name); |
177 return param(JMod.NONE, type, name); |
178 } |
178 } |
179 |
179 |
180 public JVar param(int mods, Class type, String name) { |
180 public JVar param(int mods, Class type, String name) { |
181 return param(mods, outer.owner()._ref(type), name); |
181 return param(mods, outer.owner()._ref(type), name); |
182 } |
182 } |
183 |
183 |
184 public JVar param(Class type, String name) { |
184 public JVar param(Class type, String name) { |
185 return param(outer.owner()._ref(type), name); |
185 return param(outer.owner()._ref(type), name); |
186 } |
186 } |
187 |
187 |
188 /** |
188 /** |
189 * @see #varParam(JType, String) |
189 * @see #varParam(JType, String) |
190 */ |
190 */ |
191 public JVar varParam(Class type, String name) { |
191 public JVar varParam(Class type, String name) { |
192 return varParam(outer.owner()._ref(type),name); |
192 return varParam(outer.owner()._ref(type),name); |
193 } |
193 } |
194 |
194 |
195 /** |
195 /** |
196 * Add the specified variable argument to the list of parameters |
196 * Add the specified variable argument to the list of parameters |
254 |
254 |
255 public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) { |
255 public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) { |
256 return TypedAnnotationWriter.create(clazz,this); |
256 return TypedAnnotationWriter.create(clazz,this); |
257 } |
257 } |
258 |
258 |
259 /** |
259 /** |
260 * Check if there are any varargs declared |
260 * Check if there are any varargs declared |
261 * for this method signature. |
261 * for this method signature. |
262 */ |
262 */ |
263 public boolean hasVarArgs() { |
263 public boolean hasVarArgs() { |
264 return this.varParam!=null; |
264 return this.varParam!=null; |
265 } |
265 } |
266 |
266 |
267 public String name() { |
267 public String name() { |
268 return name; |
268 return name; |
269 } |
269 } |
270 |
270 |
271 /** |
271 /** |
272 * Changes the name of the method. |
272 * Changes the name of the method. |
273 */ |
273 */ |
274 public void name(String n) { |
274 public void name(String n) { |
275 this.name = n; |
275 this.name = n; |
276 } |
276 } |
277 |
277 |
278 /** |
278 /** |
279 * Returns the return type. |
279 * Returns the return type. |
280 */ |
280 */ |
281 public JType type() { |
281 public JType type() { |
282 return type; |
282 return type; |
283 } |
283 } |
284 |
284 |
285 /** |
285 /** |
286 * Overrides the return type. |
286 * Overrides the return type. |
287 */ |
287 */ |
288 public void type(JType t) { |
288 public void type(JType t) { |
289 this.type = t; |
289 this.type = t; |
290 } |
290 } |
291 |
291 |
292 /** |
292 /** |
293 * Returns all the parameter types in an array. |
293 * Returns all the parameter types in an array. |
294 * @return |
294 * @return |
295 * If there's no parameter, an empty array will be returned. |
295 * If there's no parameter, an empty array will be returned. |
296 */ |
296 */ |
297 public JType[] listParamTypes() { |
297 public JType[] listParamTypes() { |
298 JType[] r = new JType[params.size()]; |
298 JType[] r = new JType[params.size()]; |
299 for (int i = 0; i < r.length; i++) |
299 for (int i = 0; i < r.length; i++) |
300 r[i] = params.get(i).type(); |
300 r[i] = params.get(i).type(); |
301 return r; |
301 return r; |
302 } |
302 } |
303 |
303 |
304 /** |
304 /** |
305 * Returns the varags parameter type. |
305 * Returns the varags parameter type. |
306 * @return |
306 * @return |
307 * If there's no vararg parameter type, null will be returned. |
307 * If there's no vararg parameter type, null will be returned. |
308 */ |
308 */ |
309 public JType listVarParamType() { |
309 public JType listVarParamType() { |
310 if (varParam != null) |
310 if (varParam != null) |
311 return varParam.type(); |
311 return varParam.type(); |
312 else |
312 else |
313 return null; |
313 return null; |
314 } |
314 } |
315 |
315 |
316 /** |
316 /** |
317 * Returns all the parameters in an array. |
317 * Returns all the parameters in an array. |
318 * @return |
318 * @return |
319 * If there's no parameter, an empty array will be returned. |
319 * If there's no parameter, an empty array will be returned. |
320 */ |
320 */ |
321 public JVar[] listParams() { |
321 public JVar[] listParams() { |
322 return params.toArray(new JVar[params.size()]); |
322 return params.toArray(new JVar[params.size()]); |
323 } |
323 } |
324 |
324 |
325 /** |
325 /** |
326 * Returns the variable parameter |
326 * Returns the variable parameter |
327 * @return |
327 * @return |
328 * If there's no parameter, null will be returned. |
328 * If there's no parameter, null will be returned. |
329 */ |
329 */ |
330 public JVar listVarParam() { |
330 public JVar listVarParam() { |
331 return varParam; |
331 return varParam; |
332 } |
332 } |
333 |
333 |
334 /** |
334 /** |
335 * Returns true if the method has the specified signature. |
335 * Returns true if the method has the specified signature. |
336 */ |
336 */ |
337 public boolean hasSignature(JType[] argTypes) { |
337 public boolean hasSignature(JType[] argTypes) { |
338 JVar[] p = listParams(); |
338 JVar[] p = listParams(); |
339 if (p.length != argTypes.length) |
339 if (p.length != argTypes.length) |
340 return false; |
340 return false; |
341 |
341 |
342 for (int i = 0; i < p.length; i++) |
342 for (int i = 0; i < p.length; i++) |
343 if (!p[i].type().equals(argTypes[i])) |
343 if (!p[i].type().equals(argTypes[i])) |
344 return false; |
344 return false; |
345 |
345 |
346 return true; |
346 return true; |
347 } |
347 } |
348 |
348 |
349 /** |
349 /** |
350 * Get the block that makes up body of this method |
350 * Get the block that makes up body of this method |
351 * |
351 * |
352 * @return Body of method |
352 * @return Body of method |
353 */ |
353 */ |
354 public JBlock body() { |
354 public JBlock body() { |
355 if (body == null) |
355 if (body == null) |
356 body = new JBlock(); |
356 body = new JBlock(); |
357 return body; |
357 return body; |
358 } |
358 } |
359 |
359 |
360 /** |
360 /** |
361 * Specify the default value for this annotation member |
361 * Specify the default value for this annotation member |
362 * @param value |
362 * @param value |
363 * Default value for the annotation member |
363 * Default value for the annotation member |
365 */ |
365 */ |
366 public void declareDefaultValue(JExpression value){ |
366 public void declareDefaultValue(JExpression value){ |
367 this.defaultValue = value; |
367 this.defaultValue = value; |
368 } |
368 } |
369 |
369 |
370 /** |
370 /** |
371 * Creates, if necessary, and returns the class javadoc for this |
371 * Creates, if necessary, and returns the class javadoc for this |
372 * JDefinedClass |
372 * JDefinedClass |
373 * |
373 * |
374 * @return JDocComment containing javadocs for this class |
374 * @return JDocComment containing javadocs for this class |
375 */ |
375 */ |
376 public JDocComment javadoc() { |
376 public JDocComment javadoc() { |
377 if (jdoc == null) |
377 if (jdoc == null) |
378 jdoc = new JDocComment(owner()); |
378 jdoc = new JDocComment(owner()); |
379 return jdoc; |
379 return jdoc; |
380 } |
380 } |
381 |
381 |
382 public void declare(JFormatter f) { |
382 public void declare(JFormatter f) { |
383 if (jdoc != null) |
383 if (jdoc != null) |
384 f.g(jdoc); |
384 f.g(jdoc); |
385 |
385 |
386 if (annotations != null){ |
386 if (annotations != null){ |
387 for (JAnnotationUse a : annotations) |
387 for (JAnnotationUse a : annotations) |
388 f.g(a).nl(); |
388 f.g(a).nl(); |
389 } |
389 } |
390 |
390 |
391 // declare the generics parameters |
391 // declare the generics parameters |
392 super.declare(f); |
392 super.declare(f); |
393 |
393 |
394 f.g(mods); |
394 f.g(mods); |
395 if (!isConstructor()) |
395 if (!isConstructor()) |
396 f.g(type); |
396 f.g(type); |
397 f.id(name).p('(').i(); |
397 f.id(name).p('(').i(); |
398 // when parameters are printed in new lines, we want them to be indented. |
398 // when parameters are printed in new lines, we want them to be indented. |
399 // there's a good chance no newlines happen, too, but just in case it does. |
399 // there's a good chance no newlines happen, too, but just in case it does. |
400 boolean first = true; |
400 boolean first = true; |
401 for (JVar var : params) { |
401 for (JVar var : params) { |
402 if (!first) |
402 if (!first) |
403 f.p(','); |
403 f.p(','); |
404 if(var.isAnnotated()) |
404 if(var.isAnnotated()) |
405 f.nl(); |
405 f.nl(); |
406 f.b(var); |
406 f.b(var); |
407 first = false; |
407 first = false; |
408 } |
408 } |
409 if (hasVarArgs()) { |
409 if (hasVarArgs()) { |
410 if (!first) |
410 if (!first) |
411 f.p(','); |
411 f.p(','); |
412 f.g(varParam.type().elementType()); |
412 f.g(varParam.type().elementType()); |
413 f.p("... "); |
413 f.p("... "); |
414 f.id(varParam.name()); |
414 f.id(varParam.name()); |
415 } |
415 } |
416 |
416 |
417 f.o().p(')'); |
417 f.o().p(')'); |
418 if (_throws!=null && !_throws.isEmpty()) { |
418 if (_throws!=null && !_throws.isEmpty()) { |
419 f.nl().i().p("throws").g(_throws).nl().o(); |
419 f.nl().i().p("throws").g(_throws).nl().o(); |
420 } |
420 } |
421 |
421 |
422 if (defaultValue != null) { |
422 if (defaultValue != null) { |
423 f.p("default "); |
423 f.p("default "); |
424 f.g(defaultValue); |
424 f.g(defaultValue); |
425 } |
425 } |
426 if (body != null) { |
426 if (body != null) { |
427 f.s(body); |
427 f.s(body); |
428 } else if ( |
428 } else if ( |
429 !outer.isInterface() && !outer.isAnnotationTypeDeclaration() && !mods.isAbstract() && !mods.isNative()) { |
429 !outer.isInterface() && !outer.isAnnotationTypeDeclaration() && !mods.isAbstract() && !mods.isNative()) { |
430 // Print an empty body for non-native, non-abstract methods |
430 // Print an empty body for non-native, non-abstract methods |
431 f.s(new JBlock()); |
431 f.s(new JBlock()); |
432 } else { |
432 } else { |
433 f.p(';').nl(); |
433 f.p(';').nl(); |
434 } |
434 } |
435 } |
435 } |
436 |
436 |
437 /** |
437 /** |
438 * @return |
438 * @return |
439 * the current modifiers of this method. |
439 * the current modifiers of this method. |
440 * Always return non-null valid object. |
440 * Always return non-null valid object. |