diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/convert/ClassIdentity.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/convert/ClassIdentity.java | 167 |
1 files changed, 82 insertions, 85 deletions
diff --git a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java index 76c48ab..2317a3d 100644 --- a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java +++ b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java | |||
| @@ -36,18 +36,18 @@ import javassist.expr.*; | |||
| 36 | 36 | ||
| 37 | public class ClassIdentity { | 37 | public class ClassIdentity { |
| 38 | 38 | ||
| 39 | private ClassEntry m_classEntry; | 39 | private ClassEntry classEntry; |
| 40 | private SidedClassNamer m_namer; | 40 | private SidedClassNamer namer; |
| 41 | private Multiset<String> m_fields; | 41 | private Multiset<String> fields; |
| 42 | private Multiset<String> m_methods; | 42 | private Multiset<String> methods; |
| 43 | private Multiset<String> m_constructors; | 43 | private Multiset<String> constructors; |
| 44 | private String m_staticInitializer; | 44 | private String staticInitializer; |
| 45 | private String m_extends; | 45 | private String extendz; |
| 46 | private Multiset<String> m_implements; | 46 | private Multiset<String> implementz; |
| 47 | private Set<String> m_stringLiterals; | 47 | private Set<String> stringLiterals; |
| 48 | private Multiset<String> m_implementations; | 48 | private Multiset<String> implementations; |
| 49 | private Multiset<String> m_references; | 49 | private Multiset<String> references; |
| 50 | private String m_outer; | 50 | private String outer; |
| 51 | 51 | ||
| 52 | private final ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { | 52 | private final ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { |
| 53 | 53 | ||
| @@ -63,13 +63,13 @@ public class ClassIdentity { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | // is this class ourself? | 65 | // is this class ourself? |
| 66 | if (className.equals(m_classEntry.getName())) { | 66 | if (className.equals(classEntry.getName())) { |
| 67 | return "CSelf"; | 67 | return "CSelf"; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | // try the namer | 70 | // try the namer |
| 71 | if (m_namer != null) { | 71 | if (namer != null) { |
| 72 | String newName = m_namer.getName(className); | 72 | String newName = namer.getName(className); |
| 73 | if (newName != null) { | 73 | if (newName != null) { |
| 74 | return newName; | 74 | return newName; |
| 75 | } | 75 | } |
| @@ -88,58 +88,58 @@ public class ClassIdentity { | |||
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | public ClassIdentity(CtClass c, SidedClassNamer namer, JarIndex index, boolean useReferences) { | 90 | public ClassIdentity(CtClass c, SidedClassNamer namer, JarIndex index, boolean useReferences) { |
| 91 | m_namer = namer; | 91 | this.namer = namer; |
| 92 | 92 | ||
| 93 | // stuff from the bytecode | 93 | // stuff from the bytecode |
| 94 | 94 | ||
| 95 | m_classEntry = EntryFactory.getClassEntry(c); | 95 | this.classEntry = EntryFactory.getClassEntry(c); |
| 96 | m_fields = HashMultiset.create(); | 96 | this.fields = HashMultiset.create(); |
| 97 | for (CtField field : c.getDeclaredFields()) { | 97 | for (CtField field : c.getDeclaredFields()) { |
| 98 | m_fields.add(scrubType(field.getSignature())); | 98 | this.fields.add(scrubType(field.getSignature())); |
| 99 | } | 99 | } |
| 100 | m_methods = HashMultiset.create(); | 100 | this.methods = HashMultiset.create(); |
| 101 | for (CtMethod method : c.getDeclaredMethods()) { | 101 | for (CtMethod method : c.getDeclaredMethods()) { |
| 102 | m_methods.add(scrubSignature(method.getSignature()) + "0x" + getBehaviorSignature(method)); | 102 | this.methods.add(scrubSignature(method.getSignature()) + "0x" + getBehaviorSignature(method)); |
| 103 | } | 103 | } |
| 104 | m_constructors = HashMultiset.create(); | 104 | this.constructors = HashMultiset.create(); |
| 105 | for (CtConstructor constructor : c.getDeclaredConstructors()) { | 105 | for (CtConstructor constructor : c.getDeclaredConstructors()) { |
| 106 | m_constructors.add(scrubSignature(constructor.getSignature()) + "0x" + getBehaviorSignature(constructor)); | 106 | this.constructors.add(scrubSignature(constructor.getSignature()) + "0x" + getBehaviorSignature(constructor)); |
| 107 | } | 107 | } |
| 108 | m_staticInitializer = ""; | 108 | this.staticInitializer = ""; |
| 109 | if (c.getClassInitializer() != null) { | 109 | if (c.getClassInitializer() != null) { |
| 110 | m_staticInitializer = getBehaviorSignature(c.getClassInitializer()); | 110 | this.staticInitializer = getBehaviorSignature(c.getClassInitializer()); |
| 111 | } | 111 | } |
| 112 | m_extends = ""; | 112 | this.extendz = ""; |
| 113 | if (c.getClassFile().getSuperclass() != null) { | 113 | if (c.getClassFile().getSuperclass() != null) { |
| 114 | m_extends = scrubClassName(Descriptor.toJvmName(c.getClassFile().getSuperclass())); | 114 | this.extendz = scrubClassName(Descriptor.toJvmName(c.getClassFile().getSuperclass())); |
| 115 | } | 115 | } |
| 116 | m_implements = HashMultiset.create(); | 116 | this.implementz = HashMultiset.create(); |
| 117 | for (String interfaceName : c.getClassFile().getInterfaces()) { | 117 | for (String interfaceName : c.getClassFile().getInterfaces()) { |
| 118 | m_implements.add(scrubClassName(Descriptor.toJvmName(interfaceName))); | 118 | this.implementz.add(scrubClassName(Descriptor.toJvmName(interfaceName))); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | m_stringLiterals = Sets.newHashSet(); | 121 | this.stringLiterals = Sets.newHashSet(); |
| 122 | ConstPool constants = c.getClassFile().getConstPool(); | 122 | ConstPool constants = c.getClassFile().getConstPool(); |
| 123 | for (int i = 1; i < constants.getSize(); i++) { | 123 | for (int i = 1; i < constants.getSize(); i++) { |
| 124 | if (constants.getTag(i) == ConstPool.CONST_String) { | 124 | if (constants.getTag(i) == ConstPool.CONST_String) { |
| 125 | m_stringLiterals.add(constants.getStringInfo(i)); | 125 | this.stringLiterals.add(constants.getStringInfo(i)); |
| 126 | } | 126 | } |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | // stuff from the jar index | 129 | // stuff from the jar index |
| 130 | 130 | ||
| 131 | m_implementations = HashMultiset.create(); | 131 | this.implementations = HashMultiset.create(); |
| 132 | ClassImplementationsTreeNode implementationsNode = index.getClassImplementations(null, m_classEntry); | 132 | ClassImplementationsTreeNode implementationsNode = index.getClassImplementations(null, this.classEntry); |
| 133 | if (implementationsNode != null) { | 133 | if (implementationsNode != null) { |
| 134 | @SuppressWarnings("unchecked") | 134 | @SuppressWarnings("unchecked") |
| 135 | Enumeration<ClassImplementationsTreeNode> implementations = implementationsNode.children(); | 135 | Enumeration<ClassImplementationsTreeNode> implementations = implementationsNode.children(); |
| 136 | while (implementations.hasMoreElements()) { | 136 | while (implementations.hasMoreElements()) { |
| 137 | ClassImplementationsTreeNode node = implementations.nextElement(); | 137 | ClassImplementationsTreeNode node = implementations.nextElement(); |
| 138 | m_implementations.add(scrubClassName(node.getClassEntry().getName())); | 138 | this.implementations.add(scrubClassName(node.getClassEntry().getName())); |
| 139 | } | 139 | } |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | m_references = HashMultiset.create(); | 142 | this.references = HashMultiset.create(); |
| 143 | if (useReferences) { | 143 | if (useReferences) { |
| 144 | for (CtField field : c.getDeclaredFields()) { | 144 | for (CtField field : c.getDeclaredFields()) { |
| 145 | FieldEntry fieldEntry = EntryFactory.getFieldEntry(field); | 145 | FieldEntry fieldEntry = EntryFactory.getFieldEntry(field); |
| @@ -151,79 +151,79 @@ public class ClassIdentity { | |||
| 151 | } | 151 | } |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | m_outer = null; | 154 | this.outer = null; |
| 155 | if (m_classEntry.isInnerClass()) { | 155 | if (this.classEntry.isInnerClass()) { |
| 156 | m_outer = m_classEntry.getOuterClassName(); | 156 | this.outer = this.classEntry.getOuterClassName(); |
| 157 | } | 157 | } |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | private void addReference(EntryReference<? extends Entry, BehaviorEntry> reference) { | 160 | private void addReference(EntryReference<? extends Entry, BehaviorEntry> reference) { |
| 161 | if (reference.context.getSignature() != null) { | 161 | if (reference.context.getSignature() != null) { |
| 162 | m_references.add(String.format("%s_%s", | 162 | this.references.add(String.format("%s_%s", |
| 163 | scrubClassName(reference.context.getClassName()), | 163 | scrubClassName(reference.context.getClassName()), |
| 164 | scrubSignature(reference.context.getSignature()) | 164 | scrubSignature(reference.context.getSignature()) |
| 165 | )); | 165 | )); |
| 166 | } else { | 166 | } else { |
| 167 | m_references.add(String.format("%s_<clinit>", | 167 | this.references.add(String.format("%s_<clinit>", |
| 168 | scrubClassName(reference.context.getClassName()) | 168 | scrubClassName(reference.context.getClassName()) |
| 169 | )); | 169 | )); |
| 170 | } | 170 | } |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | public ClassEntry getClassEntry() { | 173 | public ClassEntry getClassEntry() { |
| 174 | return m_classEntry; | 174 | return this.classEntry; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | @Override | 177 | @Override |
| 178 | public String toString() { | 178 | public String toString() { |
| 179 | StringBuilder buf = new StringBuilder(); | 179 | StringBuilder buf = new StringBuilder(); |
| 180 | buf.append("class: "); | 180 | buf.append("class: "); |
| 181 | buf.append(m_classEntry.getName()); | 181 | buf.append(this.classEntry.getName()); |
| 182 | buf.append(" "); | 182 | buf.append(" "); |
| 183 | buf.append(hashCode()); | 183 | buf.append(hashCode()); |
| 184 | buf.append("\n"); | 184 | buf.append("\n"); |
| 185 | for (String field : m_fields) { | 185 | for (String field : this.fields) { |
| 186 | buf.append("\tfield "); | 186 | buf.append("\tfield "); |
| 187 | buf.append(field); | 187 | buf.append(field); |
| 188 | buf.append("\n"); | 188 | buf.append("\n"); |
| 189 | } | 189 | } |
| 190 | for (String method : m_methods) { | 190 | for (String method : this.methods) { |
| 191 | buf.append("\tmethod "); | 191 | buf.append("\tmethod "); |
| 192 | buf.append(method); | 192 | buf.append(method); |
| 193 | buf.append("\n"); | 193 | buf.append("\n"); |
| 194 | } | 194 | } |
| 195 | for (String constructor : m_constructors) { | 195 | for (String constructor : this.constructors) { |
| 196 | buf.append("\tconstructor "); | 196 | buf.append("\tconstructor "); |
| 197 | buf.append(constructor); | 197 | buf.append(constructor); |
| 198 | buf.append("\n"); | 198 | buf.append("\n"); |
| 199 | } | 199 | } |
| 200 | if (m_staticInitializer.length() > 0) { | 200 | if (this.staticInitializer.length() > 0) { |
| 201 | buf.append("\tinitializer "); | 201 | buf.append("\tinitializer "); |
| 202 | buf.append(m_staticInitializer); | 202 | buf.append(this.staticInitializer); |
| 203 | buf.append("\n"); | 203 | buf.append("\n"); |
| 204 | } | 204 | } |
| 205 | if (m_extends.length() > 0) { | 205 | if (this.extendz.length() > 0) { |
| 206 | buf.append("\textends "); | 206 | buf.append("\textends "); |
| 207 | buf.append(m_extends); | 207 | buf.append(this.extendz); |
| 208 | buf.append("\n"); | 208 | buf.append("\n"); |
| 209 | } | 209 | } |
| 210 | for (String interfaceName : m_implements) { | 210 | for (String interfaceName : this.implementz) { |
| 211 | buf.append("\timplements "); | 211 | buf.append("\timplements "); |
| 212 | buf.append(interfaceName); | 212 | buf.append(interfaceName); |
| 213 | buf.append("\n"); | 213 | buf.append("\n"); |
| 214 | } | 214 | } |
| 215 | for (String implementation : m_implementations) { | 215 | for (String implementation : this.implementations) { |
| 216 | buf.append("\timplemented by "); | 216 | buf.append("\timplemented by "); |
| 217 | buf.append(implementation); | 217 | buf.append(implementation); |
| 218 | buf.append("\n"); | 218 | buf.append("\n"); |
| 219 | } | 219 | } |
| 220 | for (String reference : m_references) { | 220 | for (String reference : this.references) { |
| 221 | buf.append("\treference "); | 221 | buf.append("\treference "); |
| 222 | buf.append(reference); | 222 | buf.append(reference); |
| 223 | buf.append("\n"); | 223 | buf.append("\n"); |
| 224 | } | 224 | } |
| 225 | buf.append("\touter "); | 225 | buf.append("\touter "); |
| 226 | buf.append(m_outer); | 226 | buf.append(this.outer); |
| 227 | buf.append("\n"); | 227 | buf.append("\n"); |
| 228 | return buf.toString(); | 228 | return buf.toString(); |
| 229 | } | 229 | } |
| @@ -253,7 +253,7 @@ public class ClassIdentity { | |||
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | private boolean isClassMatchedUniquely(String className) { | 255 | private boolean isClassMatchedUniquely(String className) { |
| 256 | return m_namer != null && m_namer.getName(Descriptor.toJvmName(className)) != null; | 256 | return this.namer != null && this.namer.getName(Descriptor.toJvmName(className)) != null; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | private String getBehaviorSignature(CtBehavior behavior) { | 259 | private String getBehaviorSignature(CtBehavior behavior) { |
| @@ -361,56 +361,53 @@ public class ClassIdentity { | |||
| 361 | 361 | ||
| 362 | @Override | 362 | @Override |
| 363 | public boolean equals(Object other) { | 363 | public boolean equals(Object other) { |
| 364 | if (other instanceof ClassIdentity) { | 364 | return other instanceof ClassIdentity && equals((ClassIdentity) other); |
| 365 | return equals((ClassIdentity) other); | ||
| 366 | } | ||
| 367 | return false; | ||
| 368 | } | 365 | } |
| 369 | 366 | ||
| 370 | public boolean equals(ClassIdentity other) { | 367 | public boolean equals(ClassIdentity other) { |
| 371 | return m_fields.equals(other.m_fields) | 368 | return this.fields.equals(other.fields) |
| 372 | && m_methods.equals(other.m_methods) | 369 | && this.methods.equals(other.methods) |
| 373 | && m_constructors.equals(other.m_constructors) | 370 | && this.constructors.equals(other.constructors) |
| 374 | && m_staticInitializer.equals(other.m_staticInitializer) | 371 | && this.staticInitializer.equals(other.staticInitializer) |
| 375 | && m_extends.equals(other.m_extends) | 372 | && this.extendz.equals(other.extendz) |
| 376 | && m_implements.equals(other.m_implements) | 373 | && this.implementz.equals(other.implementz) |
| 377 | && m_implementations.equals(other.m_implementations) | 374 | && this.implementations.equals(other.implementations) |
| 378 | && m_references.equals(other.m_references); | 375 | && this.references.equals(other.references); |
| 379 | } | 376 | } |
| 380 | 377 | ||
| 381 | @Override | 378 | @Override |
| 382 | public int hashCode() { | 379 | public int hashCode() { |
| 383 | List<Object> objs = Lists.newArrayList(); | 380 | List<Object> objs = Lists.newArrayList(); |
| 384 | objs.addAll(m_fields); | 381 | objs.addAll(this.fields); |
| 385 | objs.addAll(m_methods); | 382 | objs.addAll(this.methods); |
| 386 | objs.addAll(m_constructors); | 383 | objs.addAll(this.constructors); |
| 387 | objs.add(m_staticInitializer); | 384 | objs.add(this.staticInitializer); |
| 388 | objs.add(m_extends); | 385 | objs.add(this.extendz); |
| 389 | objs.addAll(m_implements); | 386 | objs.addAll(this.implementz); |
| 390 | objs.addAll(m_implementations); | 387 | objs.addAll(this.implementations); |
| 391 | objs.addAll(m_references); | 388 | objs.addAll(this.references); |
| 392 | return Util.combineHashesOrdered(objs); | 389 | return Util.combineHashesOrdered(objs); |
| 393 | } | 390 | } |
| 394 | 391 | ||
| 395 | public int getMatchScore(ClassIdentity other) { | 392 | public int getMatchScore(ClassIdentity other) { |
| 396 | return 2 * getNumMatches(m_extends, other.m_extends) | 393 | return 2 * getNumMatches(this.extendz, other.extendz) |
| 397 | + 2 * getNumMatches(m_outer, other.m_outer) | 394 | + 2 * getNumMatches(this.outer, other.outer) |
| 398 | + 2 * getNumMatches(m_implements, other.m_implements) | 395 | + 2 * getNumMatches(this.implementz, other.implementz) |
| 399 | + getNumMatches(m_stringLiterals, other.m_stringLiterals) | 396 | + getNumMatches(this.stringLiterals, other.stringLiterals) |
| 400 | + getNumMatches(m_fields, other.m_fields) | 397 | + getNumMatches(this.fields, other.fields) |
| 401 | + getNumMatches(m_methods, other.m_methods) | 398 | + getNumMatches(this.methods, other.methods) |
| 402 | + getNumMatches(m_constructors, other.m_constructors); | 399 | + getNumMatches(this.constructors, other.constructors); |
| 403 | } | 400 | } |
| 404 | 401 | ||
| 405 | public int getMaxMatchScore() { | 402 | public int getMaxMatchScore() { |
| 406 | return 2 + 2 + 2 * m_implements.size() + m_stringLiterals.size() + m_fields.size() + m_methods.size() + m_constructors.size(); | 403 | return 2 + 2 + 2 * this.implementz.size() + this.stringLiterals.size() + this.fields.size() + this.methods.size() + this.constructors.size(); |
| 407 | } | 404 | } |
| 408 | 405 | ||
| 409 | public boolean matches(CtClass c) { | 406 | public boolean matches(CtClass c) { |
| 410 | // just compare declaration counts | 407 | // just compare declaration counts |
| 411 | return m_fields.size() == c.getDeclaredFields().length | 408 | return this.fields.size() == c.getDeclaredFields().length |
| 412 | && m_methods.size() == c.getDeclaredMethods().length | 409 | && this.methods.size() == c.getDeclaredMethods().length |
| 413 | && m_constructors.size() == c.getDeclaredConstructors().length; | 410 | && this.constructors.size() == c.getDeclaredConstructors().length; |
| 414 | } | 411 | } |
| 415 | 412 | ||
| 416 | private int getNumMatches(Set<String> a, Set<String> b) { | 413 | private int getNumMatches(Set<String> a, Set<String> b) { |