📄 singleimplementationinliner.java
字号:
int nameAndTypeIndex = cpIndex; if (nameAndTypeIndex != 0) { // Create a new method reference entry. cpIndex = constantPoolEditor.addMethodrefCpInfo((ProgramClassFile)classFile, methodrefCpInfo.getClassIndex(), nameAndTypeIndex, methodrefCpInfo.referencedClassFile, methodrefCpInfo.referencedMemberInfo); } } public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo) { // Create a new ordinary method reference entry, if its referenced class // is an interface with a single implementation, or a a new interface // method reference entry, if its type has changed. cpIndex = 0; classFile.constantPoolEntryAccept(interfaceMethodrefCpInfo.getClassIndex(), this); int classIndex = cpIndex; cpIndex = 0; classFile.constantPoolEntryAccept(interfaceMethodrefCpInfo.getNameAndTypeIndex(), this); int nameAndTypeIndex = cpIndex; if (classIndex != 0) { if (nameAndTypeIndex == 0) { nameAndTypeIndex = interfaceMethodrefCpInfo.getNameAndTypeIndex(); } // See if we can find the referenced method. ClassFile referencedClassFile = singleImplementationClassFile; String name = interfaceMethodrefCpInfo.getName(classFile); String type = interfaceMethodrefCpInfo.getType(classFile); // See if we can find the referenced class membver somewhere in the // hierarchy. MethodInfo referencedMethodInfo = memberFinder.findMethod(referencedClassFile, name, type); referencedClassFile = memberFinder.correspondingClassFile(); // Create an ordinary method reference entry. cpIndex = constantPoolEditor.addMethodrefCpInfo((ProgramClassFile)classFile, classIndex, nameAndTypeIndex, referencedClassFile, referencedMethodInfo); } else if (nameAndTypeIndex != 0) { classIndex = interfaceMethodrefCpInfo.getClassIndex(); // Create an interface method reference entry. cpIndex = constantPoolEditor.addInterfaceMethodrefCpInfo((ProgramClassFile)classFile, classIndex, nameAndTypeIndex, interfaceMethodrefCpInfo.referencedClassFile, interfaceMethodrefCpInfo.referencedMemberInfo); } } public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo) { // Create a new class entry if its referenced class is an interface with // a single implementation. singleImplementationClassFile = SingleImplementationMarker.singleImplementation(classCpInfo.referencedClassFile); if (singleImplementationClassFile != null) { // Create a new class entry. cpIndex = constantPoolEditor.addClassCpInfo((ProgramClassFile)classFile, newClassName(classCpInfo.getName(classFile), singleImplementationClassFile), singleImplementationClassFile); } } public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) { // Create a new name and type entry if any of the referenced classes of // its type is an interface with a single implementation. ClassFile[] referencedClassFiles = updateReferencedClassFiles(nameAndTypeCpInfo.referencedClassFiles); if (referencedClassFiles != null) { // Create a new name and type entry. cpIndex = constantPoolEditor.addNameAndTypeCpInfo((ProgramClassFile)classFile, nameAndTypeCpInfo.getName(classFile), newDescriptor(nameAndTypeCpInfo.getType(classFile), referencedClassFiles), referencedClassFiles); } } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo) { // Create a new type entry if its referenced class is an interface with // a single implementation. ClassFile singleImplementationClassFile = SingleImplementationMarker.singleImplementation(localVariableInfo.referencedClassFile); // Update the type if necessary. if (singleImplementationClassFile != null) { // Refer to a new Utf8 entry. localVariableInfo.u2descriptorIndex = constantPoolEditor.addUtf8CpInfo((ProgramClassFile)classFile, newClassName(classFile.getCpString(localVariableInfo.u2descriptorIndex), singleImplementationClassFile)); } } // Implementations for LocalVariableTypeInfoVisitor. public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo) { // Create a new signature entry if any of the referenced classes of // its type is an interface with a single implementation. ClassFile[] referencedClassFiles = updateReferencedClassFiles(localVariableTypeInfo.referencedClassFiles); // Update the signature if necessary. if (referencedClassFiles != null) { localVariableTypeInfo.u2signatureIndex = constantPoolEditor.addUtf8CpInfo((ProgramClassFile)classFile, newDescriptor(classFile.getCpString(localVariableTypeInfo.u2signatureIndex), referencedClassFiles)); } } // Small utility methods. /** * Updates the given array of referenced class files, if the refer to an * interface with a single implementation. Returns a new array if it * needed to be updated, or <code>null</code> otherwise. */ private ClassFile[] updateReferencedClassFiles(ClassFile[] referencedClassFiles) { ClassFile[] newReferencedClassFiles = null; // Check all referenced classes. if (referencedClassFiles != null && referencedClassFilesChanged(referencedClassFiles)) { // Create a new array to copy the elements. newReferencedClassFiles = new ClassFile[referencedClassFiles.length]; // Update all referenced classes. for (int index = 0; index < referencedClassFiles.length; index++) { ClassFile referencedClassFile = referencedClassFiles[index]; // See if we have is an interface with a single implementation. ClassFile singleImplementationClassFile = SingleImplementationMarker.singleImplementation(referencedClassFile); // Update or copy the referenced class file. newReferencedClassFiles[index] = singleImplementationClassFile != null ? singleImplementationClassFile : referencedClassFile; } } return newReferencedClassFiles; } private boolean referencedClassFilesChanged(ClassFile[] referencedClassFiles) { // Check all referenced classes. for (int index = 0; index < referencedClassFiles.length; index++) { // See if we have is an interface with a single implementation. if (SingleImplementationMarker.singleImplementation(referencedClassFiles[index]) != null) { // We've found an element that needs to be updated. return true; } } return false; } /** * Returns the new descriptor based on the given descriptor and the new * names of the given referenced class files. */ private String newDescriptor(String descriptor, ClassFile[] referencedClassFiles) { // Unravel and reconstruct the class elements of the descriptor. DescriptorClassEnumeration descriptorClassEnumeration = new DescriptorClassEnumeration(descriptor); String newDescriptor = descriptorClassEnumeration.nextFluff(); int index = 0; while (descriptorClassEnumeration.hasMoreClassNames()) { String className = descriptorClassEnumeration.nextClassName(); String fluff = descriptorClassEnumeration.nextFluff(); String newClassName = newClassName(className, referencedClassFiles[index++]); // Fall back on the original class name if there is no new name. if (newClassName == null) { newClassName = className; } newDescriptor = newDescriptor + newClassName + fluff; } return newDescriptor; } /** * Returns the new class name based on the given class name and the new * name of the given referenced class file. Class names of array types * are handled properly. */ private String newClassName(String className, ClassFile referencedClassFile) { // If there is no new class name, the descriptor doesn't change. if (referencedClassFile == null) { return className; } // Reconstruct the class name. String newClassName = referencedClassFile.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 + -