1 21 package proguard.optimize.peephole; 22 23 import proguard.classfile.*; 24 import proguard.classfile.constant.*; 25 import proguard.classfile.constant.visitor.ConstantVisitor; 26 import proguard.classfile.editor.*; 27 import proguard.classfile.util.SimplifiedVisitor; 28 import proguard.classfile.visitor.ClassVisitor; 29 import proguard.optimize.info.SingleImplementationMarker; 30 31 44 public class SingleImplementationFixer 45 extends SimplifiedVisitor 46 implements ClassVisitor, 47 ConstantVisitor 48 { 49 private ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(); 50 51 52 54 public void visitProgramClass(ProgramClass programClass) 55 { 56 Clazz singleImplementationClass = 58 SingleImplementationMarker.singleImplementation(programClass); 59 60 if (singleImplementationClass != null) 61 { 62 fixThisClassReference(programClass); 64 65 fixInterfaceReference((ProgramClass)programClass.subClasses[0], 67 programClass); 68 } 69 70 programClass.constantPoolEntriesAccept(this); 72 } 73 74 75 77 public void visitAnyConstant(Clazz clazz, Constant constant) {} 78 79 80 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 81 { 82 Clazz singleImplementationClass = 85 SingleImplementationMarker.singleImplementation(fieldrefConstant.referencedClass); 86 87 if (singleImplementationClass != null) 88 { 89 fixFieldrefClassReference((ProgramClass)clazz, 91 fieldrefConstant); 92 } 93 } 94 95 96 98 101 private void fixThisClassReference(ProgramClass programClass) 102 { 103 int nameIndex = 107 constantPoolEditor.addUtf8Constant(programClass, 108 programClass.getName()); 109 programClass.u2thisClass = 110 constantPoolEditor.addConstant(programClass, 111 new ClassConstant(nameIndex, 112 programClass)); 113 } 114 115 116 119 private void fixInterfaceReference(ProgramClass programClass, 120 ProgramClass interfaceClass) 121 { 122 String interfaceName = interfaceClass.getName(); 124 125 int interfacesCount = programClass.u2interfacesCount; 126 for (int index = 0; index < interfacesCount; index++) 127 { 128 if (interfaceName.equals(programClass.getInterfaceName(index))) 129 { 130 int nameIndex = 135 constantPoolEditor.addUtf8Constant(programClass, 136 interfaceName); 137 programClass.u2interfaces[index] = 138 constantPoolEditor.addConstant(programClass, 139 new ClassConstant(nameIndex, 140 interfaceClass)); 141 break; 142 143 } 144 } 145 } 146 147 148 153 private void fixFieldrefClassReference(ProgramClass programClass, 154 FieldrefConstant fieldrefConstant) 155 { 156 Clazz referencedClass = fieldrefConstant.referencedClass; 157 158 int nameIndex = 162 constantPoolEditor.addUtf8Constant(programClass, 163 fieldrefConstant.getClassName(programClass)); 164 fieldrefConstant.u2classIndex = 165 constantPoolEditor.addConstant(programClass, 166 new ClassConstant(nameIndex, 167 referencedClass)); 168 } 169 } 170 | Popular Tags |