1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.classfile.visitor;
22
23import proguard.classfile.*;
24import proguard.classfile.attribute.*;
25import proguard.classfile.attribute.annotation.*;
26import proguard.classfile.attribute.annotation.visitor.*;
27import proguard.classfile.attribute.visitor.*;
28import proguard.classfile.constant.*;
29import proguard.classfile.constant.visitor.ConstantVisitor;
30import proguard.classfile.util.SimplifiedVisitor;
31
32/**
33 * This ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor, etc.
34 * lets a given ClassVisitor visit all the referenced classes of the elements
35 * that it visits. Only downstream elements are considered (in order to avoid
36 * loops and repeated visits).
37 *
38 * @author Eric Lafortune
39 */
40public class ReferencedClassVisitor
41extends      SimplifiedVisitor
42implements   ClassVisitor,
43             MemberVisitor,
44             ConstantVisitor,
45             AttributeVisitor,
46             LocalVariableInfoVisitor,
47             LocalVariableTypeInfoVisitor,
48             AnnotationVisitor,
49             ElementValueVisitor
50{
51    protected final ClassVisitor classVisitor;
52
53
54    public ReferencedClassVisitor(ClassVisitor classVisitor)
55    {
56        this.classVisitor = classVisitor;
57    }
58
59
60    // Implementations for ClassVisitor.
61
62    public void visitProgramClass(ProgramClass programClass)
63    {
64        // Visit the constant pool entries.
65        programClass.constantPoolEntriesAccept(this);
66
67        // Visit the fields and methods.
68        programClass.fieldsAccept(this);
69        programClass.methodsAccept(this);
70
71        // Visit the attributes.
72        programClass.attributesAccept(this);
73    }
74
75
76    public void visitLibraryClass(LibraryClass libraryClass)
77    {
78        // Visit the superclass and interfaces.
79        libraryClass.superClassAccept(classVisitor);
80        libraryClass.interfacesAccept(classVisitor);
81
82        // Visit the fields and methods.
83        libraryClass.fieldsAccept(this);
84        libraryClass.methodsAccept(this);
85    }
86
87
88    // Implementations for MemberVisitor.
89
90    public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
91    {
92        // Let the visitor visit the classes referenced in the descriptor string.
93        programMember.referencedClassesAccept(classVisitor);
94
95        // Visit the attributes.
96        programMember.attributesAccept(programClass, this);
97    }
98
99
100    public void visitLibraryMember(LibraryClass programClass, LibraryMember libraryMember)
101    {
102        // Let the visitor visit the classes referenced in the descriptor string.
103        libraryMember.referencedClassesAccept(classVisitor);
104    }
105
106
107    // Implementations for ConstantVisitor.
108
109    public void visitAnyConstant(Clazz clazz, Constant constant) {}
110
111
112    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
113    {
114        // Let the visitor visit the class referenced in the string constant.
115        stringConstant.referencedClassAccept(classVisitor);
116    }
117
118
119    public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
120    {
121        // Let the visitor visit the class referenced in the reference constant.
122        refConstant.referencedClassAccept(classVisitor);
123    }
124
125
126    public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
127    {
128        // Let the visitor visit the class referenced in the reference constant.
129        invokeDynamicConstant.referencedClassesAccept(classVisitor);
130    }
131
132
133    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
134    {
135        // Let the visitor visit the class referenced in the class constant.
136        classConstant.referencedClassAccept(classVisitor);
137    }
138
139
140    public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
141    {
142        // Let the visitor visit the classes referenced in the method type constant.
143        methodTypeConstant.referencedClassesAccept(classVisitor);
144    }
145
146
147    // Implementations for AttributeVisitor.
148
149    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
150
151
152    public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
153    {
154        // Let the visitor visit the class of the enclosing method.
155        enclosingMethodAttribute.referencedClassAccept(classVisitor);
156    }
157
158
159    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
160    {
161        // Visit the attributes of the code attribute.
162        codeAttribute.attributesAccept(clazz, method, this);
163    }
164
165
166    public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
167    {
168        // Visit the local variables.
169        localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
170    }
171
172
173    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
174    {
175        // Visit the local variable types.
176        localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
177    }
178
179
180    public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
181    {
182        // Let the visitor visit the classes referenced in the signature string.
183        signatureAttribute.referencedClassesAccept(classVisitor);
184    }
185
186
187    public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
188    {
189        // Visit the annotations.
190        annotationsAttribute.annotationsAccept(clazz, this);
191    }
192
193
194    public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
195    {
196        // Visit the parameter annotations.
197        parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
198    }
199
200
201    public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
202    {
203        // Visit the default element value.
204        annotationDefaultAttribute.defaultValueAccept(clazz, this);
205    }
206
207
208    // Implementations for LocalVariableInfoVisitor.
209
210    public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
211    {
212        // Let the visitor visit the class referenced in the local variable.
213        localVariableInfo.referencedClassAccept(classVisitor);
214    }
215
216
217    // Implementations for LocalVariableTypeInfoVisitor.
218
219    public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
220    {
221        // Let the visitor visit the classes referenced in the local variable type.
222        localVariableTypeInfo.referencedClassesAccept(classVisitor);
223    }
224
225
226    // Implementations for AnnotationVisitor.
227
228    public void visitAnnotation(Clazz clazz, Annotation annotation)
229    {
230        // Let the visitor visit the classes referenced in the annotation.
231        annotation.referencedClassesAccept(classVisitor);
232
233        // Visit the element values.
234        annotation.elementValuesAccept(clazz, this);
235    }
236
237
238    // Implementations for ElementValueVisitor.
239
240    public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {}
241
242
243    public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
244    {
245        // Let the visitor visit the classes referenced in the constant element value.
246        enumConstantElementValue.referencedClassesAccept(classVisitor);
247    }
248
249
250    public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
251    {
252        // Let the visitor visit the classes referenced in the class element value.
253        classElementValue.referencedClassesAccept(classVisitor);
254    }
255
256
257    public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
258    {
259        // Visit the contained annotation.
260        annotationElementValue.annotationAccept(clazz, this);
261    }
262
263
264    public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
265    {
266        // Visit the element values.
267        arrayElementValue.elementValuesAccept(clazz, annotation, this);
268    }
269}
270