1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it
8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free
9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option)
10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version.
11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT
13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details.
16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along
18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc.,
19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.classfile.util;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.*;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.annotation.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.annotation.visitor.*;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.*;
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.*;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor;
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This ClassVisitor initializes the references of all classes that
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * it visits.
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * All class constant pool entries get direct references to the corresponding
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * classes. These references make it more convenient to travel up and across
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * the class hierarchy.
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * All field and method reference constant pool entries get direct references
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * to the corresponding classes, fields, and methods.
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * All name and type constant pool entries get a list of direct references to
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * the classes listed in the type.
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This visitor optionally prints warnings if some items can't be found.
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * The class hierarchy must be initialized before using this visitor.
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ClassReferenceInitializer
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends      SimplifiedVisitor
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements   ClassVisitor,
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             MemberVisitor,
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             ConstantVisitor,
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             AttributeVisitor,
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             LocalVariableInfoVisitor,
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             LocalVariableTypeInfoVisitor,
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             AnnotationVisitor,
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             ElementValueVisitor
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final ClassPool      programClassPool;
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final ClassPool      libraryClassPool;
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final WarningPrinter missingClassWarningPrinter;
67b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    private final WarningPrinter missingProgramMemberWarningPrinter;
68b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    private final WarningPrinter missingLibraryMemberWarningPrinter;
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final WarningPrinter dependencyWarningPrinter;
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final MemberFinder memberFinder = new MemberFinder();
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new ClassReferenceInitializer that initializes the references
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * of all visited class files, optionally printing warnings if some classes
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * or class members can't be found or if they are in the program class pool.
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ClassReferenceInitializer(ClassPool      programClassPool,
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                     ClassPool      libraryClassPool,
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                     WarningPrinter missingClassWarningPrinter,
82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                     WarningPrinter missingProgramMemberWarningPrinter,
83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                     WarningPrinter missingLibraryMemberWarningPrinter,
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                     WarningPrinter dependencyWarningPrinter)
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.programClassPool                   = programClassPool;
87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.libraryClassPool                   = libraryClassPool;
88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.missingClassWarningPrinter         = missingClassWarningPrinter;
89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.missingProgramMemberWarningPrinter = missingProgramMemberWarningPrinter;
90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.missingLibraryMemberWarningPrinter = missingLibraryMemberWarningPrinter;
91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.dependencyWarningPrinter           = dependencyWarningPrinter;
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ClassVisitor.
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramClass(ProgramClass programClass)
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the constant pool entries.
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.constantPoolEntriesAccept(this);
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize all fields and methods.
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.fieldsAccept(this);
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.methodsAccept(this);
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the attributes.
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.attributesAccept(this);
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryClass(LibraryClass libraryClass)
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize all fields and methods.
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClass.fieldsAccept(this);
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClass.methodsAccept(this);
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for MemberVisitor.
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramField(ProgramClass programClass, ProgramField programField)
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programField.referencedClass =
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClass(programClass.getName(),
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                programField.getDescriptor(programClass));
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the attributes.
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programField.attributesAccept(programClass, this);
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programMethod.referencedClasses =
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(programClass.getName(),
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  programMethod.getDescriptor(programClass));
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the attributes.
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programMethod.attributesAccept(programClass, this);
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryField.referencedClass =
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClass(libraryClass.getName(),
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                libraryField.getDescriptor(libraryClass));
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryMethod.referencedClasses =
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(libraryClass.getName(),
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  libraryMethod.getDescriptor(libraryClass));
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ConstantVisitor.
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyConstant(Clazz clazz, Constant constant) {}
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Fill out the String class.
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        stringConstant.javaLangStringClass =
1682270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_STRING);
1692270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    }
1702270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
1712270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
1722270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
1732270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    {
1742270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        invokeDynamicConstant.referencedClasses =
1752270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findReferencedClasses(clazz.getName(),
1762270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  invokeDynamicConstant.getType(clazz));
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
180b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
181b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
182b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Fill out the MethodHandle class.
183b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        methodHandleConstant.javaLangInvokeMethodHandleClass =
1842270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_HANDLE);
185b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
186b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
187b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String className = refConstant.getClassName(clazz);
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
192b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Methods for array types should be found in the Object class.
193b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (ClassUtil.isInternalArrayType(className))
194b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
1952270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            className = ClassConstants.NAME_JAVA_LANG_OBJECT;
196b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
197b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // See if we can find the referenced class.
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Unresolved references are assumed to refer to library classes
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // that will not change anyway.
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz referencedClass = findClass(clazz.getName(), className);
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
203b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (referencedClass != null)
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String name = refConstant.getName(clazz);
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String type = refConstant.getType(clazz);
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            boolean isFieldRef = refConstant.getTag() == ClassConstants.CONSTANT_Fieldref;
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // See if we can find the referenced class member somewhere in the
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // hierarchy.
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            refConstant.referencedMember = memberFinder.findMember(clazz,
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                                   referencedClass,
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                                   name,
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                                   type,
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                                   isFieldRef);
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            refConstant.referencedClass  = memberFinder.correspondingClass();
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (refConstant.referencedMember == null)
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
221b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                // We haven't found the class member anywhere in the hierarchy.
222b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                boolean isProgramClass = referencedClass instanceof ProgramClass;
223b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
224b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                WarningPrinter missingMemberWarningPrinter = isProgramClass ?
225b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                    missingProgramMemberWarningPrinter :
226b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                    missingLibraryMemberWarningPrinter;
227b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                missingMemberWarningPrinter.print(clazz.getName(),
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  className,
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  "Warning: " +
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  ClassUtil.externalClassName(clazz.getName()) +
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  ": can't find referenced " +
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  (isFieldRef ?
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      "field '"  + ClassUtil.externalFullFieldDescription(0, name, type) :
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      "method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) +
236b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                  "' in " +
237b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                  (isProgramClass ?
238b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                      "program" :
239b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                      "library") +
240b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                  " class " +
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  ClassUtil.externalClassName(className));
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String className = clazz.getName();
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Fill out the referenced class.
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        classConstant.referencedClass =
253b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz)));
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Fill out the Class class.
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        classConstant.javaLangClassClass =
2572270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findClass(className, ClassConstants.NAME_JAVA_LANG_CLASS);
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
261b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
262b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
263b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Fill out the MethodType class.
264b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        methodTypeConstant.javaLangInvokeMethodTypeClass =
2652270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_TYPE);
2662270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
2672270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        methodTypeConstant.referencedClasses =
2682270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            findReferencedClasses(clazz.getName(),
2692270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  methodTypeConstant.getType(clazz));
270b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
271b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
272b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for AttributeVisitor.
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String className          = clazz.getName();
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String enclosingClassName = enclosingMethodAttribute.getClassName(clazz);
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // See if we can find the referenced class.
284b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        enclosingMethodAttribute.referencedClass =
285b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            findClass(className, enclosingClassName);
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
287b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (enclosingMethodAttribute.referencedClass != null)
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
289b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            // Is there an enclosing method? Otherwise it's just initialization
290b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            // code outside of the constructors.
291b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
292b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
293b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                String name = enclosingMethodAttribute.getName(clazz);
294b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                String type = enclosingMethodAttribute.getType(clazz);
2959f606f95f03a75961498803e24bee6799a7c0885Ying Wang
296b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                // See if we can find the method in the referenced class.
297b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                enclosingMethodAttribute.referencedMethod =
298b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                    enclosingMethodAttribute.referencedClass.findMethod(name, type);
2999f606f95f03a75961498803e24bee6799a7c0885Ying Wang
300b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                if (enclosingMethodAttribute.referencedMethod == null)
301b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                {
302b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                    // We couldn't find the enclosing method.
303b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                    missingProgramMemberWarningPrinter.print(className,
304b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             enclosingClassName,
305b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             "Warning: " +
306b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             ClassUtil.externalClassName(className) +
307b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             ": can't find enclosing method '" +
308b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) +
309b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             "' in program class " +
310b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                             ClassUtil.externalClassName(enclosingClassName));
311b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                }
312b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the nested attributes.
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        codeAttribute.attributesAccept(clazz, method, this);
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the local variables.
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the local variable types.
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        signatureAttribute.referencedClasses =
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(clazz.getName(),
3422270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  signatureAttribute.getSignature(clazz));
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the annotations.
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationsAttribute.annotationsAccept(clazz, this);
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the annotations.
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the annotation.
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationDefaultAttribute.defaultValueAccept(clazz, this);
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for LocalVariableInfoVisitor.
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableInfo.referencedClass =
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClass(clazz.getName(),
3732270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                localVariableInfo.getDescriptor(clazz));
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for LocalVariableTypeInfoVisitor.
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableTypeInfo.referencedClasses =
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(clazz.getName(),
3832270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  localVariableTypeInfo.getSignature(clazz));
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for AnnotationVisitor.
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotation(Clazz clazz, Annotation annotation)
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotation.referencedClasses =
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(clazz.getName(),
3932270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  annotation.getType(clazz));
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the element values.
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotation.elementValuesAccept(clazz, this);
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ElementValueVisitor.
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initializeElementValue(clazz, annotation, constantElementValue);
405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initializeElementValue(clazz, annotation, enumConstantElementValue);
411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        enumConstantElementValue.referencedClasses =
413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(clazz.getName(),
4142270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  enumConstantElementValue.getTypeName(clazz));
415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initializeElementValue(clazz, annotation, classElementValue);
421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        classElementValue.referencedClasses =
423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findReferencedClasses(clazz.getName(),
4242270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                  classElementValue.getClassName(clazz));
425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
429b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
430b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initializeElementValue(clazz, annotation, annotationElementValue);
431b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
432b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the annotation.
433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationElementValue.annotationAccept(clazz, this);
434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initializeElementValue(clazz, annotation, arrayElementValue);
440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the element values.
442b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        arrayElementValue.elementValuesAccept(clazz, annotation, this);
443b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
444b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
445b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
446b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
447b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Initializes the referenced method of an element value, if any.
448b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
449b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void initializeElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
450b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
451b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // See if we have a referenced class.
452b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (annotation                      != null &&
453b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            annotation.referencedClasses    != null &&
454b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            elementValue.u2elementNameIndex != 0)
455b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
456b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // See if we can find the method in the referenced class
457b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // (ignoring the descriptor).
4582270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            String name = elementValue.getMethodName(clazz);
459b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
460b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Clazz referencedClass = annotation.referencedClasses[0];
461b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            elementValue.referencedClass  = referencedClass;
462b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            elementValue.referencedMethod = referencedClass.findMethod(name, null);
463b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
464b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
465b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
466b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
467b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
468b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
469b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
470b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the single class referenced by the given descriptor, or
471b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * <code>null</code> if there isn't any useful reference.
472b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
473b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz findReferencedClass(String referencingClassName,
474b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      String descriptor)
475b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
476b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        DescriptorClassEnumeration enumeration =
477b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new DescriptorClassEnumeration(descriptor);
478b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
479b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        enumeration.nextFluff();
480b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
481b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (enumeration.hasMoreClassNames())
482b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
483b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return findClass(referencingClassName, enumeration.nextClassName());
484b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
485b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
486b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return null;
487b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
488b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
489b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
490b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
491b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns an array of classes referenced by the given descriptor, or
492b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * <code>null</code> if there aren't any useful references.
493b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
494b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz[] findReferencedClasses(String referencingClassName,
495b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          String descriptor)
496b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
497b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        DescriptorClassEnumeration enumeration =
498b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new DescriptorClassEnumeration(descriptor);
499b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
500b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int classCount = enumeration.classCount();
501b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (classCount > 0)
502b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
503b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Clazz[] referencedClasses = new Clazz[classCount];
504b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
505b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            boolean foundReferencedClasses = false;
506b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
507b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < classCount; index++)
508b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
509b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                String fluff = enumeration.nextFluff();
510b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                String name  = enumeration.nextClassName();
511b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
512b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                Clazz referencedClass = findClass(referencingClassName, name);
513b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
514b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (referencedClass != null)
515b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
516b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    referencedClasses[index] = referencedClass;
517b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    foundReferencedClasses = true;
518b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
519b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
520b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
521b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (foundReferencedClasses)
522b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
523b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return referencedClasses;
524b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
525b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
526b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
527b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return null;
528b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
529b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
530b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
531b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
532b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the class with the given name, either for the program class pool
533b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * or from the library class pool, or <code>null</code> if it can't be found.
534b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
535b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz findClass(String referencingClassName, String name)
536b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
537b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Is it an array type?
538b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (ClassUtil.isInternalArrayType(name))
539b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
540b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            // Ignore any primitive array types.
541b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (!ClassUtil.isInternalClassType(name))
542b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
543b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                return null;
544b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
545b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
546b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            // Strip the array part.
547b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            name = ClassUtil.internalClassNameFromClassType(name);
548b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
549b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
550b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // First look for the class in the program class pool.
551b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz clazz = programClassPool.getClass(name);
552b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
553b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Otherwise look for the class in the library class pool.
554b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (clazz == null)
555b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
556b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            clazz = libraryClassPool.getClass(name);
557b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
558b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (clazz == null &&
559b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                missingClassWarningPrinter != null)
560b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
561b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // We didn't find the superclass or interface. Print a warning.
562b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                missingClassWarningPrinter.print(referencingClassName,
563b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 name,
564b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 "Warning: " +
565b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 ClassUtil.externalClassName(referencingClassName) +
566b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 ": can't find referenced class " +
567b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 ClassUtil.externalClassName(name));
568b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
569b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
570b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        else if (dependencyWarningPrinter != null)
571b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
572b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // The superclass or interface was found in the program class pool.
573b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Print a warning.
574b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            dependencyWarningPrinter.print(referencingClassName,
575b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           name,
576b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           "Warning: library class " +
577b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           ClassUtil.externalClassName(referencingClassName) +
578b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           " depends on program class " +
579b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           ClassUtil.externalClassName(name));
580b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
581b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
582b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return clazz;
583b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
584b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
585