📄 classreferenceinitializer.java
字号:
/* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2007 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.visitor.*;import proguard.classfile.attribute.annotation.*;import proguard.classfile.attribute.annotation.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 ClassReferenceInitializerextends SimplifiedVisitorimplements ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor, LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor, AnnotationVisitor, ElementValueVisitor{ private ClassPool programClassPool; private ClassPool libraryClassPool; private WarningPrinter warningPrinter; private MemberFinder memberFinder = new MemberFinder(); /** * Creates a new ClassReferenceInitializer that initializes the references * of all visited class files, optionally printing warnings if some classes * can't be found. */ public ClassReferenceInitializer(ClassPool programClassPool, ClassPool libraryClassPool, WarningPrinter warningPrinter) { this.programClassPool = programClassPool; this.libraryClassPool = libraryClassPool; this.warningPrinter = warningPrinter; } // 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(programField.getDescriptor(programClass)); // Initialize the attributes. programField.attributesAccept(programClass, this); } public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { programMethod.referencedClasses = findReferencedClasses(programMethod.getDescriptor(programClass)); // Initialize the attributes. programMethod.attributesAccept(programClass, this); } public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) { libraryField.referencedClass = findReferencedClass(libraryField.getDescriptor(libraryClass)); } public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) { libraryMethod.referencedClasses = findReferencedClasses(libraryMethod.getDescriptor(libraryClass)); } // Implementations for ConstantVisitor. public void visitAnyConstant(Clazz clazz, Constant constant) {} public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { String className = refConstant.getClassName(clazz); // 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(className); if (referencedClass != null && !ClassUtil.isInternalArrayType(className)) { 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 && warningPrinter != null) { // We've haven't found the class member anywhere in the hierarchy. warningPrinter.print("Warning: " + ClassUtil.externalClassName(clazz.getName()) + ": can't find referenced " + (isFieldRef ? "field '" + ClassUtil.externalFullFieldDescription(0, name, type) : "method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) + "' in class " + ClassUtil.externalClassName(className)); } } } public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { classConstant.referencedClass = findClass(classConstant.getName(clazz)); } // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) { String className = enclosingMethodAttribute.getClassName(clazz); // See if we can find the referenced class. Clazz referencedClass = findClass(className); if (referencedClass == null) { // We couldn't find the enclosing class. if (warningPrinter != null) { warningPrinter.print("Warning: " + ClassUtil.externalClassName(clazz.getName()) + ": can't find enclosing class " + ClassUtil.externalClassName(className)); } return; } // Make sure there is actually an enclosed method. if (enclosingMethodAttribute.u2nameAndTypeIndex == 0) { return; } String name = enclosingMethodAttribute.getName(clazz); String type = enclosingMethodAttribute.getType(clazz); // See if we can find the method in the referenced class. Method referencedMethod = referencedClass.findMethod(name, type); if (referencedMethod == null) { // We couldn't find the enclosing method.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -