📄 classreferencefixer.java
字号:
} public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) { // Fix the annotations. annotationsAttribute.annotationsAccept(clazz, this); } public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) { // Fix the annotations. parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); } public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) { // Fix the annotation. annotationDefaultAttribute.defaultValueAccept(clazz, this); } // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) { // Fix the inner class name. int innerClassIndex = innerClassesInfo.u2innerClassIndex; int innerNameIndex = innerClassesInfo.u2innerNameIndex; if (innerClassIndex != 0 && innerNameIndex != 0) { String newInnerName = clazz.getClassName(innerClassIndex); int index = newInnerName.lastIndexOf(ClassConstants.INNER_CLASS_SEPARATOR); if (index >= 0) { innerClassesInfo.u2innerNameIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newInnerName.substring(index + 1)); } } } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { // Has the descriptor changed? String descriptor = clazz.getString(localVariableInfo.u2descriptorIndex); String newDescriptor = newDescriptor(descriptor, localVariableInfo.referencedClass); if (!descriptor.equals(newDescriptor)) { // Refer to a new Utf8 entry. localVariableInfo.u2descriptorIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newDescriptor); } } // Implementations for LocalVariableTypeInfoVisitor. public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { // Has the signature changed? String signature = clazz.getString(localVariableTypeInfo.u2signatureIndex); String newSignature = newDescriptor(signature, localVariableTypeInfo.referencedClasses); if (!signature.equals(newSignature)) { localVariableTypeInfo.u2signatureIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newSignature); } } // Implementations for AnnotationVisitor. public void visitAnnotation(Clazz clazz, Annotation annotation) { // Compute the new type name. String typeName = clazz.getString(annotation.u2typeIndex); String newTypeName = newDescriptor(typeName, annotation.referencedClasses); if (!typeName.equals(newTypeName)) { // Refer to a new Utf8 entry. annotation.u2typeIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newTypeName); } // Fix the element values. annotation.elementValuesAccept(clazz, this); } // Implementations for ElementValueVisitor. public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) { } public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) { // Compute the new type name. String typeName = clazz.getString(enumConstantElementValue.u2typeNameIndex); String newTypeName = newDescriptor(typeName, enumConstantElementValue.referencedClasses); if (!typeName.equals(newTypeName)) { // Refer to a new Utf8 entry. enumConstantElementValue.u2typeNameIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newTypeName); } } public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) { // Compute the new class name. String className = clazz.getString(classElementValue.u2classInfoIndex); String newClassName = newDescriptor(className, classElementValue.referencedClasses); if (!className.equals(newClassName)) { // Refer to a new Utf8 entry. classElementValue.u2classInfoIndex = constantPoolEditor.addUtf8Constant((ProgramClass)clazz, newClassName); } } public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) { // Fix the annotation. annotationElementValue.annotationAccept(clazz, this); } public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) { // Fix the element values. arrayElementValue.elementValuesAccept(clazz, annotation, this); } // Small utility methods. private static String newDescriptor(String descriptor, Clazz referencedClass) { // If there is no referenced class, the descriptor won't change. if (referencedClass == null) { return descriptor; } // Unravel and reconstruct the class element of the descriptor. DescriptorClassEnumeration descriptorClassEnumeration = new DescriptorClassEnumeration(descriptor); StringBuffer newDescriptorBuffer = new StringBuffer(descriptor.length()); newDescriptorBuffer.append(descriptorClassEnumeration.nextFluff()); // Only if the descriptor contains a class name (e.g. with an array of // primitive types), the descriptor can change. if (descriptorClassEnumeration.hasMoreClassNames()) { String className = descriptorClassEnumeration.nextClassName(); String fluff = descriptorClassEnumeration.nextFluff(); String newClassName = newClassName(className, referencedClass); newDescriptorBuffer.append(newClassName); newDescriptorBuffer.append(fluff); } return newDescriptorBuffer.toString(); } private static String newDescriptor(String descriptor, Clazz[] referencedClasses) { // If there are no referenced classes, the descriptor won't change. if (referencedClasses == null || referencedClasses.length == 0) { return descriptor; } // Unravel and reconstruct the class elements of the descriptor. DescriptorClassEnumeration descriptorClassEnumeration = new DescriptorClassEnumeration(descriptor); StringBuffer newDescriptorBuffer = new StringBuffer(descriptor.length()); newDescriptorBuffer.append(descriptorClassEnumeration.nextFluff()); int index = 0; while (descriptorClassEnumeration.hasMoreClassNames()) { String className = descriptorClassEnumeration.nextClassName(); String fluff = descriptorClassEnumeration.nextFluff(); String newClassName = newClassName(className, referencedClasses[index++]); newDescriptorBuffer.append(newClassName); newDescriptorBuffer.append(fluff); } return newDescriptorBuffer.toString(); } /** * Returns a unique class member name, based on the given name and descriptor. */ private String newUniqueMemberName(String name, String descriptor) { // TODO: Avoid duplicate constructors. return name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ? ClassConstants.INTERNAL_METHOD_NAME_INIT : name + ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); } /** * Returns the new class name based on the given class name and the new * name of the given referenced class. Class names of array types * are handled properly. */ private static String newClassName(String className, Clazz referencedClass) { // If there is no referenced class, the class name won't change. if (referencedClass == null) { return className; } // Reconstruct the class name. String newClassName = referencedClass.getName(); // Is it an array type? if (className.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY) { // Add the array prefixes and suffix "[L...;". newClassName = className.substring(0, className.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1) + newClassName + ClassConstants.INTERNAL_TYPE_CLASS_END; } return newClassName; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -