diff options
Diffstat (limited to 'src/proguard/classfile/util/ClassReferenceInitializer.java')
-rw-r--r-- | src/proguard/classfile/util/ClassReferenceInitializer.java | 584 |
1 files changed, 0 insertions, 584 deletions
diff --git a/src/proguard/classfile/util/ClassReferenceInitializer.java b/src/proguard/classfile/util/ClassReferenceInitializer.java deleted file mode 100644 index 3baf422..0000000 --- a/src/proguard/classfile/util/ClassReferenceInitializer.java +++ /dev/null @@ -1,584 +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.classfile.util; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.annotation.visitor.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.visitor.*; - - -/** - * This ClassVisitor initializes the references of all classes that - * it visits. - * <p> - * All class constant pool entries get direct references to the corresponding - * classes. These references make it more convenient to travel up and across - * the class hierarchy. - * <p> - * All field and method reference constant pool entries get direct references - * to the corresponding classes, fields, and methods. - * <p> - * All name and type constant pool entries get a list of direct references to - * the classes listed in the type. - * <p> - * This visitor optionally prints warnings if some items can't be found. - * <p> - * The class hierarchy must be initialized before using this visitor. - * - * @author Eric Lafortune - */ -public class ClassReferenceInitializer -extends SimplifiedVisitor -implements ClassVisitor, - MemberVisitor, - ConstantVisitor, - AttributeVisitor, - LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor, - AnnotationVisitor, - ElementValueVisitor -{ - private final ClassPool programClassPool; - private final ClassPool libraryClassPool; - private final WarningPrinter missingClassWarningPrinter; - private final WarningPrinter missingProgramMemberWarningPrinter; - private final WarningPrinter missingLibraryMemberWarningPrinter; - private final WarningPrinter dependencyWarningPrinter; - - private final MemberFinder memberFinder = new MemberFinder(); - - - /** - * Creates a new ClassReferenceInitializer that initializes the references - * of all visited class files, optionally printing warnings if some classes - * or class members can't be found or if they are in the program class pool. - */ - public ClassReferenceInitializer(ClassPool programClassPool, - ClassPool libraryClassPool, - WarningPrinter missingClassWarningPrinter, - WarningPrinter missingProgramMemberWarningPrinter, - WarningPrinter missingLibraryMemberWarningPrinter, - WarningPrinter dependencyWarningPrinter) - { - this.programClassPool = programClassPool; - this.libraryClassPool = libraryClassPool; - this.missingClassWarningPrinter = missingClassWarningPrinter; - this.missingProgramMemberWarningPrinter = missingProgramMemberWarningPrinter; - this.missingLibraryMemberWarningPrinter = missingLibraryMemberWarningPrinter; - this.dependencyWarningPrinter = dependencyWarningPrinter; - } - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - // Initialize the constant pool entries. - programClass.constantPoolEntriesAccept(this); - - // Initialize all fields and methods. - programClass.fieldsAccept(this); - programClass.methodsAccept(this); - - // Initialize the attributes. - programClass.attributesAccept(this); - } - - - public void visitLibraryClass(LibraryClass libraryClass) - { - // Initialize all fields and methods. - libraryClass.fieldsAccept(this); - libraryClass.methodsAccept(this); - } - - - // Implementations for MemberVisitor. - - public void visitProgramField(ProgramClass programClass, ProgramField programField) - { - programField.referencedClass = - findReferencedClass(programClass.getName(), - programField.getDescriptor(programClass)); - - // Initialize the attributes. - programField.attributesAccept(programClass, this); - } - - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - programMethod.referencedClasses = - findReferencedClasses(programClass.getName(), - programMethod.getDescriptor(programClass)); - - // Initialize the attributes. - programMethod.attributesAccept(programClass, this); - } - - - public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) - { - libraryField.referencedClass = - findReferencedClass(libraryClass.getName(), - libraryField.getDescriptor(libraryClass)); - } - - - public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) - { - libraryMethod.referencedClasses = - findReferencedClasses(libraryClass.getName(), - libraryMethod.getDescriptor(libraryClass)); - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) {} - - - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) - { - // Fill out the String class. - stringConstant.javaLangStringClass = - findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_STRING); - } - - - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - invokeDynamicConstant.referencedClasses = - findReferencedClasses(clazz.getName(), - invokeDynamicConstant.getType(clazz)); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - // Fill out the MethodHandle class. - methodHandleConstant.javaLangInvokeMethodHandleClass = - findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_HANDLE); - } - - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) - { - String className = refConstant.getClassName(clazz); - - // Methods for array types should be found in the Object class. - if (ClassUtil.isInternalArrayType(className)) - { - className = ClassConstants.NAME_JAVA_LANG_OBJECT; - } - - // See if we can find the referenced class. - // Unresolved references are assumed to refer to library classes - // that will not change anyway. - Clazz referencedClass = findClass(clazz.getName(), className); - - if (referencedClass != null) - { - String name = refConstant.getName(clazz); - String type = refConstant.getType(clazz); - - boolean isFieldRef = refConstant.getTag() == ClassConstants.CONSTANT_Fieldref; - - // See if we can find the referenced class member somewhere in the - // hierarchy. - refConstant.referencedMember = memberFinder.findMember(clazz, - referencedClass, - name, - type, - isFieldRef); - refConstant.referencedClass = memberFinder.correspondingClass(); - - if (refConstant.referencedMember == null) - { - // We haven't found the class member anywhere in the hierarchy. - boolean isProgramClass = referencedClass instanceof ProgramClass; - - WarningPrinter missingMemberWarningPrinter = isProgramClass ? - missingProgramMemberWarningPrinter : - missingLibraryMemberWarningPrinter; - - missingMemberWarningPrinter.print(clazz.getName(), - className, - "Warning: " + - ClassUtil.externalClassName(clazz.getName()) + - ": can't find referenced " + - (isFieldRef ? - "field '" + ClassUtil.externalFullFieldDescription(0, name, type) : - "method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) + - "' in " + - (isProgramClass ? - "program" : - "library") + - " class " + - ClassUtil.externalClassName(className)); - } - } - } - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - String className = clazz.getName(); - - // Fill out the referenced class. - classConstant.referencedClass = - findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz))); - - // Fill out the Class class. - classConstant.javaLangClassClass = - findClass(className, ClassConstants.NAME_JAVA_LANG_CLASS); - } - - - public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) - { - // Fill out the MethodType class. - methodTypeConstant.javaLangInvokeMethodTypeClass = - findClass(clazz.getName(), ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_TYPE); - - methodTypeConstant.referencedClasses = - findReferencedClasses(clazz.getName(), - methodTypeConstant.getType(clazz)); - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) - { - String className = clazz.getName(); - String enclosingClassName = enclosingMethodAttribute.getClassName(clazz); - - // See if we can find the referenced class. - enclosingMethodAttribute.referencedClass = - findClass(className, enclosingClassName); - - if (enclosingMethodAttribute.referencedClass != null) - { - // Is there an enclosing method? Otherwise it's just initialization - // code outside of the constructors. - if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) - { - String name = enclosingMethodAttribute.getName(clazz); - String type = enclosingMethodAttribute.getType(clazz); - - // See if we can find the method in the referenced class. - enclosingMethodAttribute.referencedMethod = - enclosingMethodAttribute.referencedClass.findMethod(name, type); - - if (enclosingMethodAttribute.referencedMethod == null) - { - // We couldn't find the enclosing method. - missingProgramMemberWarningPrinter.print(className, - enclosingClassName, - "Warning: " + - ClassUtil.externalClassName(className) + - ": can't find enclosing method '" + - ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) + - "' in program class " + - ClassUtil.externalClassName(enclosingClassName)); - } - } - } - } - - - public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - // Initialize the nested attributes. - codeAttribute.attributesAccept(clazz, method, this); - } - - - public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) - { - // Initialize the local variables. - localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) - { - // Initialize the local variable types. - localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) - { - signatureAttribute.referencedClasses = - findReferencedClasses(clazz.getName(), - signatureAttribute.getSignature(clazz)); - } - - - public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) - { - // Initialize the annotations. - annotationsAttribute.annotationsAccept(clazz, this); - } - - - public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) - { - // Initialize the annotations. - parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); - } - - - public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) - { - // Initialize the annotation. - annotationDefaultAttribute.defaultValueAccept(clazz, this); - } - - - // Implementations for LocalVariableInfoVisitor. - - public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) - { - localVariableInfo.referencedClass = - findReferencedClass(clazz.getName(), - localVariableInfo.getDescriptor(clazz)); - } - - - // Implementations for LocalVariableTypeInfoVisitor. - - public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) - { - localVariableTypeInfo.referencedClasses = - findReferencedClasses(clazz.getName(), - localVariableTypeInfo.getSignature(clazz)); - } - - - // Implementations for AnnotationVisitor. - - public void visitAnnotation(Clazz clazz, Annotation annotation) - { - annotation.referencedClasses = - findReferencedClasses(clazz.getName(), - annotation.getType(clazz)); - - // Initialize the element values. - annotation.elementValuesAccept(clazz, this); - } - - - // Implementations for ElementValueVisitor. - - public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) - { - initializeElementValue(clazz, annotation, constantElementValue); - } - - - public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) - { - initializeElementValue(clazz, annotation, enumConstantElementValue); - - enumConstantElementValue.referencedClasses = - findReferencedClasses(clazz.getName(), - enumConstantElementValue.getTypeName(clazz)); - } - - - public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) - { - initializeElementValue(clazz, annotation, classElementValue); - - classElementValue.referencedClasses = - findReferencedClasses(clazz.getName(), - classElementValue.getClassName(clazz)); - } - - - public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) - { - initializeElementValue(clazz, annotation, annotationElementValue); - - // Initialize the annotation. - annotationElementValue.annotationAccept(clazz, this); - } - - - public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) - { - initializeElementValue(clazz, annotation, arrayElementValue); - - // Initialize the element values. - arrayElementValue.elementValuesAccept(clazz, annotation, this); - } - - - /** - * Initializes the referenced method of an element value, if any. - */ - private void initializeElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) - { - // See if we have a referenced class. - if (annotation != null && - annotation.referencedClasses != null && - elementValue.u2elementNameIndex != 0) - { - // See if we can find the method in the referenced class - // (ignoring the descriptor). - String name = elementValue.getMethodName(clazz); - - Clazz referencedClass = annotation.referencedClasses[0]; - elementValue.referencedClass = referencedClass; - elementValue.referencedMethod = referencedClass.findMethod(name, null); - } - } - - - // Small utility methods. - - /** - * Returns the single class referenced by the given descriptor, or - * <code>null</code> if there isn't any useful reference. - */ - private Clazz findReferencedClass(String referencingClassName, - String descriptor) - { - DescriptorClassEnumeration enumeration = - new DescriptorClassEnumeration(descriptor); - - enumeration.nextFluff(); - - if (enumeration.hasMoreClassNames()) - { - return findClass(referencingClassName, enumeration.nextClassName()); - } - - return null; - } - - - /** - * Returns an array of classes referenced by the given descriptor, or - * <code>null</code> if there aren't any useful references. - */ - private Clazz[] findReferencedClasses(String referencingClassName, - String descriptor) - { - DescriptorClassEnumeration enumeration = - new DescriptorClassEnumeration(descriptor); - - int classCount = enumeration.classCount(); - if (classCount > 0) - { - Clazz[] referencedClasses = new Clazz[classCount]; - - boolean foundReferencedClasses = false; - - for (int index = 0; index < classCount; index++) - { - String fluff = enumeration.nextFluff(); - String name = enumeration.nextClassName(); - - Clazz referencedClass = findClass(referencingClassName, name); - - if (referencedClass != null) - { - referencedClasses[index] = referencedClass; - foundReferencedClasses = true; - } - } - - if (foundReferencedClasses) - { - return referencedClasses; - } - } - - return null; - } - - - /** - * Returns the class with the given name, either for the program class pool - * or from the library class pool, or <code>null</code> if it can't be found. - */ - private Clazz findClass(String referencingClassName, String name) - { - // Is it an array type? - if (ClassUtil.isInternalArrayType(name)) - { - // Ignore any primitive array types. - if (!ClassUtil.isInternalClassType(name)) - { - return null; - } - - // Strip the array part. - name = ClassUtil.internalClassNameFromClassType(name); - } - - // First look for the class in the program class pool. - Clazz clazz = programClassPool.getClass(name); - - // Otherwise look for the class in the library class pool. - if (clazz == null) - { - clazz = libraryClassPool.getClass(name); - - if (clazz == null && - missingClassWarningPrinter != null) - { - // We didn't find the superclass or interface. Print a warning. - missingClassWarningPrinter.print(referencingClassName, - name, - "Warning: " + - ClassUtil.externalClassName(referencingClassName) + - ": can't find referenced class " + - ClassUtil.externalClassName(name)); - } - } - else if (dependencyWarningPrinter != null) - { - // The superclass or interface was found in the program class pool. - // Print a warning. - dependencyWarningPrinter.print(referencingClassName, - name, - "Warning: library class " + - ClassUtil.externalClassName(referencingClassName) + - " depends on program class " + - ClassUtil.externalClassName(name)); - } - - return clazz; - } -} |