Thu, 12 Oct 2017 19:44:07 +0800
merge
1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.codemodel.internal;
28 import java.lang.annotation.Annotation;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.TreeSet;
33 import java.util.Collections;
34 import java.util.Collection;
36 import com.sun.codemodel.internal.util.ClassNameComparator;
38 /**
39 * Java method.
40 */
41 public class JMethod extends JGenerifiableImpl implements JDeclaration, JAnnotatable, JDocCommentable {
43 /**
44 * Modifiers for this method
45 */
46 private JMods mods;
48 /**
49 * Return type for this method
50 */
51 private JType type = null;
53 /**
54 * Name of this method
55 */
56 private String name = null;
58 /**
59 * List of parameters for this method's declaration
60 */
61 private final List<JVar> params = new ArrayList<JVar>();
63 /**
64 * Set of exceptions that this method may throw.
65 * A set instance lazily created.
66 */
67 private Set<JClass> _throws;
69 /**
70 * JBlock of statements that makes up the body this method
71 */
72 private JBlock body = null;
74 private JDefinedClass outer;
76 /**
77 * javadoc comments for this JMethod
78 */
79 private JDocComment jdoc = null;
81 /**
82 * Variable parameter for this method's varargs declaration
83 * introduced in J2SE 1.5
84 */
85 private JVar varParam = null;
87 /**
88 * Annotations on this variable. Lazily created.
89 */
90 private List<JAnnotationUse> annotations = null;
93 private boolean isConstructor() {
94 return type == null;
95 }
97 /** To set the default value for the
98 * annotation member
99 */
100 private JExpression defaultValue = null;
103 /**
104 * JMethod constructor
105 *
106 * @param mods
107 * Modifiers for this method's declaration
108 *
109 * @param type
110 * Return type for the method
111 *
112 * @param name
113 * Name of this method
114 */
115 JMethod(JDefinedClass outer, int mods, JType type, String name) {
116 this.mods = JMods.forMethod(mods);
117 this.type = type;
118 this.name = name;
119 this.outer = outer;
120 }
122 /**
123 * Constructor constructor
124 *
125 * @param mods
126 * Modifiers for this constructor's declaration
127 *
128 * @param _class
129 * JClass containing this constructor
130 */
131 JMethod(int mods, JDefinedClass _class) {
132 this.mods = JMods.forMethod(mods);
133 this.type = null;
134 this.name = _class.name();
135 this.outer = _class;
136 }
138 private Set<JClass> getThrows() {
139 if(_throws==null)
140 _throws = new TreeSet<JClass>(ClassNameComparator.theInstance);
141 return _throws;
142 }
144 /**
145 * Add an exception to the list of exceptions that this
146 * method may throw.
147 *
148 * @param exception
149 * Name of an exception that this method may throw
150 */
151 public JMethod _throws(JClass exception) {
152 getThrows().add(exception);
153 return this;
154 }
156 public JMethod _throws(Class<? extends Throwable> exception) {
157 return _throws(outer.owner().ref(exception));
158 }
160 /**
161 * Returns the list of variable of this method.
162 *
163 * @return List of parameters of this method. This list is not modifiable.
164 */
165 public List<JVar> params() {
166 return Collections.<JVar>unmodifiableList(params);
167 }
169 /**
170 * Add the specified variable to the list of parameters
171 * for this method signature.
172 *
173 * @param type
174 * JType of the parameter being added
175 *
176 * @param name
177 * Name of the parameter being added
178 *
179 * @return New parameter variable
180 */
181 public JVar param(int mods, JType type, String name) {
182 JVar v = new JVar(JMods.forVar(mods), type, name, null);
183 params.add(v);
184 return v;
185 }
187 public JVar param(JType type, String name) {
188 return param(JMod.NONE, type, name);
189 }
191 public JVar param(int mods, Class<?> type, String name) {
192 return param(mods, outer.owner()._ref(type), name);
193 }
195 public JVar param(Class<?> type, String name) {
196 return param(outer.owner()._ref(type), name);
197 }
199 /**
200 * @see #varParam(JType, String)
201 */
202 public JVar varParam(Class<?> type, String name) {
203 return varParam(outer.owner()._ref(type),name);
204 }
206 /**
207 * Add the specified variable argument to the list of parameters
208 * for this method signature.
209 *
210 * @param type
211 * Type of the parameter being added.
212 *
213 * @param name
214 * Name of the parameter being added
215 *
216 * @return the variable parameter
217 *
218 * @throws IllegalStateException
219 * If this method is called twice.
220 * varargs in J2SE 1.5 can appear only once in the
221 * method signature.
222 */
223 public JVar varParam(JType type, String name) {
224 if (!hasVarArgs()) {
226 varParam =
227 new JVar(
228 JMods.forVar(JMod.NONE),
229 type.array(),
230 name,
231 null);
232 return varParam;
233 } else {
234 throw new IllegalStateException(
235 "Cannot have two varargs in a method,\n"
236 + "Check if varParam method of JMethod is"
237 + " invoked more than once");
239 }
241 }
243 /**
244 * Adds an annotation to this variable.
245 * @param clazz
246 * The annotation class to annotate the field with
247 */
248 public JAnnotationUse annotate(JClass clazz){
249 if(annotations==null)
250 annotations = new ArrayList<JAnnotationUse>();
251 JAnnotationUse a = new JAnnotationUse(clazz);
252 annotations.add(a);
253 return a;
254 }
256 /**
257 * Adds an annotation to this variable.
258 *
259 * @param clazz
260 * The annotation class to annotate the field with
261 */
262 public JAnnotationUse annotate(Class <? extends Annotation> clazz){
263 return annotate(owner().ref(clazz));
264 }
266 public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
267 return TypedAnnotationWriter.create(clazz,this);
268 }
270 public Collection<JAnnotationUse> annotations() {
271 if (annotations == null)
272 annotations = new ArrayList<JAnnotationUse>();
273 return Collections.unmodifiableList(annotations);
274 }
276 /**
277 * Check if there are any varargs declared
278 * for this method signature.
279 */
280 public boolean hasVarArgs() {
281 return this.varParam!=null;
282 }
284 public String name() {
285 return name;
286 }
288 /**
289 * Changes the name of the method.
290 */
291 public void name(String n) {
292 this.name = n;
293 }
295 /**
296 * Returns the return type.
297 */
298 public JType type() {
299 return type;
300 }
302 /**
303 * Overrides the return type.
304 */
305 public void type(JType t) {
306 this.type = t;
307 }
309 /**
310 * Returns all the parameter types in an array.
311 * @return
312 * If there's no parameter, an empty array will be returned.
313 */
314 public JType[] listParamTypes() {
315 JType[] r = new JType[params.size()];
316 for (int i = 0; i < r.length; i++)
317 r[i] = params.get(i).type();
318 return r;
319 }
321 /**
322 * Returns the varags parameter type.
323 * @return
324 * If there's no vararg parameter type, null will be returned.
325 */
326 public JType listVarParamType() {
327 if (varParam != null)
328 return varParam.type();
329 else
330 return null;
331 }
333 /**
334 * Returns all the parameters in an array.
335 * @return
336 * If there's no parameter, an empty array will be returned.
337 */
338 public JVar[] listParams() {
339 return params.toArray(new JVar[params.size()]);
340 }
342 /**
343 * Returns the variable parameter
344 * @return
345 * If there's no parameter, null will be returned.
346 */
347 public JVar listVarParam() {
348 return varParam;
349 }
351 /**
352 * Returns true if the method has the specified signature.
353 */
354 public boolean hasSignature(JType[] argTypes) {
355 JVar[] p = listParams();
356 if (p.length != argTypes.length)
357 return false;
359 for (int i = 0; i < p.length; i++)
360 if (!p[i].type().equals(argTypes[i]))
361 return false;
363 return true;
364 }
366 /**
367 * Get the block that makes up body of this method
368 *
369 * @return Body of method
370 */
371 public JBlock body() {
372 if (body == null)
373 body = new JBlock();
374 return body;
375 }
377 /**
378 * Specify the default value for this annotation member
379 * @param value
380 * Default value for the annotation member
381 *
382 */
383 public void declareDefaultValue(JExpression value){
384 this.defaultValue = value;
385 }
387 /**
388 * Creates, if necessary, and returns the class javadoc for this
389 * JDefinedClass
390 *
391 * @return JDocComment containing javadocs for this class
392 */
393 public JDocComment javadoc() {
394 if (jdoc == null)
395 jdoc = new JDocComment(owner());
396 return jdoc;
397 }
399 public void declare(JFormatter f) {
400 if (jdoc != null)
401 f.g(jdoc);
403 if (annotations != null){
404 for (JAnnotationUse a : annotations)
405 f.g(a).nl();
406 }
408 f.g(mods);
410 // declare the generics parameters
411 super.declare(f);
413 if (!isConstructor())
414 f.g(type);
415 f.id(name).p('(').i();
416 // when parameters are printed in new lines, we want them to be indented.
417 // there's a good chance no newlines happen, too, but just in case it does.
418 boolean first = true;
419 for (JVar var : params) {
420 if (!first)
421 f.p(',');
422 if(var.isAnnotated())
423 f.nl();
424 f.b(var);
425 first = false;
426 }
427 if (hasVarArgs()) {
428 if (!first)
429 f.p(',');
430 f.g(varParam.type().elementType());
431 f.p("... ");
432 f.id(varParam.name());
433 }
435 f.o().p(')');
436 if (_throws!=null && !_throws.isEmpty()) {
437 f.nl().i().p("throws").g(_throws).nl().o();
438 }
440 if (defaultValue != null) {
441 f.p("default ");
442 f.g(defaultValue);
443 }
444 if (body != null) {
445 f.s(body);
446 } else if (
447 !outer.isInterface() && !outer.isAnnotationTypeDeclaration() && !mods.isAbstract() && !mods.isNative()) {
448 // Print an empty body for non-native, non-abstract methods
449 f.s(new JBlock());
450 } else {
451 f.p(';').nl();
452 }
453 }
455 /**
456 * @return
457 * the current modifiers of this method.
458 * Always return non-null valid object.
459 */
460 public JMods mods() {
461 return mods;
462 }
464 /**
465 * @deprecated use {@link #mods()}
466 */
467 public JMods getMods() {
468 return mods;
469 }
471 protected JCodeModel owner() {
472 return outer.owner();
473 }
474 }