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