// Construct a reduced library class pool with only those library
// classes whose hierarchies are referenced by the program classes.
// We can't do this if we later have to come up with the obfuscated
// class member names that are globally unique.
ClassPool reducedLibraryClassPool = configuration.useUniqueClassMemberNames ?
null : new ClassPool();
WarningPrinter classReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn);
WarningPrinter dependencyWarningPrinter = new WarningPrinter(System.err, configuration.warn);
// Initialize the superclass hierarchies for program classes.
programClassPool.classesAccept(
new ClassSuperHierarchyInitializer(programClassPool,
libraryClassPool,
classReferenceWarningPrinter,
null));
// Initialize the superclass hierarchy of all library classes, without
// warnings.
libraryClassPool.classesAccept(
new ClassSuperHierarchyInitializer(programClassPool,
libraryClassPool,
null,
dependencyWarningPrinter));
// Initialize the class references of program class members and
// attributes. Note that all superclass hierarchies have to be
// initialized for this purpose.
WarningPrinter programMemberReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn);
WarningPrinter libraryMemberReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn);
programClassPool.classesAccept(
new ClassReferenceInitializer(programClassPool,
libraryClassPool,
classReferenceWarningPrinter,
programMemberReferenceWarningPrinter,
libraryMemberReferenceWarningPrinter,
null));
if (reducedLibraryClassPool != null)
{
// Collect the library classes that are directly referenced by
// program classes, without introspection.
programClassPool.classesAccept(
new ReferencedClassVisitor(
new LibraryClassFilter(
new ClassPoolFiller(reducedLibraryClassPool))));
// Reinitialize the superclass hierarchies of referenced library
// classes, this time with warnings.
reducedLibraryClassPool.classesAccept(
new ClassSuperHierarchyInitializer(programClassPool,
libraryClassPool,
classReferenceWarningPrinter,
null));
}
// Initialize the enum annotation references.
programClassPool.classesAccept(
new AllAttributeVisitor(true,
new AllElementValueVisitor(true,
new EnumFieldReferenceInitializer())));
// Initialize the Class.forName references.
WarningPrinter dynamicClassReferenceNotePrinter = new WarningPrinter(System.out, configuration.note);
WarningPrinter classForNameNotePrinter = new WarningPrinter(System.out, configuration.note);
programClassPool.classesAccept(
new AllMethodVisitor(
new AllAttributeVisitor(
new AllInstructionVisitor(
new DynamicClassReferenceInitializer(programClassPool,
libraryClassPool,
dynamicClassReferenceNotePrinter,
null,
classForNameNotePrinter,
createClassNoteExceptionMatcher(configuration.keep))))));
// Initialize the Class.get[Declared]{Field,Method} references.
WarningPrinter getMemberNotePrinter = new WarningPrinter(System.out, configuration.note);
programClassPool.classesAccept(
new AllMethodVisitor(
new AllAttributeVisitor(
new AllInstructionVisitor(
new DynamicMemberReferenceInitializer(programClassPool,
libraryClassPool,
getMemberNotePrinter,
createClassMemberNoteExceptionMatcher(configuration.keep, true),
createClassMemberNoteExceptionMatcher(configuration.keep, false))))));
// Initialize other string constant references, if requested.
if (configuration.adaptClassStrings != null)
{
programClassPool.classesAccept(
new ClassNameFilter(configuration.adaptClassStrings,
new AllConstantVisitor(
new StringReferenceInitializer(programClassPool,
libraryClassPool))));
}
// Check for unkept descriptor classes of kept class members.
WarningPrinter descriptorKeepNotePrinter = new WarningPrinter(System.out, configuration.note);
new DescriptorKeepChecker(programClassPool,
libraryClassPool,
descriptorKeepNotePrinter).checkClassSpecifications(configuration.keep);
// Initialize the class references of library class members.
if (reducedLibraryClassPool != null)
{
// Collect the library classes that are referenced by program
// classes, directly or indirectly, with or without introspection.
programClassPool.classesAccept(
new ReferencedClassVisitor(
new LibraryClassFilter(
new ClassHierarchyTraveler(true, true, true, false,
new LibraryClassFilter(
new ClassPoolFiller(reducedLibraryClassPool))))));
// Initialize the class references of referenced library
// classes, without warnings.
reducedLibraryClassPool.classesAccept(
new ClassReferenceInitializer(programClassPool,
libraryClassPool,
null,
null,
null,
dependencyWarningPrinter));
// Reset the library class pool.
libraryClassPool.clear();
// Copy the library classes that are referenced directly by program
// classes and the library classes that are referenced by referenced
// library classes.
reducedLibraryClassPool.classesAccept(
new MultiClassVisitor(new ClassVisitor[]
{
new ClassHierarchyTraveler(true, true, true, false,
new LibraryClassFilter(
new ClassPoolFiller(libraryClassPool))),