1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 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;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.ClassPool;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.AllAttributeVisitor;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.visitor.AllInstructionVisitor;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*;
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.util.*;
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.IOException;
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.util.*;
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class initializes class pools.
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class Initializer
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final Configuration configuration;
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new Initializer to initialize classes according to the given
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * configuration.
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Initializer(Configuration configuration)
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.configuration = configuration;
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Initializes the classes in the given program class pool and library class
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * pool, performs some basic checks, and shrinks the library class pool.
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void execute(ClassPool programClassPool,
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        ClassPool libraryClassPool) throws IOException
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int originalLibraryClassPoolSize = libraryClassPool.size();
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Construct a reduced library class pool with only those library
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // classes whose hierarchies are referenced by the program classes.
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // We can't do this if we later have to come up with the obfuscated
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // class member names that are globally unique.
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ClassPool reducedLibraryClassPool = configuration.useUniqueClassMemberNames ?
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            null : new ClassPool();
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter classReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn);
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter dependencyWarningPrinter     = new WarningPrinter(System.err, configuration.warn);
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the superclass hierarchies for program classes.
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ClassSuperHierarchyInitializer(programClassPool,
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               libraryClassPool,
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               classReferenceWarningPrinter,
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               null));
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the superclass hierarchy of all library classes, without
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // warnings.
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClassPool.classesAccept(
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ClassSuperHierarchyInitializer(programClassPool,
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               libraryClassPool,
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               null,
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               dependencyWarningPrinter));
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the class references of program class members and
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // attributes. Note that all superclass hierarchies have to be
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // initialized for this purpose.
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter memberReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn);
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ClassReferenceInitializer(programClassPool,
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          libraryClassPool,
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          classReferenceWarningPrinter,
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          memberReferenceWarningPrinter,
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          null));
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (reducedLibraryClassPool != null)
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Collect the library classes that are directly referenced by
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // program classes, without introspection.
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClassPool.classesAccept(
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ReferencedClassVisitor(
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new LibraryClassFilter(
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassPoolFiller(reducedLibraryClassPool))));
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Reinitialize the superclass hierarchies of referenced library
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // classes, this time with warnings.
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            reducedLibraryClassPool.classesAccept(
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassSuperHierarchyInitializer(programClassPool,
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                   libraryClassPool,
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                   classReferenceWarningPrinter,
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                   null));
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the Class.forName references.
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter dynamicClassReferenceNotePrinter = new WarningPrinter(System.out, configuration.note);
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter classForNameNotePrinter          = new WarningPrinter(System.out, configuration.note);
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllMethodVisitor(
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllAttributeVisitor(
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllInstructionVisitor(
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new DynamicClassReferenceInitializer(programClassPool,
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 libraryClassPool,
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 dynamicClassReferenceNotePrinter,
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 null,
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 classForNameNotePrinter,
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 createClassNoteExceptionMatcher(configuration.keep))))));
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the Class.get[Declared]{Field,Method} references.
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter getMemberNotePrinter = new WarningPrinter(System.out, configuration.note);
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllMethodVisitor(
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllAttributeVisitor(
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new AllInstructionVisitor(
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new DynamicMemberReferenceInitializer(programClassPool,
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  libraryClassPool,
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  getMemberNotePrinter,
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  createClassMemberNoteExceptionMatcher(configuration.keep, true),
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  createClassMemberNoteExceptionMatcher(configuration.keep, false))))));
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize other string constant references, if requested.
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.adaptClassStrings != null)
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClassPool.classesAccept(
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassNameFilter(configuration.adaptClassStrings,
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new AllConstantVisitor(
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new StringReferenceInitializer(programClassPool,
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               libraryClassPool))));
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Print various notes, if specified.
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter fullyQualifiedClassNameNotePrinter = new WarningPrinter(System.out, configuration.note);
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter descriptorKeepNotePrinter          = new WarningPrinter(System.out, configuration.note);
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new FullyQualifiedClassNameChecker(programClassPool,
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           libraryClassPool,
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           fullyQualifiedClassNameNotePrinter).checkClassSpecifications(configuration.keep);
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new DescriptorKeepChecker(programClassPool,
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  libraryClassPool,
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  descriptorKeepNotePrinter).checkClassSpecifications(configuration.keep);
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the class references of library class members.
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (reducedLibraryClassPool != null)
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Collect the library classes that are referenced by program
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // classes, directly or indirectly, with or without introspection.
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClassPool.classesAccept(
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ReferencedClassVisitor(
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new LibraryClassFilter(
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassHierarchyTraveler(true, true, true, false,
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new LibraryClassFilter(
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassPoolFiller(reducedLibraryClassPool))))));
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Initialize the class references of referenced library
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // classes, without warnings.
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            reducedLibraryClassPool.classesAccept(
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassReferenceInitializer(programClassPool,
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              libraryClassPool,
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              null,
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              null,
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              dependencyWarningPrinter));
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Reset the library class pool.
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            libraryClassPool.clear();
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Copy the library classes that are referenced directly by program
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // classes and the library classes that are referenced by referenced
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // library classes.
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            reducedLibraryClassPool.classesAccept(
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new MultiClassVisitor(new ClassVisitor[]
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new ClassHierarchyTraveler(true, true, true, false,
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new LibraryClassFilter(
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new ClassPoolFiller(libraryClassPool))),
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new ReferencedClassVisitor(
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new LibraryClassFilter(
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new ClassHierarchyTraveler(true, true, true, false,
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new LibraryClassFilter(
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    new ClassPoolFiller(libraryClassPool)))))
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }));
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        else
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Initialize the class references of all library class members.
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            libraryClassPool.classesAccept(
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ClassReferenceInitializer(programClassPool,
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              libraryClassPool,
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              null,
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              null,
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                              dependencyWarningPrinter));
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Initialize the subclass hierarchies.
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(new ClassSubHierarchyInitializer());
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClassPool.classesAccept(new ClassSubHierarchyInitializer());
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Share strings between the classes, to reduce heap memory usage.
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(new StringSharer());
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClassPool.classesAccept(new StringSharer());
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Print out a summary of the notes, if necessary.
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int fullyQualifiedNoteCount = fullyQualifiedClassNameNotePrinter.getWarningCount();
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (fullyQualifiedNoteCount > 0)
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: there were " + fullyQualifiedNoteCount +
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " references to unknown classes.");
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      You should check your configuration for typos.");
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int descriptorNoteCount = descriptorKeepNotePrinter.getWarningCount();
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (descriptorNoteCount > 0)
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: there were " + descriptorNoteCount +
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " unkept descriptor classes in kept class members.");
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      You should consider explicitly keeping the mentioned classes");
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      (using '-keep').");
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int dynamicClassReferenceNoteCount = dynamicClassReferenceNotePrinter.getWarningCount();
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (dynamicClassReferenceNoteCount > 0)
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: there were " + dynamicClassReferenceNoteCount +
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " unresolved dynamic references to classes or interfaces.");
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("      You should check if you need to specify additional program jars.");
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int classForNameNoteCount = classForNameNotePrinter.getWarningCount();
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (classForNameNoteCount > 0)
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: there were " + classForNameNoteCount +
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " class casts of dynamically created class instances.");
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      You might consider explicitly keeping the mentioned classes and/or");
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      their implementations (using '-keep').");
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int getmemberNoteCount = getMemberNotePrinter.getWarningCount();
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (getmemberNoteCount > 0)
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: there were " + getmemberNoteCount +
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " accesses to class members by means of introspection.");
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      You should consider explicitly keeping the mentioned class members");
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("      (using '-keep' or '-keepclassmembers').");
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Print out a summary of the warnings, if necessary.
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int classReferenceWarningCount = classReferenceWarningPrinter.getWarningCount();
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (classReferenceWarningCount > 0)
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("Warning: there were " + classReferenceWarningCount +
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " unresolved references to classes or interfaces.");
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         You may need to specify additional library jars (using '-libraryjars'),");
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         or perhaps the '-dontskipnonpubliclibraryclasses' option.");
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int dependencyWarningCount = dependencyWarningPrinter.getWarningCount();
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (dependencyWarningCount > 0)
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("Warning: there were " + dependencyWarningCount +
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " instances of library classes depending on program classes.");
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         You must avoid such dependencies, since the program classes will");
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         be processed, while the library classes will remain unchanged.");
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int memberReferenceWarningCount = memberReferenceWarningPrinter.getWarningCount();
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (memberReferenceWarningCount > 0)
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("Warning: there were " + memberReferenceWarningCount +
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " unresolved references to program class members.");
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         Your input classes appear to be inconsistent.");
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         You may need to recompile them and try again.");
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         Alternatively, you may have to specify the options ");
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         '-dontskipnonpubliclibraryclasses' and/or");
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         '-dontskipnonpubliclibraryclassmembers'.");
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if ((classReferenceWarningCount   > 0 ||
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             dependencyWarningCount       > 0 ||
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             memberReferenceWarningCount  > 0) &&
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            !configuration.ignoreWarnings)
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IOException("Please correct the above warnings first.");
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if ((configuration.note == null ||
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             !configuration.note.isEmpty()) &&
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            (configuration.warn != null &&
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             configuration.warn.isEmpty() ||
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             configuration.ignoreWarnings))
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Note: You're ignoring all warnings!");
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Discard unused library classes.
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Ignoring unused library classes...");
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("  Original number of library classes: " + originalLibraryClassPoolSize);
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("  Final number of library classes:    " + libraryClassPool.size());
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Extracts a list of exceptions of classes for which not to print notes,
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * from the keep configuration.
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private StringMatcher createClassNoteExceptionMatcher(List noteExceptions)
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (noteExceptions != null)
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            List noteExceptionNames = new ArrayList(noteExceptions.size());
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < noteExceptions.size(); index++)
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                KeepClassSpecification keepClassSpecification = (KeepClassSpecification)noteExceptions.get(index);
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (keepClassSpecification.markClasses)
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // If the class itself is being kept, it's ok.
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    String className = keepClassSpecification.className;
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    if (className != null)
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        noteExceptionNames.add(className);
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // If all of its extensions are being kept, it's ok too.
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    String extendsClassName = keepClassSpecification.extendsClassName;
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    if (extendsClassName != null)
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        noteExceptionNames.add(extendsClassName);
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (noteExceptionNames.size() > 0)
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return new ListParser(new ClassNameParser()).parse(noteExceptionNames);
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return null;
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Extracts a list of exceptions of field or method names for which not to
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * print notes, from the keep configuration.
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private StringMatcher createClassMemberNoteExceptionMatcher(List    noteExceptions,
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                                boolean isField)
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (noteExceptions != null)
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            List noteExceptionNames = new ArrayList();
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < noteExceptions.size(); index++)
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                KeepClassSpecification keepClassSpecification = (KeepClassSpecification)noteExceptions.get(index);
383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                List memberSpecifications = isField ?
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    keepClassSpecification.fieldSpecifications :
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    keepClassSpecification.methodSpecifications;
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (memberSpecifications != null)
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    for (int index2 = 0; index2 < memberSpecifications.size(); index2++)
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        MemberSpecification memberSpecification =
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                            (MemberSpecification)memberSpecifications.get(index2);
393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        String memberName = memberSpecification.name;
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        if (memberName != null)
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        {
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                            noteExceptionNames.add(memberName);
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        }
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (noteExceptionNames.size() > 0)
404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return new ListParser(new ClassNameParser()).parse(noteExceptionNames);
406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return null;
410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
412