1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 package com.helger.jcodemodel;
42
43 import java.lang.annotation.Annotation;
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.List;
48 import java.util.Set;
49 import java.util.TreeSet;
50
51 import javax.annotation.Nonnegative;
52 import javax.annotation.Nonnull;
53 import javax.annotation.Nullable;
54
55 import com.helger.jcodemodel.util.ClassNameComparator;
56 import com.helger.jcodemodel.util.JCValueEnforcer;
57
58
59
60
61 public class JMethod extends AbstractJGenerifiableImpl implements IJAnnotatable, IJDocCommentable
62 {
63
64
65
66 private final JMods m_aMods;
67
68
69
70
71 private AbstractJType m_aReturnType;
72
73
74
75
76 private String m_sName;
77
78
79
80
81 private final List <JVar> m_aParams = new ArrayList <> ();
82
83
84
85
86
87 private Set <AbstractJClass> m_aThrows;
88
89
90
91
92 private JBlock m_aBody;
93
94 private final JDefinedClass m_aOwningClass;
95
96
97
98
99 private JDocComment m_aJDoc;
100
101
102
103
104
105 private JVar m_aVarParam;
106
107
108
109
110 private List <JAnnotationUse> m_aAnnotations;
111
112
113
114 private IJExpression m_aDefaultValue;
115
116
117
118
119
120
121
122
123
124
125
126
127
128 protected JMethod (@Nonnull final JDefinedClass aOwningClass,
129 final int nMods,
130 @Nonnull final AbstractJType aReturnType,
131 @Nonnull final String sName)
132 {
133 JCValueEnforcer.notNull (aOwningClass, "OwningClass");
134 JCValueEnforcer.notNull (aReturnType, "ReturnType");
135 JCValueEnforcer.notEmpty (sName, "Name");
136 m_aMods = JMods.forMethod (nMods);
137 m_aReturnType = aReturnType;
138 m_sName = sName;
139 m_aOwningClass = aOwningClass;
140 }
141
142
143
144
145
146
147
148
149
150 protected JMethod (final int nMods, @Nonnull final JDefinedClass aClass)
151 {
152 JCValueEnforcer.notNull (aClass, "Class");
153 m_aMods = JMods.forMethod (nMods);
154 m_aReturnType = null;
155 m_sName = aClass.name ();
156 m_aOwningClass = aClass;
157 }
158
159 public boolean isConstructor ()
160 {
161 return m_aReturnType == null;
162 }
163
164 @Nonnull
165 public Collection <AbstractJClass> getThrows ()
166 {
167 if (m_aThrows == null)
168 return Collections.emptySet ();
169 return Collections.unmodifiableSet (m_aThrows);
170 }
171
172
173
174
175
176
177
178
179 @Nonnull
180 public JMethod _throws (@Nonnull final AbstractJClass aException)
181 {
182 if (m_aThrows == null)
183 m_aThrows = new TreeSet <> (ClassNameComparator.getInstance ());
184 m_aThrows.add (aException);
185 return this;
186 }
187
188 @Nonnull
189 public JMethod _throws (@Nonnull final Class <? extends Throwable> aException)
190 {
191 return _throws (m_aOwningClass.owner ().ref (aException));
192 }
193
194
195
196
197
198
199 @Nonnull
200 public List <JVar> params ()
201 {
202 return Collections.unmodifiableList (m_aParams);
203 }
204
205 @Nonnull
206 public JVar paramAtIndex (@Nonnegative final int nIndex) throws IndexOutOfBoundsException
207 {
208 return m_aParams.get (nIndex);
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223 @Nonnull
224 public JVar param (final int nMods, @Nonnull final AbstractJType aType, @Nonnull final String sName)
225 {
226 final JVarhtml#JVar">JVar aVar = new JVar (JMods.forVar (nMods), aType, sName, null);
227 m_aParams.add (aVar);
228 return aVar;
229 }
230
231 @Nonnull
232 public JVar param (@Nonnull final AbstractJType aType, @Nonnull final String sName)
233 {
234 return param (JMod.NONE, aType, sName);
235 }
236
237 @Nonnull
238 public JVar param (final int nMods, @Nonnull final Class <?> aType, @Nonnull final String sName)
239 {
240 return param (nMods, m_aOwningClass.owner ()._ref (aType), sName);
241 }
242
243 @Nonnull
244 public JVar param (@Nonnull final Class <?> aType, @Nonnull final String sName)
245 {
246 return param (m_aOwningClass.owner ()._ref (aType), sName);
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 @Nonnull
263 public JVar varParam (@Nonnull final Class <?> aType, @Nonnull final String sName)
264 {
265 return varParam (m_aOwningClass.owner ()._ref (aType), sName);
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 @Nonnull
282 public JVar varParam (@Nonnull final AbstractJType aType, @Nonnull final String sName)
283 {
284 return varParam (JMod.NONE, aType, sName);
285 }
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 @Nonnull
304 public JVar varParam (final int nMods, @Nonnull final Class <?> aType, @Nonnull final String sName)
305 {
306 return varParam (nMods, m_aOwningClass.owner ()._ref (aType), sName);
307 }
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325 @Nonnull
326 public JVar varParam (final int nMods, @Nonnull final AbstractJType aType, @Nonnull final String sName)
327 {
328 JCValueEnforcer.isFalse (hasVarArgs (),
329 "Cannot have two varargs in a method,\n" +
330 "Check if varParam method of JMethod is" +
331 " invoked more than once");
332
333 m_aVarParam = new JVar (JMods.forVar (nMods), aType.array (), sName, null);
334 return m_aVarParam;
335 }
336
337 @Nullable
338 public JVar varParam ()
339 {
340 return m_aVarParam;
341 }
342
343
344
345
346
347 public boolean hasVarArgs ()
348 {
349 return m_aVarParam != null;
350 }
351
352
353
354
355
356
357 @Nullable
358 public AbstractJType listVarParamType ()
359 {
360 return m_aVarParam != null ? m_aVarParam.type () : null;
361 }
362
363
364
365
366
367
368
369
370 @Nonnull
371 public JAnnotationUse annotate (@Nonnull final AbstractJClass aClazz)
372 {
373 if (m_aAnnotations == null)
374 m_aAnnotations = new ArrayList <> ();
375 final JAnnotationUsese.html#JAnnotationUse">JAnnotationUse a = new JAnnotationUse (aClazz);
376 m_aAnnotations.add (a);
377 return a;
378 }
379
380
381
382
383
384
385
386
387 @Nonnull
388 public JAnnotationUse annotate (@Nonnull final Class <? extends Annotation> aClazz)
389 {
390 return annotate (owner ().ref (aClazz));
391 }
392
393 @Nonnull
394 public Collection <JAnnotationUse> annotations ()
395 {
396 if (m_aAnnotations == null)
397 return Collections.emptyList ();
398 return Collections.unmodifiableList (m_aAnnotations);
399 }
400
401 public String name ()
402 {
403 return m_sName;
404 }
405
406
407
408
409
410
411
412 public void name (@Nonnull final String sName)
413 {
414 JCValueEnforcer.notEmpty (sName, "Name");
415 m_sName = sName;
416 }
417
418
419
420
421 @Nullable
422 public AbstractJType type ()
423 {
424 return m_aReturnType;
425 }
426
427
428
429
430
431
432
433
434 public void type (@Nullable final AbstractJType aReturnType)
435 {
436 m_aReturnType = aReturnType;
437 }
438
439
440
441
442
443
444 @Nonnull
445 public AbstractJType [] listParamTypes ()
446 {
447 final AbstractJTypehtml#AbstractJType">AbstractJType [] r = new AbstractJType [m_aParams.size ()];
448 for (int i = 0; i < r.length; i++)
449 r[i] = m_aParams.get (i).type ();
450 return r;
451 }
452
453
454
455
456
457
458 @Nonnull
459 public JVar [] listParams ()
460 {
461 return m_aParams.toArray (new JVar [m_aParams.size ()]);
462 }
463
464
465
466
467
468
469
470 @Nullable
471 @Deprecated
472 public JVar listVarParam ()
473 {
474 return varParam ();
475 }
476
477
478
479
480
481
482
483
484 public boolean hasSignature (@Nonnull final AbstractJType [] argTypes)
485 {
486 final JVar [] aParams = listParams ();
487 if (aParams.length != argTypes.length)
488 return false;
489
490 for (int i = 0; i < aParams.length; i++)
491 if (!aParams[i].type ().equals (argTypes[i]))
492 return false;
493
494 return true;
495 }
496
497
498
499
500
501
502 @Nonnull
503 public JBlock body ()
504 {
505 if (m_aBody == null)
506 m_aBody = new JBlock ();
507 return m_aBody;
508 }
509
510
511
512
513
514
515
516 public void declareDefaultValue (@Nullable final IJExpression aDefaultValue)
517 {
518 m_aDefaultValue = aDefaultValue;
519 }
520
521 @Nonnull
522 public JDocComment javadoc ()
523 {
524 if (m_aJDoc == null)
525 m_aJDoc = new JDocComment (owner ());
526 return m_aJDoc;
527 }
528
529 @Override
530 public void declare (@Nonnull final IJFormatter f)
531 {
532 if (m_aJDoc != null)
533 f.generable (m_aJDoc);
534
535 if (m_aAnnotations != null)
536 for (final JAnnotationUse a : m_aAnnotations)
537 f.generable (a).newline ();
538
539 f.generable (m_aMods);
540
541
542 super.declare (f);
543
544 if (!isConstructor ())
545 f.generable (m_aReturnType);
546 f.id (m_sName).print ('(').indent ();
547
548
549 boolean first = true;
550 for (final JVar var : m_aParams)
551 {
552 if (!first)
553 f.print (',');
554 if (var.isAnnotated ())
555 f.newline ();
556 f.var (var);
557 first = false;
558 }
559 if (hasVarArgs ())
560 {
561 if (!first)
562 f.print (',');
563 for (final JAnnotationUse annotation : m_aVarParam.annotations ())
564 f.generable (annotation).newline ();
565 f.generable (m_aVarParam.mods ()).generable (m_aVarParam.type ().elementType ());
566 f.print ("... ");
567 f.id (m_aVarParam.name ());
568 }
569
570 f.outdent ().print (')');
571 if (m_aThrows != null && !m_aThrows.isEmpty ())
572 {
573 f.newline ().indent ().print ("throws").generable (m_aThrows).newline ().outdent ();
574 }
575
576 if (m_aDefaultValue != null)
577 {
578
579 f.print ("default ");
580 f.generable (m_aDefaultValue);
581 }
582 if (m_aBody != null)
583 {
584 f.statement (m_aBody);
585 }
586 else
587 {
588 final boolean bIsDeclarationOnly = (m_aOwningClass.isInterface () && !m_aMods.isDefault ()) ||
589 m_aOwningClass.isAnnotationTypeDeclaration () ||
590 m_aMods.isAbstract () ||
591 m_aMods.isNative ();
592
593 if (bIsDeclarationOnly)
594 {
595 f.print (';').newline ();
596 }
597 else
598 {
599
600 f.statement (new JBlock ());
601 }
602 }
603 }
604
605
606
607
608
609 @Nonnull
610 public JMods mods ()
611 {
612 return m_aMods;
613 }
614
615
616
617
618
619 @Nonnull
620 public JDefinedClass owningClass ()
621 {
622 return m_aOwningClass;
623 }
624
625 @Nonnull
626 public JCodeModel owner ()
627 {
628 return m_aOwningClass.owner ();
629 }
630 }