1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.dependency.analyzer.asm;
20
21 import org.junit.jupiter.api.BeforeEach;
22 import org.junit.jupiter.api.Test;
23 import org.objectweb.asm.AnnotationVisitor;
24 import org.objectweb.asm.Attribute;
25 import org.objectweb.asm.FieldVisitor;
26 import org.objectweb.asm.Label;
27 import org.objectweb.asm.MethodVisitor;
28 import org.objectweb.asm.Opcodes;
29 import org.objectweb.asm.Type;
30 import org.objectweb.asm.signature.SignatureVisitor;
31
32 import static org.assertj.core.api.Assertions.assertThat;
33
34
35
36
37
38
39 class DependencyVisitorTest {
40 private final ResultCollector resultCollector = new ResultCollector();
41 private DefaultClassVisitor visitor;
42 private MethodVisitor mv;
43
44 private String usedByClass = "com.example.MyClass";
45
46 @BeforeEach
47 void setUp() {
48 AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor(resultCollector, usedByClass);
49 SignatureVisitor signatureVisitor = new DefaultSignatureVisitor(resultCollector, usedByClass);
50 FieldVisitor fieldVisitor = new DefaultFieldVisitor(annotationVisitor, resultCollector, usedByClass);
51 mv = new DefaultMethodVisitor(annotationVisitor, signatureVisitor, resultCollector, usedByClass);
52 visitor = new DefaultClassVisitor(
53 signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector, usedByClass);
54 }
55
56 @Test
57 void testVisitWithDefaultSuperclass() {
58
59 visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", null);
60
61 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object");
62 }
63
64 @Test
65 void testVisitWithSuperclass() {
66
67 visitor.visit(50, 0, "a/b/c", null, "x/y/z", null);
68
69 assertThat(resultCollector.getDependencies()).containsOnly("x.y.z");
70 }
71
72 @Test
73 void testVisitWithInterface() {
74
75 visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", new String[] {"x/y/z"});
76
77 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
78 }
79
80 @Test
81 void testVisitWithInterfaces() {
82
83 visitor.visit(50, 0, "a/b/c", null, "java/lang/Object", new String[] {"p/q/r", "x/y/z"});
84
85 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
86 }
87
88 @Test
89 void testVisitWithUnboundedClassTypeParameter() {
90
91 String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;";
92
93 visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
94
95 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object");
96 }
97
98 @Test
99 void testVisitWithBoundedClassTypeParameter() {
100
101 String signature = "<T:Lx/y/z;>Ljava/lang/Object;";
102
103 visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
104
105 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
106 }
107
108 @Test
109 void testVisitWithBoundedClassTypeParameters() {
110
111 String signature = "<K:Lp/q/r;V:Lx/y/z;>Ljava/lang/Object;";
112
113 visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", null);
114
115 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
116 }
117
118 @Test
119 void testVisitWithGenericInterface() {
120
121 String signature = "Ljava/lang/Object;Lp/q/r<Lx/y/z;>;";
122
123 visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", new String[] {"p.q.r"});
124
125 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "p.q.r", "x.y.z");
126 }
127
128 @Test
129 void testVisitWithInterfaceBound() {
130
131 String signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;Lx/y/z<TT;>;";
132
133 visitor.visit(50, 0, "a/b/c", signature, "java/lang/Object", new String[] {"x.y.z"});
134
135 assertThat(resultCollector.getDependencies()).containsOnly("java.lang.Object", "x.y.z");
136 }
137
138
139
140 @Test
141 void testVisitSource() {
142 visitor.visitSource(null, null);
143
144 assertThat(resultCollector.getDependencies()).isEmpty();
145 }
146
147
148
149 @Test
150 void testVisitOuterClass() {
151
152
153
154
155
156
157 visitor.visitOuterClass("a/b/c", null, null);
158
159 assertThat(resultCollector.getDependencies()).isEmpty();
160 }
161
162 @Test
163 void testVisitOuterClassInMethod() {
164
165
166
167
168
169
170
171
172
173 visitor.visitOuterClass("a/b/c", "x", "(Lp/q/r;)Lx/y/z;");
174
175 assertThat(resultCollector.getDependencies()).isEmpty();
176 }
177
178
179
180 @Test
181 void testVisitAnnotation() {
182 assertVisitor(visitor.visitAnnotation("La/b/c;", false));
183
184 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
185 }
186
187 @Test
188 void testVisitAnnotationWithRuntimeVisibility() {
189 assertVisitor(visitor.visitAnnotation("La/b/c;", true));
190
191 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
192 }
193
194
195
196 @Test
197 void testVisitAttribute() {
198 visitor.visitAttribute(new MockAttribute("a"));
199
200 assertThat(resultCollector.getDependencies()).isEmpty();
201 }
202
203
204
205 @Test
206 void testVisitInnerClass() {
207
208
209
210 visitor.visitInnerClass("x/y/z", "a/b/c", "z", 0);
211
212 assertThat(resultCollector.getDependencies()).isEmpty();
213 }
214
215 @Test
216 void testVisitInnerClassAnonymous() {
217
218 visitor.visitInnerClass("x/y/z$1", "a/b/c", null, 0);
219
220 assertThat(resultCollector.getDependencies()).isEmpty();
221 }
222
223
224
225 @Test
226 void testVisitField() {
227
228 assertVisitor(visitor.visitField(0, "a", "La/b/c;", null, null));
229
230 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
231 }
232
233
234
235
236
237
238 @Test
239 void testVisitFieldArray() {
240
241 assertVisitor(visitor.visitField(0, "a", "[La/b/c;", null, null));
242
243 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
244 }
245
246 @Test
247 void testVisitFieldGeneric() {
248
249 assertVisitor(visitor.visitField(0, "a", "La/b/c;", "La/b/c<Lx/y/z;>;", null));
250
251 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
252 }
253
254
255
256 @Test
257 void testVisitMethod() {
258
259 assertVisitor(visitor.visitMethod(0, "a", "()V", null, null));
260
261 assertThat(resultCollector.getDependencies()).isEmpty();
262 }
263
264 @Test
265 void testVisitMethodWithPrimitiveArgument() {
266
267 assertVisitor(visitor.visitMethod(0, "a", "(I)V", null, null));
268
269 assertThat(resultCollector.getDependencies()).isEmpty();
270 }
271
272 @Test
273 void testVisitMethodWithPrimitiveArrayArgument() {
274
275 assertVisitor(visitor.visitMethod(0, "a", "([I)V", null, null));
276
277 assertThat(resultCollector.getDependencies()).isEmpty();
278 }
279
280 @Test
281 void testVisitMethodWithObjectArgument() {
282
283 assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;)V", null, null));
284
285 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
286 }
287
288 @Test
289 void testVisitMethodWithObjectArguments() {
290
291 assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;Lx/y/z;)V", null, null));
292
293 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
294 }
295
296 @Test
297 void testVisitMethodWithObjectArrayArgument() {
298
299 assertVisitor(visitor.visitMethod(0, "a", "([La/b/c;)V", null, null));
300
301 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
302 }
303
304 @Test
305 void testVisitMethodWithGenericArgument() {
306
307 assertVisitor(visitor.visitMethod(0, "a", "(La/b/c;)V", "(La/b/c<Lx/y/z;>;)V", null));
308
309 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
310 }
311
312 @Test
313 void testVisitMethodWithPrimitiveReturnType() {
314
315 assertVisitor(visitor.visitMethod(0, "a", "()I", null, null));
316
317 assertThat(resultCollector.getDependencies()).isEmpty();
318 }
319
320 @Test
321 void testVisitMethodWithPrimitiveArrayReturnType() {
322
323 assertVisitor(visitor.visitMethod(0, "a", "()[I", null, null));
324
325 assertThat(resultCollector.getDependencies()).isEmpty();
326 }
327
328 @Test
329 void testVisitMethodWithObjectReturnType() {
330
331 assertVisitor(visitor.visitMethod(0, "a", "()La/b/c;", null, null));
332
333 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
334 }
335
336 @Test
337 void testVisitMethodWithObjectArrayReturnType() {
338
339 assertVisitor(visitor.visitMethod(0, "a", "()[La/b/c;", null, null));
340
341 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
342 }
343
344 @Test
345 void testVisitMethodWithException() {
346
347 assertVisitor(visitor.visitMethod(0, "a", "()V", null, new String[] {"a/b/c"}));
348
349 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
350 }
351
352 @Test
353 void testVisitMethodWithExceptions() {
354
355 assertVisitor(visitor.visitMethod(0, "a", "()V", null, new String[] {"a/b/c", "x/y/z"}));
356
357 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
358 }
359
360
361
362 @Test
363 void testVisitAnnotationDefault() {
364 assertVisitor(mv.visitAnnotationDefault());
365 assertThat(resultCollector.getDependencies()).isEmpty();
366 }
367
368
369
370 @Test
371 void testVisitParameterAnnotation() {
372
373 assertVisitor(mv.visitParameterAnnotation(0, "La/b/c;", false));
374
375 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
376 }
377
378
379
380 @Test
381 void testVisitCode() {
382 mv.visitCode();
383
384 assertThat(resultCollector.getDependencies()).isEmpty();
385 }
386
387
388
389 @Test
390 void testVisitFrame() {
391 mv.visitFrame(Opcodes.F_NEW, 0, new Object[0], 0, new Object[0]);
392
393 assertThat(resultCollector.getDependencies()).isEmpty();
394 }
395
396
397
398 @Test
399 void testVisitInsn() {
400 mv.visitInsn(Opcodes.NOP);
401
402 assertThat(resultCollector.getDependencies()).isEmpty();
403 }
404
405
406
407 @Test
408 void testVisitIntInsn() {
409 mv.visitIntInsn(Opcodes.BIPUSH, 0);
410
411 assertThat(resultCollector.getDependencies()).isEmpty();
412 }
413
414
415
416 @Test
417 void testVisitVarInsn() {
418 mv.visitVarInsn(Opcodes.ILOAD, 0);
419
420 assertThat(resultCollector.getDependencies()).isEmpty();
421 }
422
423
424
425 @Test
426 void testVisitTypeInsn() {
427 mv.visitTypeInsn(Opcodes.NEW, "a/b/c");
428
429 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
430 }
431
432
433
434 @Test
435 void testVisitFieldInsnWithPrimitive() {
436 mv.visitFieldInsn(Opcodes.GETFIELD, "a/b/c", "x", "I");
437
438 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
439 }
440
441 @Test
442 void testVisitFieldInsnWithObject() {
443 mv.visitFieldInsn(Opcodes.GETFIELD, "a/b/c", "x", "Lx/y/z;");
444
445 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
446 }
447
448
449
450 @Test
451 void testVisitMethodInsn() {
452 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()V", false);
453
454 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
455 }
456
457 @Test
458 void testVisitMethodInsnWithPrimitiveArgument() {
459 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(I)V", false);
460
461 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
462 }
463
464 @Test
465 void testVisitMethodInsnWithPrimitiveArrayArgument() {
466 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([I)V", false);
467
468 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
469 }
470
471 @Test
472 void testVisitMethodInsnWithObjectArgument() {
473 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lx/y/z;)V", false);
474
475 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
476 }
477
478 @Test
479 void testVisitMethodInsnWithObjectArguments() {
480 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "(Lp/q/r;Lx/y/z;)V", false);
481
482 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
483 }
484
485 @Test
486 void testVisitMethodInsnWithObjectArrayArgument() {
487 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "([Lx/y/z;)V", false);
488
489 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
490 }
491
492 @Test
493 void testVisitMethodInsnWithPrimitiveReturnType() {
494 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()I", false);
495
496 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
497 }
498
499 @Test
500 void testVisitMethodInsnWithPrimitiveArrayReturnType() {
501 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[I", false);
502
503 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
504 }
505
506 @Test
507 void testVisitMethodInsnWithObjectReturnType() {
508 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()Lx/y/z;", false);
509
510 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
511 }
512
513 @Test
514 void testVisitMethodInsnWithObjectArrayReturnType() {
515 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "a/b/c", "x", "()[Lx/y/z;", false);
516
517 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
518 }
519
520
521
522 @Test
523 void testVisitJumpInsn() {
524 mv.visitJumpInsn(Opcodes.IFEQ, new Label());
525
526 assertThat(resultCollector.getDependencies()).isEmpty();
527 }
528
529
530
531 @Test
532 void testVisitLabel() {
533 mv.visitLabel(new Label());
534
535 assertThat(resultCollector.getDependencies()).isEmpty();
536 }
537
538
539
540 @Test
541 void testVisitLdcInsnWithNonType() {
542 mv.visitLdcInsn("a");
543
544 assertThat(resultCollector.getDependencies()).isEmpty();
545 }
546
547 @Test
548 void testVisitLdcInsnWithPrimitiveType() {
549 mv.visitLdcInsn(Type.INT_TYPE);
550
551 assertThat(resultCollector.getDependencies()).isEmpty();
552 }
553
554 @Test
555 void testVisitLdcInsnWithObjectType() {
556 mv.visitLdcInsn(Type.getType("La/b/c;"));
557
558 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
559 }
560
561
562
563 @Test
564 void testVisitIincInsn() {
565 mv.visitIincInsn(0, 1);
566
567 assertThat(resultCollector.getDependencies()).isEmpty();
568 }
569
570
571
572 @Test
573 void testVisitTableSwitchInsn() {
574 mv.visitTableSwitchInsn(0, 1, new Label(), new Label());
575
576 assertThat(resultCollector.getDependencies()).isEmpty();
577 }
578
579
580
581 @Test
582 void testVisitLookupSwitchInsn() {
583 mv.visitLookupSwitchInsn(new Label(), new int[] {0}, new Label[] {new Label()});
584
585 assertThat(resultCollector.getDependencies()).isEmpty();
586 }
587
588
589
590 @Test
591 void testVisitMultiANewArrayInsnWithPrimitive() {
592 mv.visitMultiANewArrayInsn("I", 2);
593
594 assertThat(resultCollector.getDependencies()).isEmpty();
595 }
596
597 @Test
598 void testVisitMultiANewArrayInsnWithObject() {
599 mv.visitMultiANewArrayInsn("La/b/c;", 2);
600
601 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
602 }
603
604
605
606 @Test
607 void testVisitTryCatchBlock() {
608 mv.visitTryCatchBlock(new Label(), new Label(), new Label(), "a/b/c");
609
610 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
611 }
612
613 @Test
614 void testVisitTryCatchBlockForFinally() {
615 mv.visitTryCatchBlock(new Label(), new Label(), new Label(), null);
616
617 assertThat(resultCollector.getDependencies()).isEmpty();
618 }
619
620
621
622 @Test
623 void testVisitLocalVariableWithPrimitive() {
624 mv.visitLocalVariable("a", "I", null, new Label(), new Label(), 0);
625
626 assertThat(resultCollector.getDependencies()).isEmpty();
627 }
628
629 @Test
630 void testVisitLocalVariableWithPrimitiveArray() {
631 mv.visitLocalVariable("a", "[I", null, new Label(), new Label(), 0);
632
633 assertThat(resultCollector.getDependencies()).isEmpty();
634 }
635
636 @Test
637 void testVisitLocalVariableWithObject() {
638 mv.visitLocalVariable("a", "La/b/c;", null, new Label(), new Label(), 0);
639
640 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
641 }
642
643 @Test
644 void testVisitLocalVariableWithObjectArray() {
645 mv.visitLocalVariable("a", "[La/b/c;", null, new Label(), new Label(), 0);
646
647 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c");
648 }
649
650 @Test
651 void testVisitLocalVariableWithGenericObject() {
652 mv.visitLocalVariable("a", "La/b/c;", "La/b/c<Lx/y/z;>;", new Label(), new Label(), 0);
653
654 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
655 }
656
657 @Test
658 void testVisitLocalVariableWithGenericObjectArray() {
659 mv.visitLocalVariable("a", "La/b/c;", "[La/b/c<Lx/y/z;>;", new Label(), new Label(), 0);
660
661 assertThat(resultCollector.getDependencies()).containsOnly("a.b.c", "x.y.z");
662 }
663
664
665
666 @Test
667 void testVisitLineNumber() {
668 mv.visitLineNumber(0, new Label());
669
670 assertThat(resultCollector.getDependencies()).isEmpty();
671 }
672
673
674
675 @Test
676 void testVisitMaxs() {
677 mv.visitMaxs(0, 0);
678
679 assertThat(resultCollector.getDependencies()).isEmpty();
680 }
681
682
683 @Test
684 void testVisitInvokeDynamic() {
685 Type type = Type.getType("(La/b/C;)V");
686 mv.visitInvokeDynamicInsn("a", "", null, type);
687 assertThat(resultCollector.getDependencies()).contains("a.b.C");
688 }
689
690 private void assertVisitor(Object actualVisitor) {
691
692 }
693
694
695
696
697
698
699 static class MockAttribute extends Attribute {
700 MockAttribute(String type) {
701 super(type);
702 }
703 }
704 }