diff options
Diffstat (limited to 'src/cuchaz/enigma/convert/ClassIdentity.java')
| -rw-r--r-- | src/cuchaz/enigma/convert/ClassIdentity.java | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/src/cuchaz/enigma/convert/ClassIdentity.java b/src/cuchaz/enigma/convert/ClassIdentity.java index b514012..3736a53 100644 --- a/src/cuchaz/enigma/convert/ClassIdentity.java +++ b/src/cuchaz/enigma/convert/ClassIdentity.java | |||
| @@ -52,9 +52,10 @@ import cuchaz.enigma.mapping.BehaviorEntry; | |||
| 52 | import cuchaz.enigma.mapping.ClassEntry; | 52 | import cuchaz.enigma.mapping.ClassEntry; |
| 53 | import cuchaz.enigma.mapping.ClassNameReplacer; | 53 | import cuchaz.enigma.mapping.ClassNameReplacer; |
| 54 | import cuchaz.enigma.mapping.Entry; | 54 | import cuchaz.enigma.mapping.Entry; |
| 55 | import cuchaz.enigma.mapping.FieldEntry; | ||
| 56 | import cuchaz.enigma.mapping.EntryFactory; | 55 | import cuchaz.enigma.mapping.EntryFactory; |
| 56 | import cuchaz.enigma.mapping.FieldEntry; | ||
| 57 | import cuchaz.enigma.mapping.Signature; | 57 | import cuchaz.enigma.mapping.Signature; |
| 58 | import cuchaz.enigma.mapping.Type; | ||
| 58 | 59 | ||
| 59 | public class ClassIdentity { | 60 | public class ClassIdentity { |
| 60 | 61 | ||
| @@ -68,7 +69,45 @@ public class ClassIdentity { | |||
| 68 | private Multiset<String> m_implements; | 69 | private Multiset<String> m_implements; |
| 69 | private Multiset<String> m_implementations; | 70 | private Multiset<String> m_implementations; |
| 70 | private Multiset<String> m_references; | 71 | private Multiset<String> m_references; |
| 71 | 72 | ||
| 73 | private final ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { | ||
| 74 | |||
| 75 | private Map<String,String> m_classNames = Maps.newHashMap(); | ||
| 76 | |||
| 77 | @Override | ||
| 78 | public String replace(String className) { | ||
| 79 | |||
| 80 | // classes not in the none package can be passed through | ||
| 81 | ClassEntry classEntry = new ClassEntry(className); | ||
| 82 | if (!classEntry.getPackageName().equals(Constants.NonePackage)) { | ||
| 83 | return className; | ||
| 84 | } | ||
| 85 | |||
| 86 | // is this class ourself? | ||
| 87 | if (className.equals(m_classEntry.getName())) { | ||
| 88 | return "CSelf"; | ||
| 89 | } | ||
| 90 | |||
| 91 | // try the namer | ||
| 92 | if (m_namer != null) { | ||
| 93 | String newName = m_namer.getName(className); | ||
| 94 | if (newName != null) { | ||
| 95 | return newName; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | // otherwise, use local naming | ||
| 100 | if (!m_classNames.containsKey(className)) { | ||
| 101 | m_classNames.put(className, getNewClassName()); | ||
| 102 | } | ||
| 103 | return m_classNames.get(className); | ||
| 104 | } | ||
| 105 | |||
| 106 | private String getNewClassName() { | ||
| 107 | return String.format("C%03d", m_classNames.size()); | ||
| 108 | } | ||
| 109 | }; | ||
| 110 | |||
| 72 | public ClassIdentity(CtClass c, SidedClassNamer namer, JarIndex index, boolean useReferences) { | 111 | public ClassIdentity(CtClass c, SidedClassNamer namer, JarIndex index, boolean useReferences) { |
| 73 | m_namer = namer; | 112 | m_namer = namer; |
| 74 | 113 | ||
| @@ -77,7 +116,7 @@ public class ClassIdentity { | |||
| 77 | m_classEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); | 116 | m_classEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); |
| 78 | m_fields = HashMultiset.create(); | 117 | m_fields = HashMultiset.create(); |
| 79 | for (CtField field : c.getDeclaredFields()) { | 118 | for (CtField field : c.getDeclaredFields()) { |
| 80 | m_fields.add(scrubSignature(field.getSignature())); | 119 | m_fields.add(scrubType(field.getSignature())); |
| 81 | } | 120 | } |
| 82 | m_methods = HashMultiset.create(); | 121 | m_methods = HashMultiset.create(); |
| 83 | for (CtMethod method : c.getDeclaredMethods()) { | 122 | for (CtMethod method : c.getDeclaredMethods()) { |
| @@ -93,11 +132,11 @@ public class ClassIdentity { | |||
| 93 | } | 132 | } |
| 94 | m_extends = ""; | 133 | m_extends = ""; |
| 95 | if (c.getClassFile().getSuperclass() != null) { | 134 | if (c.getClassFile().getSuperclass() != null) { |
| 96 | m_extends = scrubClassName(c.getClassFile().getSuperclass()); | 135 | m_extends = scrubClassName(Descriptor.toJvmName(c.getClassFile().getSuperclass())); |
| 97 | } | 136 | } |
| 98 | m_implements = HashMultiset.create(); | 137 | m_implements = HashMultiset.create(); |
| 99 | for (String interfaceName : c.getClassFile().getInterfaces()) { | 138 | for (String interfaceName : c.getClassFile().getInterfaces()) { |
| 100 | m_implements.add(scrubClassName(interfaceName)); | 139 | m_implements.add(scrubClassName(Descriptor.toJvmName(interfaceName))); |
| 101 | } | 140 | } |
| 102 | 141 | ||
| 103 | // stuff from the jar index | 142 | // stuff from the jar index |
| @@ -132,9 +171,14 @@ public class ClassIdentity { | |||
| 132 | 171 | ||
| 133 | private void addReference(EntryReference<? extends Entry,BehaviorEntry> reference) { | 172 | private void addReference(EntryReference<? extends Entry,BehaviorEntry> reference) { |
| 134 | if (reference.context.getSignature() != null) { | 173 | if (reference.context.getSignature() != null) { |
| 135 | m_references.add(String.format("%s_%s", scrubClassName(reference.context.getClassName()), scrubSignature(reference.context.getSignature()))); | 174 | m_references.add(String.format("%s_%s", |
| 175 | scrubClassName(reference.context.getClassName()), | ||
| 176 | scrubSignature(reference.context.getSignature()) | ||
| 177 | )); | ||
| 136 | } else { | 178 | } else { |
| 137 | m_references.add(String.format("%s_<clinit>", scrubClassName(reference.context.getClassName()))); | 179 | m_references.add(String.format("%s_<clinit>", |
| 180 | scrubClassName(reference.context.getClassName()) | ||
| 181 | )); | ||
| 138 | } | 182 | } |
| 139 | } | 183 | } |
| 140 | 184 | ||
| @@ -194,52 +238,27 @@ public class ClassIdentity { | |||
| 194 | } | 238 | } |
| 195 | 239 | ||
| 196 | private String scrubClassName(String className) { | 240 | private String scrubClassName(String className) { |
| 197 | return scrubSignature("L" + Descriptor.toJvmName(className) + ";"); | 241 | return m_classNameReplacer.replace(className); |
| 242 | } | ||
| 243 | |||
| 244 | private String scrubType(String typeName) { | ||
| 245 | return scrubType(new Type(typeName)).toString(); | ||
| 246 | } | ||
| 247 | |||
| 248 | private Type scrubType(Type type) { | ||
| 249 | if (type.hasClass()) { | ||
| 250 | return new Type(type, m_classNameReplacer); | ||
| 251 | } else { | ||
| 252 | return type; | ||
| 253 | } | ||
| 198 | } | 254 | } |
| 199 | 255 | ||
| 200 | private String scrubSignature(String signature) { | 256 | private String scrubSignature(String signature) { |
| 201 | return scrubSignature(new Signature(signature)); | 257 | return scrubSignature(new Signature(signature)).toString(); |
| 202 | } | 258 | } |
| 203 | 259 | ||
| 204 | private String scrubSignature(Signature signature) { | 260 | private Signature scrubSignature(Signature signature) { |
| 205 | 261 | return new Signature(signature, m_classNameReplacer); | |
| 206 | return new Signature(signature, new ClassNameReplacer() { | ||
| 207 | |||
| 208 | private Map<String,String> m_classNames = Maps.newHashMap(); | ||
| 209 | |||
| 210 | @Override | ||
| 211 | public String replace(String className) { | ||
| 212 | |||
| 213 | // classes not in the none package can be passed through | ||
| 214 | ClassEntry classEntry = new ClassEntry(className); | ||
| 215 | if (!classEntry.getPackageName().equals(Constants.NonePackage)) { | ||
| 216 | return className; | ||
| 217 | } | ||
| 218 | |||
| 219 | // is this class ourself? | ||
| 220 | if (className.equals(m_classEntry.getName())) { | ||
| 221 | return "CSelf"; | ||
| 222 | } | ||
| 223 | |||
| 224 | // try the namer | ||
| 225 | if (m_namer != null) { | ||
| 226 | String newName = m_namer.getName(className); | ||
| 227 | if (newName != null) { | ||
| 228 | return newName; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | // otherwise, use local naming | ||
| 233 | if (!m_classNames.containsKey(className)) { | ||
| 234 | m_classNames.put(className, getNewClassName()); | ||
| 235 | } | ||
| 236 | return m_classNames.get(className); | ||
| 237 | } | ||
| 238 | |||
| 239 | private String getNewClassName() { | ||
| 240 | return String.format("C%03d", m_classNames.size()); | ||
| 241 | } | ||
| 242 | }).toString(); | ||
| 243 | } | 262 | } |
| 244 | 263 | ||
| 245 | private boolean isClassMatchedUniquely(String className) { | 264 | private boolean isClassMatchedUniquely(String className) { |
| @@ -284,7 +303,7 @@ public class ClassIdentity { | |||
| 284 | behavior.instrument(new ExprEditor() { | 303 | behavior.instrument(new ExprEditor() { |
| 285 | @Override | 304 | @Override |
| 286 | public void edit(MethodCall call) { | 305 | public void edit(MethodCall call) { |
| 287 | updateHashWithString(digest, scrubClassName(call.getClassName())); | 306 | updateHashWithString(digest, scrubClassName(Descriptor.toJvmName(call.getClassName()))); |
| 288 | updateHashWithString(digest, scrubSignature(call.getSignature())); | 307 | updateHashWithString(digest, scrubSignature(call.getSignature())); |
| 289 | if (isClassMatchedUniquely(call.getClassName())) { | 308 | if (isClassMatchedUniquely(call.getClassName())) { |
| 290 | updateHashWithString(digest, call.getMethodName()); | 309 | updateHashWithString(digest, call.getMethodName()); |
| @@ -293,8 +312,8 @@ public class ClassIdentity { | |||
| 293 | 312 | ||
| 294 | @Override | 313 | @Override |
| 295 | public void edit(FieldAccess access) { | 314 | public void edit(FieldAccess access) { |
| 296 | updateHashWithString(digest, scrubClassName(access.getClassName())); | 315 | updateHashWithString(digest, scrubClassName(Descriptor.toJvmName(access.getClassName()))); |
| 297 | updateHashWithString(digest, scrubSignature(access.getSignature())); | 316 | updateHashWithString(digest, scrubType(access.getSignature())); |
| 298 | if (isClassMatchedUniquely(access.getClassName())) { | 317 | if (isClassMatchedUniquely(access.getClassName())) { |
| 299 | updateHashWithString(digest, access.getFieldName()); | 318 | updateHashWithString(digest, access.getFieldName()); |
| 300 | } | 319 | } |
| @@ -302,13 +321,13 @@ public class ClassIdentity { | |||
| 302 | 321 | ||
| 303 | @Override | 322 | @Override |
| 304 | public void edit(ConstructorCall call) { | 323 | public void edit(ConstructorCall call) { |
| 305 | updateHashWithString(digest, scrubClassName(call.getClassName())); | 324 | updateHashWithString(digest, scrubClassName(Descriptor.toJvmName(call.getClassName()))); |
| 306 | updateHashWithString(digest, scrubSignature(call.getSignature())); | 325 | updateHashWithString(digest, scrubSignature(call.getSignature())); |
| 307 | } | 326 | } |
| 308 | 327 | ||
| 309 | @Override | 328 | @Override |
| 310 | public void edit(NewExpr expr) { | 329 | public void edit(NewExpr expr) { |
| 311 | updateHashWithString(digest, scrubClassName(expr.getClassName())); | 330 | updateHashWithString(digest, scrubClassName(Descriptor.toJvmName(expr.getClassName()))); |
| 312 | } | 331 | } |
| 313 | }); | 332 | }); |
| 314 | 333 | ||