ClassSuperHierarchyInitializer.java revision 2270795fbe0b277bfd49f40950ecaa78583175cc
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.constant.ClassConstant;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.ClassVisitor;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This ClassVisitor initializes the superclass hierarchy of all classes that
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * it visits.
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Visited library classes get direct references to their superclasses and
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * interfaces, replacing the superclass names and interface names. The direct
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * references are equivalent to the names, but they are more efficient to work
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with.
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p>
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This visitor optionally prints warnings if some superclasses can't be found
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * or if they are in the program class pool.
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ClassSuperHierarchyInitializer
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends      SimplifiedVisitor
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements   ClassVisitor,
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             ConstantVisitor
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final ClassPool      programClassPool;
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final ClassPool      libraryClassPool;
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final WarningPrinter missingWarningPrinter;
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final WarningPrinter dependencyWarningPrinter;
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new ClassSuperHierarchyInitializer that initializes the super
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * hierarchy of all visited class files, optionally printing warnings if
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * some classes can't be found or if they are in the program class pool.
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ClassSuperHierarchyInitializer(ClassPool      programClassPool,
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          ClassPool      libraryClassPool,
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          WarningPrinter missingWarningPrinter,
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          WarningPrinter dependencyWarningPrinter)
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.programClassPool         = programClassPool;
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.libraryClassPool         = libraryClassPool;
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.missingWarningPrinter    = missingWarningPrinter;
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.dependencyWarningPrinter = dependencyWarningPrinter;
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ClassVisitor.
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramClass(ProgramClass programClass)
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Link to the super class.
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.superClassConstantAccept(this);
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Link to the interfaces.
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.interfaceConstantsAccept(this);
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryClass(LibraryClass libraryClass)
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String className = libraryClass.getName();
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Link to the super class.
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String superClassName = libraryClass.superClassName;
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (superClassName != null)
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Keep a reference to the superclass.
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            libraryClass.superClass = findClass(className, superClassName);
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Link to the interfaces.
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (libraryClass.interfaceNames != null)
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String[] interfaceNames   = libraryClass.interfaceNames;
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Clazz[]  interfaceClasses = new Clazz[interfaceNames.length];
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < interfaceNames.length; index++)
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Keep a reference to the interface class.
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                interfaceClasses[index] =
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    findClass(className, interfaceNames[index]);
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            libraryClass.interfaceClasses = interfaceClasses;
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ConstantVisitor.
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        classConstant.referencedClass =
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            findClass(clazz.getName(), classConstant.getName(clazz));
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the class with the given name, either for the program class pool
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * or from the library class pool, or <code>null</code> if it can't be found.
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz findClass(String referencingClassName, String name)
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // First look for the class in the program class pool.
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz clazz = programClassPool.getClass(name);
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Otherwise look for the class in the library class pool.
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (clazz == null)
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            clazz = libraryClassPool.getClass(name);
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (clazz == null &&
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                missingWarningPrinter != null)
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // We didn't find the superclass or interface. Print a warning.
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                missingWarningPrinter.print(referencingClassName,
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            name,
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            "Warning: " +
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            ClassUtil.externalClassName(referencingClassName) +
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            ": can't find superclass or interface " +
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            ClassUtil.externalClassName(name));
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        else if (dependencyWarningPrinter != null)
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // The superclass or interface was found in the program class pool.
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Print a warning.
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            dependencyWarningPrinter.print(referencingClassName,
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           name,
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           "Warning: library class " +
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           ClassUtil.externalClassName(referencingClassName) +
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           " extends or implements program class " +
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           ClassUtil.externalClassName(name));
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return clazz;
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
164