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 }