diff options
Diffstat (limited to 'src/proguard/Initializer.java')
-rw-r--r-- | src/proguard/Initializer.java | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/src/proguard/Initializer.java b/src/proguard/Initializer.java deleted file mode 100644 index 6159c7b..0000000 --- a/src/proguard/Initializer.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard; - -import proguard.classfile.*; -import proguard.classfile.attribute.annotation.visitor.AllElementValueVisitor; -import proguard.classfile.attribute.visitor.AllAttributeVisitor; -import proguard.classfile.constant.visitor.AllConstantVisitor; -import proguard.classfile.instruction.visitor.AllInstructionVisitor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.*; -import proguard.util.*; - -import java.io.IOException; -import java.util.*; - -/** - * This class initializes class pools. - * - * @author Eric Lafortune - */ -public class Initializer -{ - private final Configuration configuration; - - - /** - * Creates a new Initializer to initialize classes according to the given - * configuration. - */ - public Initializer(Configuration configuration) - { - this.configuration = configuration; - } - - - /** - * Initializes the classes in the given program class pool and library class - * pool, performs some basic checks, and shrinks the library class pool. - */ - public void execute(ClassPool programClassPool, - ClassPool libraryClassPool) throws IOException - { - int originalLibraryClassPoolSize = libraryClassPool.size(); - - // Perform basic checks on the configuration. - WarningPrinter fullyQualifiedClassNameNotePrinter = new WarningPrinter(System.out, configuration.note); - - FullyQualifiedClassNameChecker fullyQualifiedClassNameChecker = - new FullyQualifiedClassNameChecker(programClassPool, - libraryClassPool, - fullyQualifiedClassNameNotePrinter); - - fullyQualifiedClassNameChecker.checkClassSpecifications(configuration.keep); - fullyQualifiedClassNameChecker.checkClassSpecifications(configuration.assumeNoSideEffects); - - StringMatcher keepAttributesMatcher = configuration.keepAttributes != null ? - new ListParser(new NameParser()).parse(configuration.keepAttributes) : - new EmptyStringMatcher(); - - WarningPrinter getAnnotationNotePrinter = new WarningPrinter(System.out, configuration.note); - - if (!keepAttributesMatcher.matches(ClassConstants.ATTR_RuntimeVisibleAnnotations)) - { - programClassPool.classesAccept( - new AllConstantVisitor( - new GetAnnotationChecker(getAnnotationNotePrinter))); - } - - WarningPrinter getSignatureNotePrinter = new WarningPrinter(System.out, configuration.note); - - if (!keepAttributesMatcher.matches(ClassConstants.ATTR_Signature)) - { - programClassPool.classesAccept( - new AllConstantVisitor( - new GetSignatureChecker(getSignatureNotePrinter))); - } - - WarningPrinter getEnclosingClassNotePrinter = new WarningPrinter(System.out, configuration.note); - - if (!keepAttributesMatcher.matches(ClassConstants.ATTR_InnerClasses)) - { - programClassPool.classesAccept( - new AllConstantVisitor( - new GetEnclosingClassChecker(getEnclosingClassNotePrinter))); - } - - WarningPrinter getEnclosingMethodNotePrinter = new WarningPrinter(System.out, configuration.note); - - if (!keepAttributesMatcher.matches(ClassConstants.ATTR_EnclosingMethod)) - { - programClassPool.classesAccept( - new AllConstantVisitor( - new GetEnclosingMethodChecker(getEnclosingMethodNotePrinter))); - } - - // 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)))); - } - - // 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 reflection. - 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))), - - new ReferencedClassVisitor( - new LibraryClassFilter( - new ClassHierarchyTraveler(true, true, true, false, - new LibraryClassFilter( - new ClassPoolFiller(libraryClassPool))))) - })); - } - else - { - // Initialize the class references of all library class members. - libraryClassPool.classesAccept( - new ClassReferenceInitializer(programClassPool, - libraryClassPool, - null, - null, - null, - dependencyWarningPrinter)); - } - - // Initialize the subclass hierarchies. - programClassPool.classesAccept(new ClassSubHierarchyInitializer()); - libraryClassPool.classesAccept(new ClassSubHierarchyInitializer()); - - // Share strings between the classes, to reduce heap memory usage. - programClassPool.classesAccept(new StringSharer()); - libraryClassPool.classesAccept(new StringSharer()); - - // Check for any unmatched class members. - WarningPrinter classMemberNotePrinter = new WarningPrinter(System.out, configuration.note); - - ClassMemberChecker classMemberChecker = - new ClassMemberChecker(programClassPool, - classMemberNotePrinter); - - classMemberChecker.checkClassSpecifications(configuration.keep); - classMemberChecker.checkClassSpecifications(configuration.assumeNoSideEffects); - - // 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); - - // Check for keep options that only match library classes. - WarningPrinter libraryKeepNotePrinter = new WarningPrinter(System.out, configuration.note); - - new LibraryKeepChecker(programClassPool, - libraryClassPool, - libraryKeepNotePrinter).checkClassSpecifications(configuration.keep); - - // Print out a summary of the notes, if necessary. - int fullyQualifiedNoteCount = fullyQualifiedClassNameNotePrinter.getWarningCount(); - if (fullyQualifiedNoteCount > 0) - { - System.out.println("Note: there were " + fullyQualifiedNoteCount + - " references to unknown classes."); - System.out.println(" You should check your configuration for typos."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass)"); - } - - int classMemberNoteCount = classMemberNotePrinter.getWarningCount(); - if (classMemberNoteCount > 0) - { - System.out.println("Note: there were " + classMemberNoteCount + - " references to unknown class members."); - System.out.println(" You should check your configuration for typos."); - } - - int getAnnotationNoteCount = getAnnotationNotePrinter.getWarningCount(); - if (getAnnotationNoteCount > 0) - { - System.out.println("Note: there were " + getAnnotationNoteCount + - " classes trying to access annotations using reflection."); - System.out.println(" You should consider keeping the annotation attributes"); - System.out.println(" (using '-keepattributes *Annotation*')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); - } - - int getSignatureNoteCount = getSignatureNotePrinter.getWarningCount(); - if (getSignatureNoteCount > 0) - { - System.out.println("Note: there were " + getSignatureNoteCount + - " classes trying to access generic signatures using reflection."); - System.out.println(" You should consider keeping the signature attributes"); - System.out.println(" (using '-keepattributes Signature')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); - } - - int getEnclosingClassNoteCount = getEnclosingClassNotePrinter.getWarningCount(); - if (getEnclosingClassNoteCount > 0) - { - System.out.println("Note: there were " + getEnclosingClassNoteCount + - " classes trying to access enclosing classes using reflection."); - System.out.println(" You should consider keeping the inner classes attributes"); - System.out.println(" (using '-keepattributes InnerClasses')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); - } - - int getEnclosingMethodNoteCount = getEnclosingMethodNotePrinter.getWarningCount(); - if (getEnclosingMethodNoteCount > 0) - { - System.out.println("Note: there were " + getEnclosingMethodNoteCount + - " classes trying to access enclosing methods using reflection."); - System.out.println(" You should consider keeping the enclosing method attributes"); - System.out.println(" (using '-keepattributes InnerClasses,EnclosingMethod')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); - } - - int descriptorNoteCount = descriptorKeepNotePrinter.getWarningCount(); - if (descriptorNoteCount > 0) - { - System.out.println("Note: there were " + descriptorNoteCount + - " unkept descriptor classes in kept class members."); - System.out.println(" You should consider explicitly keeping the mentioned classes"); - System.out.println(" (using '-keep')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass)"); - } - - int libraryNoteCount = libraryKeepNotePrinter.getWarningCount(); - if (libraryNoteCount > 0) - { - System.out.println("Note: there were " + libraryNoteCount + - " library classes explicitly being kept."); - System.out.println(" You don't need to keep library classes; they are already left unchanged."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#libraryclass)"); - } - - int dynamicClassReferenceNoteCount = dynamicClassReferenceNotePrinter.getWarningCount(); - if (dynamicClassReferenceNoteCount > 0) - { - System.out.println("Note: there were " + dynamicClassReferenceNoteCount + - " unresolved dynamic references to classes or interfaces."); - System.out.println(" You should check if you need to specify additional program jars."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass)"); - } - - int classForNameNoteCount = classForNameNotePrinter.getWarningCount(); - if (classForNameNoteCount > 0) - { - System.out.println("Note: there were " + classForNameNoteCount + - " class casts of dynamically created class instances."); - System.out.println(" You might consider explicitly keeping the mentioned classes and/or"); - System.out.println(" their implementations (using '-keep')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclasscast)"); - } - - int getmemberNoteCount = getMemberNotePrinter.getWarningCount(); - if (getmemberNoteCount > 0) - { - System.out.println("Note: there were " + getmemberNoteCount + - " accesses to class members by means of introspection."); - System.out.println(" You should consider explicitly keeping the mentioned class members"); - System.out.println(" (using '-keep' or '-keepclassmembers')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclassmember)"); - } - - // Print out a summary of the warnings, if necessary. - int classReferenceWarningCount = classReferenceWarningPrinter.getWarningCount(); - if (classReferenceWarningCount > 0) - { - System.err.println("Warning: there were " + classReferenceWarningCount + - " unresolved references to classes or interfaces."); - System.err.println(" You may need to add missing library jars or update their versions."); - System.err.println(" If your code works fine without the missing classes, you can suppress"); - System.err.println(" the warnings with '-dontwarn' options."); - - if (configuration.skipNonPublicLibraryClasses) - { - System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); - } - - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)"); - } - - int dependencyWarningCount = dependencyWarningPrinter.getWarningCount(); - if (dependencyWarningCount > 0) - { - System.err.println("Warning: there were " + dependencyWarningCount + - " instances of library classes depending on program classes."); - System.err.println(" You must avoid such dependencies, since the program classes will"); - System.err.println(" be processed, while the library classes will remain unchanged."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)"); - } - - int programMemberReferenceWarningCount = programMemberReferenceWarningPrinter.getWarningCount(); - if (programMemberReferenceWarningCount > 0) - { - System.err.println("Warning: there were " + programMemberReferenceWarningCount + - " unresolved references to program class members."); - System.err.println(" Your input classes appear to be inconsistent."); - System.err.println(" You may need to recompile the code."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)"); - } - - int libraryMemberReferenceWarningCount = libraryMemberReferenceWarningPrinter.getWarningCount(); - if (libraryMemberReferenceWarningCount > 0) - { - System.err.println("Warning: there were " + libraryMemberReferenceWarningCount + - " unresolved references to library class members."); - System.err.println(" You probably need to update the library versions."); - - if (!configuration.skipNonPublicLibraryClassMembers) - { - System.err.println(" Alternatively, you may have to specify the option "); - System.err.println(" '-dontskipnonpubliclibraryclassmembers'."); - } - - if (configuration.skipNonPublicLibraryClasses) - { - System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); - } - - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)"); - } - - if ((classReferenceWarningCount > 0 || - dependencyWarningCount > 0 || - programMemberReferenceWarningCount > 0 || - libraryMemberReferenceWarningCount > 0) && - !configuration.ignoreWarnings) - { - throw new IOException("Please correct the above warnings first."); - } - - if ((configuration.note == null || - !configuration.note.isEmpty()) && - (configuration.warn != null && - configuration.warn.isEmpty() || - configuration.ignoreWarnings)) - { - System.out.println("Note: you're ignoring all warnings!"); - } - - // Discard unused library classes. - if (configuration.verbose) - { - System.out.println("Ignoring unused library classes..."); - System.out.println(" Original number of library classes: " + originalLibraryClassPoolSize); - System.out.println(" Final number of library classes: " + libraryClassPool.size()); - } - } - - - /** - * Extracts a list of exceptions of classes for which not to print notes, - * from the keep configuration. - */ - private StringMatcher createClassNoteExceptionMatcher(List noteExceptions) - { - if (noteExceptions != null) - { - List noteExceptionNames = new ArrayList(noteExceptions.size()); - for (int index = 0; index < noteExceptions.size(); index++) - { - KeepClassSpecification keepClassSpecification = (KeepClassSpecification)noteExceptions.get(index); - if (keepClassSpecification.markClasses) - { - // If the class itself is being kept, it's ok. - String className = keepClassSpecification.className; - if (className != null) - { - noteExceptionNames.add(className); - } - - // If all of its extensions are being kept, it's ok too. - String extendsClassName = keepClassSpecification.extendsClassName; - if (extendsClassName != null) - { - noteExceptionNames.add(extendsClassName); - } - } - } - - if (noteExceptionNames.size() > 0) - { - return new ListParser(new ClassNameParser()).parse(noteExceptionNames); - } - } - - return null; - } - - - /** - * Extracts a list of exceptions of field or method names for which not to - * print notes, from the keep configuration. - */ - private StringMatcher createClassMemberNoteExceptionMatcher(List noteExceptions, - boolean isField) - { - if (noteExceptions != null) - { - List noteExceptionNames = new ArrayList(); - for (int index = 0; index < noteExceptions.size(); index++) - { - KeepClassSpecification keepClassSpecification = (KeepClassSpecification)noteExceptions.get(index); - List memberSpecifications = isField ? - keepClassSpecification.fieldSpecifications : - keepClassSpecification.methodSpecifications; - - if (memberSpecifications != null) - { - for (int index2 = 0; index2 < memberSpecifications.size(); index2++) - { - MemberSpecification memberSpecification = - (MemberSpecification)memberSpecifications.get(index2); - - String memberName = memberSpecification.name; - if (memberName != null) - { - noteExceptionNames.add(memberName); - } - } - } - } - - if (noteExceptionNames.size() > 0) - { - return new ListParser(new ClassNameParser()).parse(noteExceptionNames); - } - } - - return null; - } -} |