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 static com.helger.jcodemodel.util.JCEqualsHelper.isEqual;
44
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.List;
48
49 import javax.annotation.Nonnull;
50 import javax.annotation.Nullable;
51
52 import com.helger.jcodemodel.util.JCHashCodeGenerator;
53
54
55
56
57 public class JInvocation extends AbstractJExpressionImpl implements IJStatement, IJOwnedMaybe
58 {
59 private final JCodeModel m_aOwner;
60
61
62
63
64
65 private final IJGenerable m_aObject;
66
67
68
69
70
71
72
73 private final String m_sMethodName;
74
75 private final JMethod m_sMethod;
76
77 private final boolean m_bIsConstructor;
78
79
80
81
82 private final List <IJExpression> _args = new ArrayList <IJExpression> ();
83
84
85
86
87 private final AbstractJType m_aConstructorType;
88
89
90
91
92 private List <JTypeVar> _typeVariables;
93
94
95
96
97
98
99
100
101
102
103 protected JInvocation (@Nullable final IJExpression object, @Nonnull final String name)
104 {
105
106 this (null, object, name);
107 }
108
109 protected JInvocation (@Nullable final IJExpression object, @Nonnull final JMethod method)
110 {
111 this (method.owner (), object, method);
112 }
113
114
115
116
117
118
119
120
121
122 protected JInvocation (@Nonnull final AbstractJClass aType, @Nonnull final String sMethodName)
123 {
124 this (aType.owner (), aType, sMethodName);
125 }
126
127
128
129
130
131
132
133
134
135 protected JInvocation (@Nonnull final AbstractJClass aType, @Nonnull final JMethod aMethod)
136 {
137 this (aType.owner (), aType, aMethod);
138 }
139
140 private JInvocation (@Nullable final JCodeModel owner, @Nullable final IJGenerable object, @Nonnull final String sName)
141 {
142 if (sName.indexOf ('.') >= 0)
143 throw new IllegalArgumentException ("method name contains '.': " + sName);
144 m_aOwner = owner;
145 m_aObject = object;
146 m_sMethodName = sName;
147 m_sMethod = null;
148 m_bIsConstructor = false;
149 m_aConstructorType = null;
150 }
151
152 private JInvocation (@Nonnull final JCodeModel owner,
153 @Nullable final IJGenerable object,
154 @Nonnull final JMethod method)
155 {
156 m_aOwner = owner;
157 m_aObject = object;
158 m_sMethodName = null;
159 m_sMethod = method;
160 m_bIsConstructor = false;
161 m_aConstructorType = null;
162 }
163
164
165
166
167
168
169
170
171
172 protected JInvocation (@Nonnull final AbstractJType aConstructorType)
173 {
174 m_aOwner = aConstructorType.owner ();
175 m_aObject = null;
176 m_sMethodName = null;
177 m_sMethod = null;
178 m_bIsConstructor = true;
179 m_aConstructorType = aConstructorType;
180 }
181
182 @Nullable
183 public JCodeModel owner ()
184 {
185 return m_aOwner;
186 }
187
188 public boolean isConstructor ()
189 {
190 return m_bIsConstructor;
191 }
192
193
194
195
196
197
198
199
200 @Nonnull
201 public JInvocation arg (@Nonnull final IJExpression arg)
202 {
203 if (arg == null)
204 throw new IllegalArgumentException ("argument may not be null");
205 _args.add (arg);
206 return this;
207 }
208
209
210
211
212
213
214
215
216 @Nonnull
217 public JInvocation arg (@Nonnull final boolean v)
218 {
219 return arg (JExpr.lit (v));
220 }
221
222
223
224
225
226
227
228
229 @Nonnull
230 public JInvocation arg (@Nonnull final char v)
231 {
232 return arg (JExpr.lit (v));
233 }
234
235
236
237
238
239
240
241
242 @Nonnull
243 public JInvocation arg (@Nonnull final double v)
244 {
245 return arg (JExpr.lit (v));
246 }
247
248
249
250
251
252
253
254
255 @Nonnull
256 public JInvocation arg (@Nonnull final float v)
257 {
258 return arg (JExpr.lit (v));
259 }
260
261
262
263
264
265
266
267
268 @Nonnull
269 public JInvocation arg (@Nonnull final int v)
270 {
271 return arg (JExpr.lit (v));
272 }
273
274
275
276
277
278
279
280
281 @Nonnull
282 public JInvocation arg (@Nonnull final long v)
283 {
284 return arg (JExpr.lit (v));
285 }
286
287
288
289
290
291
292
293
294 @Nonnull
295 public JInvocation arg (@Nonnull final String v)
296 {
297 return arg (JExpr.lit (v));
298 }
299
300
301
302
303
304
305 @Nonnull
306 public IJExpression [] listArgs ()
307 {
308 return _args.toArray (new IJExpression [_args.size ()]);
309 }
310
311
312
313
314
315
316 @Nonnull
317 public List <IJExpression> args ()
318 {
319 return new ArrayList <IJExpression> (_args);
320 }
321
322 @Nonnull
323 private JCodeModel _narrowOwner ()
324 {
325 final JCodeModel owner = owner ();
326 if (owner == null)
327 throw new IllegalStateException ("No owner is present, so this invocation cannot be generified!");
328 return owner;
329 }
330
331 @Nonnull
332 public JInvocation narrow (@Nonnull final String name)
333 {
334 final JTypeVar v = new JTypeVar (_narrowOwner (), name);
335 if (_typeVariables == null)
336 _typeVariables = new ArrayList <JTypeVar> (3);
337 _typeVariables.add (v);
338 return this;
339 }
340
341 @Nonnull
342 public JInvocation narrow (@Nonnull final Class <?> bound)
343 {
344 return narrow (_narrowOwner ().ref (bound));
345 }
346
347 @Nonnull
348 public JInvocation narrow (@Nonnull final AbstractJClass bound)
349 {
350 final JTypeVar v = new JTypeVarClass (bound);
351 if (_typeVariables == null)
352 _typeVariables = new ArrayList <JTypeVar> (3);
353 _typeVariables.add (v);
354 return this;
355 }
356
357 @Nonnull
358 public List <JTypeVar> typeParamList ()
359 {
360 if (_typeVariables == null)
361 return Collections.<JTypeVar> emptyList ();
362 return new ArrayList <JTypeVar> (_typeVariables);
363 }
364
365 private void _addTypeVars (@Nonnull final JFormatter f)
366 {
367 if (_typeVariables != null && !_typeVariables.isEmpty ())
368 {
369 f.print ('<');
370 int nIndex = 0;
371 for (final JTypeVar aTypeVar : _typeVariables)
372 {
373 if (nIndex++ > 0)
374 f.print (',');
375
376 f.type (aTypeVar);
377 }
378 f.print (JFormatter.CLOSE_TYPE_ARGS);
379 }
380 }
381
382 private String methodName ()
383 {
384 return m_sMethodName != null ? m_sMethodName : m_sMethod.name ();
385 }
386
387 public void generate (@Nonnull final JFormatter f)
388 {
389 if (m_bIsConstructor)
390 {
391 if (m_aConstructorType.isArray ())
392 {
393
394 f.print ("new").generable (m_aConstructorType);
395 _addTypeVars (f);
396 f.print ('{');
397 }
398 else
399 {
400
401 f.print ("new").generable (m_aConstructorType);
402 _addTypeVars (f);
403 f.print ('(');
404 }
405 }
406 else
407 {
408 final String name = methodName ();
409
410 if (m_aObject != null)
411 {
412
413 f.generable (m_aObject).print ('.');
414 _addTypeVars (f);
415 f.print (name).print ('(');
416 }
417 else
418 {
419
420 f.id (name).print ('(');
421 }
422 }
423
424
425 f.generable (_args);
426
427
428 if (m_bIsConstructor && m_aConstructorType.isArray ())
429 f.print ('}');
430 else
431 f.print (')');
432
433 if (m_aConstructorType instanceof JDefinedClass && ((JDefinedClass) m_aConstructorType).isAnonymous ())
434 {
435 ((JAnonymousClass) m_aConstructorType).declareBody (f);
436 }
437 }
438
439 public void state (@Nonnull final JFormatter f)
440 {
441 f.generable (this).print (';').newline ();
442 }
443
444 private String typeFullName ()
445 {
446 return m_aConstructorType != null ? m_aConstructorType.fullName () : "";
447 }
448
449 @Override
450 public boolean equals (final Object o)
451 {
452 if (o == this)
453 return true;
454 if (o == null || getClass () != o.getClass ())
455 return false;
456 final JInvocation rhs = (JInvocation) o;
457 if (!(isEqual (m_aObject, rhs.m_aObject) &&
458 isEqual (m_bIsConstructor, rhs.m_bIsConstructor) &&
459 (m_bIsConstructor || isEqual (methodName (), rhs.methodName ())) &&
460 isEqual (_args, rhs._args) &&
461 isEqual (typeFullName (), rhs.typeFullName ())))
462 {
463 return false;
464 }
465 if (_typeVariables == null)
466 return rhs._typeVariables == null;
467 if (rhs._typeVariables == null)
468 return false;
469 if (_typeVariables.size () != rhs._typeVariables.size ())
470 return false;
471 for (int i = 0; i < _typeVariables.size (); i++)
472 {
473 if (!isEqual (_typeVariables.get (i).fullName (), rhs._typeVariables.get (i).fullName ()))
474 return false;
475 }
476 return true;
477 }
478
479 @Override
480 public int hashCode ()
481 {
482 JCHashCodeGenerator hashCodeGenerator = new JCHashCodeGenerator (this).append (m_aObject).append (m_bIsConstructor);
483 if (!m_bIsConstructor)
484 hashCodeGenerator = hashCodeGenerator.append (methodName ());
485 hashCodeGenerator = hashCodeGenerator.append (_args).append (typeFullName ());
486 if (_typeVariables != null)
487 {
488 hashCodeGenerator = hashCodeGenerator.append (_typeVariables.size ());
489 for (final JTypeVar typeVariable : _typeVariables)
490 {
491 hashCodeGenerator = hashCodeGenerator.append (typeVariable.fullName ());
492 }
493 }
494 return hashCodeGenerator.getHashCode ();
495 }
496 }