View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.dependency.analyzer.asm;
20  
21  import org.objectweb.asm.AnnotationVisitor;
22  import org.objectweb.asm.ClassVisitor;
23  import org.objectweb.asm.FieldVisitor;
24  import org.objectweb.asm.MethodVisitor;
25  import org.objectweb.asm.Opcodes;
26  import org.objectweb.asm.Type;
27  import org.objectweb.asm.signature.SignatureReader;
28  import org.objectweb.asm.signature.SignatureVisitor;
29  
30  /**
31   * Computes the set of classes referenced by visited code.
32   * Inspired by <code>org.objectweb.asm.depend.DependencyVisitor</code> in the ASM dependencies example.
33   *
34   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
35   */
36  public class DefaultClassVisitor extends ClassVisitor {
37      private final ResultCollector resultCollector;
38  
39      private final SignatureVisitor signatureVisitor;
40  
41      private final AnnotationVisitor annotationVisitor;
42  
43      private final FieldVisitor fieldVisitor;
44  
45      private final MethodVisitor methodVisitor;
46  
47      private final String usedByClass;
48  
49      /**
50       * <p>Constructor for DefaultClassVisitor.</p>
51       *
52       * @param signatureVisitor a {@link org.objectweb.asm.signature.SignatureVisitor} object.
53       * @param annotationVisitor a {@link org.objectweb.asm.AnnotationVisitor} object.
54       * @param fieldVisitor a {@link org.objectweb.asm.FieldVisitor} object.
55       * @param methodVisitor a {@link org.objectweb.asm.MethodVisitor} object.
56       * @param resultCollector a {@link org.apache.maven.shared.dependency.analyzer.asm.ResultCollector} object.
57       */
58      public DefaultClassVisitor(
59              SignatureVisitor signatureVisitor,
60              AnnotationVisitor annotationVisitor,
61              FieldVisitor fieldVisitor,
62              MethodVisitor methodVisitor,
63              ResultCollector resultCollector,
64              String usedByClass) {
65          super(Opcodes.ASM9);
66          this.signatureVisitor = signatureVisitor;
67          this.annotationVisitor = annotationVisitor;
68          this.fieldVisitor = fieldVisitor;
69          this.methodVisitor = methodVisitor;
70          this.resultCollector = resultCollector;
71          this.usedByClass = usedByClass;
72      }
73  
74      /**
75       * <p>visit.</p>
76       *
77       * @param version a int.
78       * @param access a int.
79       * @param name a {@link java.lang.String} object.
80       * @param signature a {@link java.lang.String} object.
81       * @param superName a {@link java.lang.String} object.
82       * @param interfaces an array of {@link java.lang.String} objects.
83       */
84      @Override
85      public void visit(
86              final int version,
87              final int access,
88              final String name,
89              final String signature,
90              final String superName,
91              final String[] interfaces) {
92          if (signature == null) {
93              resultCollector.addName(usedByClass, superName);
94              resultCollector.addNames(usedByClass, interfaces);
95          } else {
96              addSignature(signature);
97          }
98      }
99  
100     /** {@inheritDoc} */
101     @Override
102     public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
103         resultCollector.addDesc(usedByClass, desc);
104 
105         return annotationVisitor;
106     }
107 
108     /** {@inheritDoc} */
109     @Override
110     public FieldVisitor visitField(
111             final int access, final String name, final String desc, final String signature, final Object value) {
112         if (signature == null) {
113             resultCollector.addDesc(usedByClass, desc);
114         } else {
115             addTypeSignature(signature);
116         }
117 
118         if (value instanceof Type) {
119             resultCollector.addType(usedByClass, (Type) value);
120         }
121 
122         return fieldVisitor;
123     }
124 
125     /**
126      * <p>visitMethod.</p>
127      *
128      * @param access a int.
129      * @param name a {@link java.lang.String} object.
130      * @param desc a {@link java.lang.String} object.
131      * @param signature a {@link java.lang.String} object.
132      * @param exceptions an array of {@link java.lang.String} objects.
133      * @return a {@link org.objectweb.asm.MethodVisitor} object.
134      */
135     @Override
136     public MethodVisitor visitMethod(
137             final int access, final String name, final String desc, final String signature, final String[] exceptions) {
138         if (signature == null) {
139             resultCollector.addMethodDesc(usedByClass, desc);
140         } else {
141             addSignature(signature);
142         }
143 
144         resultCollector.addNames(usedByClass, exceptions);
145 
146         return methodVisitor;
147     }
148 
149     /** {@inheritDoc} */
150     @Override
151     public void visitNestHost(final String nestHost) {
152         resultCollector.addName(usedByClass, nestHost);
153     }
154 
155     /** {@inheritDoc} */
156     @Override
157     public void visitNestMember(final String nestMember) {
158         resultCollector.addName(usedByClass, nestMember);
159     }
160 
161     private void addSignature(final String signature) {
162         if (signature != null) {
163             new SignatureReader(signature).accept(signatureVisitor);
164         }
165     }
166 
167     private void addTypeSignature(final String signature) {
168         if (signature != null) {
169             new SignatureReader(signature).acceptType(signatureVisitor);
170         }
171     }
172 }