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