summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/convert/ClassIdentity.java')
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassIdentity.java167
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
37public class ClassIdentity { 37public 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) {