diff options
| author | 2015-03-16 12:29:17 -0400 | |
|---|---|---|
| committer | 2015-03-16 12:29:17 -0400 | |
| commit | c133e05b786ff5357931842581571c046f958c74 (patch) | |
| tree | 9fc998ac7b85828f3b57f04600244c6a79b2b2e8 | |
| parent | Added tag v0.9 beta for changeset 856528c00d1c (diff) | |
| download | enigma-c133e05b786ff5357931842581571c046f958c74.tar.gz enigma-c133e05b786ff5357931842581571c046f958c74.tar.xz enigma-c133e05b786ff5357931842581571c046f958c74.zip | |
fix a zillion issues with inner classes
27 files changed, 333 insertions, 282 deletions
diff --git a/proguard.conf b/proguard.conf index e1f04aee..0d3d60e9 100644 --- a/proguard.conf +++ b/proguard.conf | |||
| @@ -4,4 +4,6 @@ | |||
| 4 | -allowaccessmodification | 4 | -allowaccessmodification |
| 5 | -dontoptimize | 5 | -dontoptimize |
| 6 | -dontshrink | 6 | -dontshrink |
| 7 | -keepparameternames | ||
| 8 | -keepattributes | ||
| 7 | -keep class cuchaz.enigma.inputs.Keep \ No newline at end of file | 9 | -keep class cuchaz.enigma.inputs.Keep \ No newline at end of file |
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index f5012bde..5a23ce5b 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -438,7 +438,13 @@ public class Deobfuscator { | |||
| 438 | public boolean hasDeobfuscatedName(Entry obfEntry) { | 438 | public boolean hasDeobfuscatedName(Entry obfEntry) { |
| 439 | Translator translator = getTranslator(TranslationDirection.Deobfuscating); | 439 | Translator translator = getTranslator(TranslationDirection.Deobfuscating); |
| 440 | if (obfEntry instanceof ClassEntry) { | 440 | if (obfEntry instanceof ClassEntry) { |
| 441 | return translator.translate((ClassEntry)obfEntry) != null; | 441 | ClassEntry obfClass = (ClassEntry)obfEntry; |
| 442 | ClassEntry translated = translator.translateEntry(obfClass); | ||
| 443 | if (obfClass.isInnerClass()) { | ||
| 444 | return !obfClass.getInnermostClassName().equals(translated.getInnermostClassName()); | ||
| 445 | } else { | ||
| 446 | return !obfClass.equals(translated); | ||
| 447 | } | ||
| 442 | } else if (obfEntry instanceof FieldEntry) { | 448 | } else if (obfEntry instanceof FieldEntry) { |
| 443 | return translator.translate((FieldEntry)obfEntry) != null; | 449 | return translator.translate((FieldEntry)obfEntry) != null; |
| 444 | } else if (obfEntry instanceof MethodEntry) { | 450 | } else if (obfEntry instanceof MethodEntry) { |
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java index 7b57cfa7..ecd7d642 100644 --- a/src/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -205,7 +205,7 @@ public class TranslatingTypeLoader implements ITypeLoader { | |||
| 205 | } | 205 | } |
| 206 | if (obfClassEntry.isInnerClass()) { | 206 | if (obfClassEntry.isInnerClass()) { |
| 207 | // try just the inner class name | 207 | // try just the inner class name |
| 208 | classNamesToTry.add(obfClassEntry.getInnerClassName()); | 208 | classNamesToTry.add(obfClassEntry.getInnermostClassName()); |
| 209 | } | 209 | } |
| 210 | return classNamesToTry; | 210 | return classNamesToTry; |
| 211 | } | 211 | } |
diff --git a/src/cuchaz/enigma/analysis/EntryReference.java b/src/cuchaz/enigma/analysis/EntryReference.java index bb611df5..d0a5c6af 100644 --- a/src/cuchaz/enigma/analysis/EntryReference.java +++ b/src/cuchaz/enigma/analysis/EntryReference.java | |||
| @@ -74,7 +74,7 @@ public class EntryReference<E extends Entry,C extends Entry> { | |||
| 74 | ClassEntry classEntry = (ClassEntry)getNameableEntry(); | 74 | ClassEntry classEntry = (ClassEntry)getNameableEntry(); |
| 75 | if (classEntry.isInnerClass()) { | 75 | if (classEntry.isInnerClass()) { |
| 76 | // make sure we only rename the inner class name | 76 | // make sure we only rename the inner class name |
| 77 | return classEntry.getInnerClassName(); | 77 | return classEntry.getInnermostClassName(); |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java index 7ebbd974..a4a3abb8 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -312,7 +312,7 @@ public class JarIndex { | |||
| 312 | 312 | ||
| 313 | // does this class already have an outer class? | 313 | // does this class already have an outer class? |
| 314 | if (classEntry.isInnerClass()) { | 314 | if (classEntry.isInnerClass()) { |
| 315 | return classEntry.getOuterClassEntry(); | 315 | return classEntry.getOutermostClassEntry(); |
| 316 | } | 316 | } |
| 317 | InnerClassesAttribute innerClassesAttribute = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); | 317 | InnerClassesAttribute innerClassesAttribute = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); |
| 318 | if (innerClassesAttribute != null) { | 318 | if (innerClassesAttribute != null) { |
diff --git a/src/cuchaz/enigma/bytecode/ClassRenamer.java b/src/cuchaz/enigma/bytecode/ClassRenamer.java index a5fea926..e9cdea3c 100644 --- a/src/cuchaz/enigma/bytecode/ClassRenamer.java +++ b/src/cuchaz/enigma/bytecode/ClassRenamer.java | |||
| @@ -43,7 +43,7 @@ public class ClassRenamer { | |||
| 43 | for (int i = 0; i < attr.tableLength(); i++) { | 43 | for (int i = 0; i < attr.tableLength(); i++) { |
| 44 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(attr.innerClass(i))); | 44 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(attr.innerClass(i))); |
| 45 | if (attr.innerNameIndex(i) != 0) { | 45 | if (attr.innerNameIndex(i) != 0) { |
| 46 | attr.setInnerNameIndex(i, constants.addUtf8Info(classEntry.getInnerClassName())); | 46 | attr.setInnerNameIndex(i, constants.addUtf8Info(classEntry.getInnermostClassName())); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /* DEBUG | 49 | /* DEBUG |
diff --git a/src/cuchaz/enigma/bytecode/ClassTranslator.java b/src/cuchaz/enigma/bytecode/ClassTranslator.java index 4167731a..94ab2c4b 100644 --- a/src/cuchaz/enigma/bytecode/ClassTranslator.java +++ b/src/cuchaz/enigma/bytecode/ClassTranslator.java | |||
| @@ -26,7 +26,6 @@ import cuchaz.enigma.mapping.BehaviorEntry; | |||
| 26 | import cuchaz.enigma.mapping.ClassEntry; | 26 | import cuchaz.enigma.mapping.ClassEntry; |
| 27 | import cuchaz.enigma.mapping.EntryFactory; | 27 | import cuchaz.enigma.mapping.EntryFactory; |
| 28 | import cuchaz.enigma.mapping.FieldEntry; | 28 | import cuchaz.enigma.mapping.FieldEntry; |
| 29 | import cuchaz.enigma.mapping.MethodEntry; | ||
| 30 | import cuchaz.enigma.mapping.Signature; | 29 | import cuchaz.enigma.mapping.Signature; |
| 31 | import cuchaz.enigma.mapping.Translator; | 30 | import cuchaz.enigma.mapping.Translator; |
| 32 | import cuchaz.enigma.mapping.Type; | 31 | import cuchaz.enigma.mapping.Type; |
| @@ -101,26 +100,30 @@ public class ClassTranslator { | |||
| 101 | } | 100 | } |
| 102 | 101 | ||
| 103 | // translate the type | 102 | // translate the type |
| 104 | Type translatedType = m_translator.translateType(new Type(field.getFieldInfo().getDescriptor())); | 103 | Type translatedType = m_translator.translateType(entry.getType()); |
| 105 | field.getFieldInfo().setDescriptor(translatedType.toString()); | 104 | field.getFieldInfo().setDescriptor(translatedType.toString()); |
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | // translate all the methods and constructors | 107 | // translate all the methods and constructors |
| 109 | for (CtBehavior behavior : c.getDeclaredBehaviors()) { | 108 | for (CtBehavior behavior : c.getDeclaredBehaviors()) { |
| 109 | |||
| 110 | BehaviorEntry entry = EntryFactory.getBehaviorEntry(behavior); | ||
| 111 | |||
| 110 | if (behavior instanceof CtMethod) { | 112 | if (behavior instanceof CtMethod) { |
| 111 | CtMethod method = (CtMethod)behavior; | 113 | CtMethod method = (CtMethod)behavior; |
| 112 | 114 | ||
| 113 | // translate the name | 115 | // translate the name |
| 114 | MethodEntry entry = EntryFactory.getMethodEntry(method); | ||
| 115 | String translatedName = m_translator.translate(entry); | 116 | String translatedName = m_translator.translate(entry); |
| 116 | if (translatedName != null) { | 117 | if (translatedName != null) { |
| 117 | method.setName(translatedName); | 118 | method.setName(translatedName); |
| 118 | } | 119 | } |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | // translate the type | 122 | if (entry.getSignature() != null) { |
| 122 | Signature translatedSignature = m_translator.translateSignature(new Signature(behavior.getMethodInfo().getDescriptor())); | 123 | // translate the type |
| 123 | behavior.getMethodInfo().setDescriptor(translatedSignature.toString()); | 124 | Signature translatedSignature = m_translator.translateSignature(entry.getSignature()); |
| 125 | behavior.getMethodInfo().setDescriptor(translatedSignature.toString()); | ||
| 126 | } | ||
| 124 | } | 127 | } |
| 125 | 128 | ||
| 126 | // translate all the class names referenced in the code | 129 | // translate all the class names referenced in the code |
| @@ -137,7 +140,7 @@ public class ClassTranslator { | |||
| 137 | // translate the source file attribute too | 140 | // translate the source file attribute too |
| 138 | ClassEntry deobfClassEntry = map.get(classEntry); | 141 | ClassEntry deobfClassEntry = map.get(classEntry); |
| 139 | if (deobfClassEntry != null) { | 142 | if (deobfClassEntry != null) { |
| 140 | String sourceFile = Descriptor.toJvmName(deobfClassEntry.getOuterClassName()) + ".java"; | 143 | String sourceFile = Descriptor.toJvmName(deobfClassEntry.getOutermostClassName()) + ".java"; |
| 141 | c.getClassFile().addAttribute(new SourceFileAttribute(constants, sourceFile)); | 144 | c.getClassFile().addAttribute(new SourceFileAttribute(constants, sourceFile)); |
| 142 | } | 145 | } |
| 143 | } | 146 | } |
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java index dd21a780..976028d2 100644 --- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java +++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java | |||
| @@ -93,7 +93,7 @@ public class InnerClassWriter { | |||
| 93 | 93 | ||
| 94 | // get the new inner class name | 94 | // get the new inner class name |
| 95 | ClassEntry obfInnerClassEntry = obfClassEntry.buildClassEntry(obfClassChain); | 95 | ClassEntry obfInnerClassEntry = obfClassEntry.buildClassEntry(obfClassChain); |
| 96 | ClassEntry obfOuterClassEntry = obfInnerClassEntry.getOuterClassEntry(); | 96 | ClassEntry obfOuterClassEntry = obfInnerClassEntry.getOutermostClassEntry(); |
| 97 | 97 | ||
| 98 | // here's what the JVM spec says about the InnerClasses attribute | 98 | // here's what the JVM spec says about the InnerClasses attribute |
| 99 | // append(inner, parent, 0 if anonymous else simple name, flags); | 99 | // append(inner, parent, 0 if anonymous else simple name, flags); |
| @@ -105,7 +105,7 @@ public class InnerClassWriter { | |||
| 105 | int innerClassNameIndex = 0; | 105 | int innerClassNameIndex = 0; |
| 106 | int accessFlags = 0; | 106 | int accessFlags = 0; |
| 107 | if (!m_index.isAnonymousClass(obfClassEntry)) { | 107 | if (!m_index.isAnonymousClass(obfClassEntry)) { |
| 108 | innerClassNameIndex = constPool.addUtf8Info(obfInnerClassEntry.getInnerClassName()); | 108 | innerClassNameIndex = constPool.addUtf8Info(obfInnerClassEntry.getInnermostClassName()); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | attr.append(innerClassIndex, parentClassIndex, innerClassNameIndex, accessFlags); | 111 | attr.append(innerClassIndex, parentClassIndex, innerClassNameIndex, accessFlags); |
diff --git a/src/cuchaz/enigma/convert/ClassIdentity.java b/src/cuchaz/enigma/convert/ClassIdentity.java index 35667b05..d76cd63e 100644 --- a/src/cuchaz/enigma/convert/ClassIdentity.java +++ b/src/cuchaz/enigma/convert/ClassIdentity.java | |||
| @@ -180,7 +180,7 @@ public class ClassIdentity { | |||
| 180 | } | 180 | } |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | m_outer = EntryFactory.getClassEntry(c).getOuterClassName(); | 183 | m_outer = EntryFactory.getClassEntry(c).getOutermostClassName(); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | private void addReference(EntryReference<? extends Entry,BehaviorEntry> reference) { | 186 | private void addReference(EntryReference<? extends Entry,BehaviorEntry> reference) { |
diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java index ddd3a53c..2afa1208 100644 --- a/src/cuchaz/enigma/convert/MappingsConverter.java +++ b/src/cuchaz/enigma/convert/MappingsConverter.java | |||
| @@ -169,7 +169,7 @@ public class MappingsConverter { | |||
| 169 | newMappings.addClassMapping(destMapping); | 169 | newMappings.addClassMapping(destMapping); |
| 170 | } | 170 | } |
| 171 | } else { | 171 | } else { |
| 172 | destMapping = destMapping.getInnerClassByObf(destChainClassEntry.getInnerClassName()); | 172 | destMapping = destMapping.getInnerClassByObfSimple(destChainClassEntry.getInnermostClassName()); |
| 173 | if (destMapping == null) { | 173 | if (destMapping == null) { |
| 174 | destMapping = new ClassMapping(destChainClassEntry.getName()); | 174 | destMapping = new ClassMapping(destChainClassEntry.getName()); |
| 175 | destMapping.addInnerClassMapping(destMapping); | 175 | destMapping.addInnerClassMapping(destMapping); |
diff --git a/src/cuchaz/enigma/gui/CodeReader.java b/src/cuchaz/enigma/gui/CodeReader.java index 743ef2e4..fb8e0825 100644 --- a/src/cuchaz/enigma/gui/CodeReader.java +++ b/src/cuchaz/enigma/gui/CodeReader.java | |||
| @@ -106,7 +106,7 @@ public class CodeReader extends JEditorPane { | |||
| 106 | // get the outermost class | 106 | // get the outermost class |
| 107 | ClassEntry outermostClassEntry = classEntry; | 107 | ClassEntry outermostClassEntry = classEntry; |
| 108 | while (outermostClassEntry.isInnerClass()) { | 108 | while (outermostClassEntry.isInnerClass()) { |
| 109 | outermostClassEntry = outermostClassEntry.getOuterClassEntry(); | 109 | outermostClassEntry = outermostClassEntry.getOutermostClassEntry(); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | // decompile it | 112 | // decompile it |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index 9fa633eb..552ee47c 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -257,7 +257,7 @@ public class GuiController { | |||
| 257 | 257 | ||
| 258 | // get the reference target class | 258 | // get the reference target class |
| 259 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); | 259 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); |
| 260 | ClassEntry obfClassEntry = obfReference.getLocationClassEntry().getOuterClassEntry(); | 260 | ClassEntry obfClassEntry = obfReference.getLocationClassEntry().getOutermostClassEntry(); |
| 261 | if (!m_deobfuscator.isObfuscatedIdentifier(obfClassEntry)) { | 261 | if (!m_deobfuscator.isObfuscatedIdentifier(obfClassEntry)) { |
| 262 | throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!"); | 262 | throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!"); |
| 263 | } | 263 | } |
diff --git a/src/cuchaz/enigma/mapping/ClassEntry.java b/src/cuchaz/enigma/mapping/ClassEntry.java index 69e66bc0..5f3b5e23 100644 --- a/src/cuchaz/enigma/mapping/ClassEntry.java +++ b/src/cuchaz/enigma/mapping/ClassEntry.java | |||
| @@ -13,6 +13,8 @@ package cuchaz.enigma.mapping; | |||
| 13 | import java.io.Serializable; | 13 | import java.io.Serializable; |
| 14 | import java.util.List; | 14 | import java.util.List; |
| 15 | 15 | ||
| 16 | import com.beust.jcommander.internal.Lists; | ||
| 17 | |||
| 16 | public class ClassEntry implements Entry, Serializable { | 18 | public class ClassEntry implements Entry, Serializable { |
| 17 | 19 | ||
| 18 | private static final long serialVersionUID = 4235460580973955811L; | 20 | private static final long serialVersionUID = 4235460580973955811L; |
| @@ -29,7 +31,7 @@ public class ClassEntry implements Entry, Serializable { | |||
| 29 | 31 | ||
| 30 | m_name = className; | 32 | m_name = className; |
| 31 | 33 | ||
| 32 | if (isInnerClass() && getInnerClassName().indexOf('/') >= 0) { | 34 | if (isInnerClass() && getInnermostClassName().indexOf('/') >= 0) { |
| 33 | throw new IllegalArgumentException("Inner class must not have a package: " + className); | 35 | throw new IllegalArgumentException("Inner class must not have a package: " + className); |
| 34 | } | 36 | } |
| 35 | } | 37 | } |
| @@ -84,22 +86,39 @@ public class ClassEntry implements Entry, Serializable { | |||
| 84 | return m_name.lastIndexOf('$') >= 0; | 86 | return m_name.lastIndexOf('$') >= 0; |
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | public String getOuterClassName() { | 89 | public List<String> getClassChainNames() { |
| 90 | return Lists.newArrayList(m_name.split("\\$")); | ||
| 91 | } | ||
| 92 | |||
| 93 | public List<ClassEntry> getClassChain() { | ||
| 94 | List<ClassEntry> entries = Lists.newArrayList(); | ||
| 95 | StringBuilder buf = new StringBuilder(); | ||
| 96 | for (String name : getClassChainNames()) { | ||
| 97 | if (buf.length() > 0) { | ||
| 98 | buf.append("$"); | ||
| 99 | } | ||
| 100 | buf.append(name); | ||
| 101 | entries.add(new ClassEntry(buf.toString())); | ||
| 102 | } | ||
| 103 | return entries; | ||
| 104 | } | ||
| 105 | |||
| 106 | public String getOutermostClassName() { | ||
| 88 | if (isInnerClass()) { | 107 | if (isInnerClass()) { |
| 89 | return m_name.substring(0, m_name.lastIndexOf('$')); | 108 | return m_name.substring(0, m_name.lastIndexOf('$')); |
| 90 | } | 109 | } |
| 91 | return m_name; | 110 | return m_name; |
| 92 | } | 111 | } |
| 93 | 112 | ||
| 94 | public String getInnerClassName() { | 113 | public String getInnermostClassName() { |
| 95 | if (!isInnerClass()) { | 114 | if (!isInnerClass()) { |
| 96 | throw new Error("This is not an inner class!"); | 115 | throw new Error("This is not an inner class!"); |
| 97 | } | 116 | } |
| 98 | return m_name.substring(m_name.lastIndexOf('$') + 1); | 117 | return m_name.substring(m_name.lastIndexOf('$') + 1); |
| 99 | } | 118 | } |
| 100 | 119 | ||
| 101 | public ClassEntry getOuterClassEntry() { | 120 | public ClassEntry getOutermostClassEntry() { |
| 102 | return new ClassEntry(getOuterClassName()); | 121 | return new ClassEntry(getOutermostClassName()); |
| 103 | } | 122 | } |
| 104 | 123 | ||
| 105 | public boolean isInDefaultPackage() { | 124 | public boolean isInDefaultPackage() { |
| @@ -130,7 +149,7 @@ public class ClassEntry implements Entry, Serializable { | |||
| 130 | buf.append(chainEntry.getName()); | 149 | buf.append(chainEntry.getName()); |
| 131 | } else { | 150 | } else { |
| 132 | buf.append("$"); | 151 | buf.append("$"); |
| 133 | buf.append(chainEntry.isInnerClass() ? chainEntry.getInnerClassName() : chainEntry.getSimpleName()); | 152 | buf.append(chainEntry.isInnerClass() ? chainEntry.getInnermostClassName() : chainEntry.getSimpleName()); |
| 134 | } | 153 | } |
| 135 | 154 | ||
| 136 | if (chainEntry == this) { | 155 | if (chainEntry == this) { |
diff --git a/src/cuchaz/enigma/mapping/ClassMapping.java b/src/cuchaz/enigma/mapping/ClassMapping.java index 38cd3d6d..6e7fd17b 100644 --- a/src/cuchaz/enigma/mapping/ClassMapping.java +++ b/src/cuchaz/enigma/mapping/ClassMapping.java | |||
| @@ -23,22 +23,23 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 23 | private String m_obfFullName; | 23 | private String m_obfFullName; |
| 24 | private String m_obfSimpleName; | 24 | private String m_obfSimpleName; |
| 25 | private String m_deobfName; | 25 | private String m_deobfName; |
| 26 | private Map<String,ClassMapping> m_innerClassesByObf; | 26 | private Map<String,ClassMapping> m_innerClassesByObfSimple; |
| 27 | private Map<String,ClassMapping> m_innerClassesByDeobf; | 27 | private Map<String,ClassMapping> m_innerClassesByDeobf; |
| 28 | private Map<String,FieldMapping> m_fieldsByObf; | 28 | private Map<String,FieldMapping> m_fieldsByObf; |
| 29 | private Map<String,FieldMapping> m_fieldsByDeobf; | 29 | private Map<String,FieldMapping> m_fieldsByDeobf; |
| 30 | private Map<String,MethodMapping> m_methodsByObf; | 30 | private Map<String,MethodMapping> m_methodsByObf; |
| 31 | private Map<String,MethodMapping> m_methodsByDeobf; | 31 | private Map<String,MethodMapping> m_methodsByDeobf; |
| 32 | 32 | ||
| 33 | public ClassMapping(String obfName) { | 33 | public ClassMapping(String obfFullName) { |
| 34 | this(obfName, null); | 34 | this(obfFullName, null); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | public ClassMapping(String obfName, String deobfName) { | 37 | public ClassMapping(String obfFullName, String deobfName) { |
| 38 | m_obfFullName = obfName; | 38 | m_obfFullName = obfFullName; |
| 39 | m_obfSimpleName = new ClassEntry(obfName).getSimpleName(); | 39 | ClassEntry classEntry = new ClassEntry(obfFullName); |
| 40 | m_obfSimpleName = classEntry.isInnerClass() ? classEntry.getInnermostClassName() : classEntry.getSimpleName(); | ||
| 40 | m_deobfName = NameValidator.validateClassName(deobfName, false); | 41 | m_deobfName = NameValidator.validateClassName(deobfName, false); |
| 41 | m_innerClassesByObf = Maps.newHashMap(); | 42 | m_innerClassesByObfSimple = Maps.newHashMap(); |
| 42 | m_innerClassesByDeobf = Maps.newHashMap(); | 43 | m_innerClassesByDeobf = Maps.newHashMap(); |
| 43 | m_fieldsByObf = Maps.newHashMap(); | 44 | m_fieldsByObf = Maps.newHashMap(); |
| 44 | m_fieldsByDeobf = Maps.newHashMap(); | 45 | m_fieldsByDeobf = Maps.newHashMap(); |
| @@ -65,12 +66,12 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 65 | //// INNER CLASSES //////// | 66 | //// INNER CLASSES //////// |
| 66 | 67 | ||
| 67 | public Iterable<ClassMapping> innerClasses() { | 68 | public Iterable<ClassMapping> innerClasses() { |
| 68 | assert (m_innerClassesByObf.size() >= m_innerClassesByDeobf.size()); | 69 | assert (m_innerClassesByObfSimple.size() >= m_innerClassesByDeobf.size()); |
| 69 | return m_innerClassesByObf.values(); | 70 | return m_innerClassesByObfSimple.values(); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | public void addInnerClassMapping(ClassMapping classMapping) { | 73 | public void addInnerClassMapping(ClassMapping classMapping) { |
| 73 | boolean obfWasAdded = m_innerClassesByObf.put(classMapping.getObfSimpleName(), classMapping) == null; | 74 | boolean obfWasAdded = m_innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping) == null; |
| 74 | assert (obfWasAdded); | 75 | assert (obfWasAdded); |
| 75 | if (classMapping.getDeobfName() != null) { | 76 | if (classMapping.getDeobfName() != null) { |
| 76 | assert (isSimpleClassName(classMapping.getDeobfName())); | 77 | assert (isSimpleClassName(classMapping.getDeobfName())); |
| @@ -80,7 +81,7 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | public void removeInnerClassMapping(ClassMapping classMapping) { | 83 | public void removeInnerClassMapping(ClassMapping classMapping) { |
| 83 | boolean obfWasRemoved = m_innerClassesByObf.remove(classMapping.getObfSimpleName()) != null; | 84 | boolean obfWasRemoved = m_innerClassesByObfSimple.remove(classMapping.getObfSimpleName()) != null; |
| 84 | assert (obfWasRemoved); | 85 | assert (obfWasRemoved); |
| 85 | if (classMapping.getDeobfName() != null) { | 86 | if (classMapping.getDeobfName() != null) { |
| 86 | boolean deobfWasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; | 87 | boolean deobfWasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; |
| @@ -88,20 +89,19 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 88 | } | 89 | } |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | public ClassMapping getOrCreateInnerClass(String obfName) { | 92 | public ClassMapping getOrCreateInnerClass(ClassEntry obfInnerClass) { |
| 92 | assert (isSimpleClassName(obfName)); | 93 | ClassMapping classMapping = m_innerClassesByObfSimple.get(obfInnerClass.getInnermostClassName()); |
| 93 | ClassMapping classMapping = m_innerClassesByObf.get(obfName); | ||
| 94 | if (classMapping == null) { | 94 | if (classMapping == null) { |
| 95 | classMapping = new ClassMapping(obfName); | 95 | classMapping = new ClassMapping(obfInnerClass.getName()); |
| 96 | boolean wasAdded = m_innerClassesByObf.put(obfName, classMapping) == null; | 96 | boolean wasAdded = m_innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping) == null; |
| 97 | assert (wasAdded); | 97 | assert (wasAdded); |
| 98 | } | 98 | } |
| 99 | return classMapping; | 99 | return classMapping; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | public ClassMapping getInnerClassByObf(String obfName) { | 102 | public ClassMapping getInnerClassByObfSimple(String obfSimpleName) { |
| 103 | assert (isSimpleClassName(obfName)); | 103 | assert (isSimpleClassName(obfSimpleName)); |
| 104 | return m_innerClassesByObf.get(obfName); | 104 | return m_innerClassesByObfSimple.get(obfSimpleName); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | public ClassMapping getInnerClassByDeobf(String deobfName) { | 107 | public ClassMapping getInnerClassByDeobf(String deobfName) { |
| @@ -109,35 +109,25 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 109 | return m_innerClassesByDeobf.get(deobfName); | 109 | return m_innerClassesByDeobf.get(deobfName); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | public ClassMapping getInnerClassByDeobfThenObf(String name) { | 112 | public ClassMapping getInnerClassByDeobfThenObfSimple(String name) { |
| 113 | ClassMapping classMapping = getInnerClassByDeobf(name); | 113 | ClassMapping classMapping = getInnerClassByDeobf(name); |
| 114 | if (classMapping == null) { | 114 | if (classMapping == null) { |
| 115 | classMapping = getInnerClassByObf(name); | 115 | classMapping = getInnerClassByObfSimple(name); |
| 116 | } | 116 | } |
| 117 | return classMapping; | 117 | return classMapping; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | public String getObfInnerClassSimpleName(String deobfName) { | 120 | public String getDeobfInnerClassName(String obfSimpleName) { |
| 121 | assert (isSimpleClassName(deobfName)); | 121 | assert (isSimpleClassName(obfSimpleName)); |
| 122 | ClassMapping classMapping = m_innerClassesByDeobf.get(deobfName); | 122 | ClassMapping classMapping = m_innerClassesByObfSimple.get(obfSimpleName); |
| 123 | if (classMapping != null) { | ||
| 124 | return classMapping.getObfSimpleName(); | ||
| 125 | } | ||
| 126 | return null; | ||
| 127 | } | ||
| 128 | |||
| 129 | public String getDeobfInnerClassName(String obfName) { | ||
| 130 | assert (isSimpleClassName(obfName)); | ||
| 131 | ClassMapping classMapping = m_innerClassesByObf.get(obfName); | ||
| 132 | if (classMapping != null) { | 123 | if (classMapping != null) { |
| 133 | return classMapping.getDeobfName(); | 124 | return classMapping.getDeobfName(); |
| 134 | } | 125 | } |
| 135 | return null; | 126 | return null; |
| 136 | } | 127 | } |
| 137 | 128 | ||
| 138 | public void setInnerClassName(String obfName, String deobfName) { | 129 | public void setInnerClassName(ClassEntry obfInnerClass, String deobfName) { |
| 139 | assert (isSimpleClassName(obfName)); | 130 | ClassMapping classMapping = getOrCreateInnerClass(obfInnerClass); |
| 140 | ClassMapping classMapping = getOrCreateInnerClass(obfName); | ||
| 141 | if (classMapping.getDeobfName() != null) { | 131 | if (classMapping.getDeobfName() != null) { |
| 142 | boolean wasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; | 132 | boolean wasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; |
| 143 | assert (wasRemoved); | 133 | assert (wasRemoved); |
| @@ -150,6 +140,15 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 150 | } | 140 | } |
| 151 | } | 141 | } |
| 152 | 142 | ||
| 143 | public boolean hasInnerClassByObfSimple(String obfSimpleName) { | ||
| 144 | return m_innerClassesByObfSimple.containsKey(obfSimpleName); | ||
| 145 | } | ||
| 146 | |||
| 147 | public boolean hasInnerClassByDeobf(String deobfName) { | ||
| 148 | return m_innerClassesByDeobf.containsKey(deobfName); | ||
| 149 | } | ||
| 150 | |||
| 151 | |||
| 153 | //// FIELDS //////// | 152 | //// FIELDS //////// |
| 154 | 153 | ||
| 155 | public Iterable<FieldMapping> fields() { | 154 | public Iterable<FieldMapping> fields() { |
| @@ -382,7 +381,7 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 382 | buf.append("\n"); | 381 | buf.append("\n"); |
| 383 | } | 382 | } |
| 384 | buf.append("Inner Classes:\n"); | 383 | buf.append("Inner Classes:\n"); |
| 385 | for (ClassMapping classMapping : m_innerClassesByObf.values()) { | 384 | for (ClassMapping classMapping : m_innerClassesByObfSimple.values()) { |
| 386 | buf.append("\t"); | 385 | buf.append("\t"); |
| 387 | buf.append(classMapping.getObfSimpleName()); | 386 | buf.append(classMapping.getObfSimpleName()); |
| 388 | buf.append(" <-> "); | 387 | buf.append(" <-> "); |
| @@ -404,11 +403,11 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> { | |||
| 404 | public boolean renameObfClass(String oldObfClassName, String newObfClassName) { | 403 | public boolean renameObfClass(String oldObfClassName, String newObfClassName) { |
| 405 | 404 | ||
| 406 | // rename inner classes | 405 | // rename inner classes |
| 407 | for (ClassMapping innerClassMapping : new ArrayList<ClassMapping>(m_innerClassesByObf.values())) { | 406 | for (ClassMapping innerClassMapping : new ArrayList<ClassMapping>(m_innerClassesByObfSimple.values())) { |
| 408 | if (innerClassMapping.renameObfClass(oldObfClassName, newObfClassName)) { | 407 | if (innerClassMapping.renameObfClass(oldObfClassName, newObfClassName)) { |
| 409 | boolean wasRemoved = m_innerClassesByObf.remove(oldObfClassName) != null; | 408 | boolean wasRemoved = m_innerClassesByObfSimple.remove(oldObfClassName) != null; |
| 410 | assert (wasRemoved); | 409 | assert (wasRemoved); |
| 411 | boolean wasAdded = m_innerClassesByObf.put(newObfClassName, innerClassMapping) == null; | 410 | boolean wasAdded = m_innerClassesByObfSimple.put(newObfClassName, innerClassMapping) == null; |
| 412 | assert (wasAdded); | 411 | assert (wasAdded); |
| 413 | } | 412 | } |
| 414 | } | 413 | } |
diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java index a85bcbf6..659d23ac 100644 --- a/src/cuchaz/enigma/mapping/Mappings.java +++ b/src/cuchaz/enigma/mapping/Mappings.java | |||
| @@ -13,9 +13,11 @@ package cuchaz.enigma.mapping; | |||
| 13 | import java.io.Serializable; | 13 | import java.io.Serializable; |
| 14 | import java.util.ArrayList; | 14 | import java.util.ArrayList; |
| 15 | import java.util.Collection; | 15 | import java.util.Collection; |
| 16 | import java.util.List; | ||
| 16 | import java.util.Map; | 17 | import java.util.Map; |
| 17 | import java.util.Set; | 18 | import java.util.Set; |
| 18 | 19 | ||
| 20 | import com.beust.jcommander.internal.Lists; | ||
| 19 | import com.google.common.collect.Maps; | 21 | import com.google.common.collect.Maps; |
| 20 | import com.google.common.collect.Sets; | 22 | import com.google.common.collect.Sets; |
| 21 | 23 | ||
| @@ -89,6 +91,18 @@ public class Mappings implements Serializable { | |||
| 89 | return m_classesByDeobf.get(deobfName); | 91 | return m_classesByDeobf.get(deobfName); |
| 90 | } | 92 | } |
| 91 | 93 | ||
| 94 | public void setClassDeobfName(ClassMapping classMapping, String deobfName) { | ||
| 95 | if (classMapping.getDeobfName() != null) { | ||
| 96 | boolean wasRemoved = m_classesByDeobf.remove(classMapping.getDeobfName()) != null; | ||
| 97 | assert (wasRemoved); | ||
| 98 | } | ||
| 99 | classMapping.setDeobfName(deobfName); | ||
| 100 | if (deobfName != null) { | ||
| 101 | boolean wasAdded = m_classesByDeobf.put(deobfName, classMapping) == null; | ||
| 102 | assert (wasAdded); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 92 | public Translator getTranslator(TranslationDirection direction, TranslationIndex index) { | 106 | public Translator getTranslator(TranslationDirection direction, TranslationIndex index) { |
| 93 | switch (direction) { | 107 | switch (direction) { |
| 94 | case Deobfuscating: | 108 | case Deobfuscating: |
| @@ -185,4 +199,18 @@ public class Mappings implements Serializable { | |||
| 185 | } | 199 | } |
| 186 | return false; | 200 | return false; |
| 187 | } | 201 | } |
| 202 | |||
| 203 | public List<ClassMapping> getClassMappingChain(ClassEntry obfClass) { | ||
| 204 | List<ClassMapping> mappingChain = Lists.newArrayList(); | ||
| 205 | ClassMapping classMapping = null; | ||
| 206 | for (ClassEntry obfClassEntry : obfClass.getClassChain()) { | ||
| 207 | if (mappingChain.isEmpty()) { | ||
| 208 | classMapping = m_classesByObf.get(obfClassEntry.getName()); | ||
| 209 | } else if (classMapping != null) { | ||
| 210 | classMapping = classMapping.getInnerClassByObfSimple(obfClassEntry.getInnermostClassName()); | ||
| 211 | } | ||
| 212 | mappingChain.add(classMapping); | ||
| 213 | } | ||
| 214 | return mappingChain; | ||
| 215 | } | ||
| 188 | } | 216 | } |
diff --git a/src/cuchaz/enigma/mapping/MappingsRenamer.java b/src/cuchaz/enigma/mapping/MappingsRenamer.java index 16f700d2..d7766dc8 100644 --- a/src/cuchaz/enigma/mapping/MappingsRenamer.java +++ b/src/cuchaz/enigma/mapping/MappingsRenamer.java | |||
| @@ -13,10 +13,10 @@ package cuchaz.enigma.mapping; | |||
| 13 | import java.io.IOException; | 13 | import java.io.IOException; |
| 14 | import java.io.ObjectOutputStream; | 14 | import java.io.ObjectOutputStream; |
| 15 | import java.io.OutputStream; | 15 | import java.io.OutputStream; |
| 16 | import java.util.List; | ||
| 16 | import java.util.Set; | 17 | import java.util.Set; |
| 17 | import java.util.zip.GZIPOutputStream; | 18 | import java.util.zip.GZIPOutputStream; |
| 18 | 19 | ||
| 19 | import cuchaz.enigma.Constants; | ||
| 20 | import cuchaz.enigma.analysis.JarIndex; | 20 | import cuchaz.enigma.analysis.JarIndex; |
| 21 | 21 | ||
| 22 | public class MappingsRenamer { | 22 | public class MappingsRenamer { |
| @@ -30,48 +30,43 @@ public class MappingsRenamer { | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | public void setClassName(ClassEntry obf, String deobfName) { | 32 | public void setClassName(ClassEntry obf, String deobfName) { |
| 33 | deobfName = NameValidator.validateClassName(deobfName, !obf.isInnerClass()); | ||
| 34 | ClassEntry targetEntry = new ClassEntry(deobfName); | ||
| 35 | if (m_mappings.containsDeobfClass(deobfName) || m_index.containsObfClass(targetEntry)) { | ||
| 36 | throw new IllegalNameException(deobfName, "There is already a class with that name"); | ||
| 37 | } | ||
| 38 | 33 | ||
| 39 | ClassMapping classMapping = getOrCreateClassMapping(obf); | 34 | deobfName = NameValidator.validateClassName(deobfName, !obf.isInnerClass()); |
| 40 | 35 | ||
| 41 | if (obf.isInnerClass()) { | 36 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); |
| 42 | classMapping.setInnerClassName(obf.getInnerClassName(), deobfName); | 37 | if (mappingChain.size() == 1) { |
| 38 | |||
| 39 | if (deobfName != null) { | ||
| 40 | // make sure we don't rename to an existing obf or deobf class | ||
| 41 | if (m_mappings.containsDeobfClass(deobfName) || m_index.containsObfClass(new ClassEntry(deobfName))) { | ||
| 42 | throw new IllegalNameException(deobfName, "There is already a class with that name"); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | ClassMapping classMapping = mappingChain.get(0); | ||
| 47 | m_mappings.setClassDeobfName(classMapping, deobfName); | ||
| 48 | |||
| 43 | } else { | 49 | } else { |
| 44 | if (classMapping.getDeobfName() != null) { | 50 | |
| 45 | boolean wasRemoved = m_mappings.m_classesByDeobf.remove(classMapping.getDeobfName()) != null; | 51 | ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); |
| 46 | assert (wasRemoved); | 52 | |
| 53 | if (deobfName != null) { | ||
| 54 | // make sure we don't rename to an existing obf or deobf inner class | ||
| 55 | if (outerClassMapping.hasInnerClassByDeobf(deobfName) || outerClassMapping.hasInnerClassByObfSimple(deobfName)) { | ||
| 56 | throw new IllegalNameException(deobfName, "There is already a class with that name"); | ||
| 57 | } | ||
| 47 | } | 58 | } |
| 48 | classMapping.setDeobfName(deobfName); | 59 | |
| 49 | boolean wasAdded = m_mappings.m_classesByDeobf.put(deobfName, classMapping) == null; | 60 | outerClassMapping.setInnerClassName(obf, deobfName); |
| 50 | assert (wasAdded); | ||
| 51 | } | 61 | } |
| 52 | } | 62 | } |
| 53 | 63 | ||
| 54 | public void removeClassMapping(ClassEntry obf) { | 64 | public void removeClassMapping(ClassEntry obf) { |
| 55 | ClassMapping classMapping = getClassMapping(obf); | 65 | setClassName(obf, null); |
| 56 | if (obf.isInnerClass()) { | ||
| 57 | classMapping.setInnerClassName(obf.getName(), null); | ||
| 58 | } else { | ||
| 59 | boolean wasRemoved = m_mappings.m_classesByDeobf.remove(classMapping.getDeobfName()) != null; | ||
| 60 | assert (wasRemoved); | ||
| 61 | classMapping.setDeobfName(null); | ||
| 62 | } | ||
| 63 | } | 66 | } |
| 64 | 67 | ||
| 65 | public void markClassAsDeobfuscated(ClassEntry obf) { | 68 | public void markClassAsDeobfuscated(ClassEntry obf) { |
| 66 | ClassMapping classMapping = getOrCreateClassMapping(obf); | 69 | setClassName(obf, obf.isInnerClass() ? obf.getInnermostClassName() : obf.getSimpleName()); |
| 67 | if (obf.isInnerClass()) { | ||
| 68 | String innerClassName = Constants.NonePackage + "/" + obf.getInnerClassName(); | ||
| 69 | classMapping.setInnerClassName(innerClassName, innerClassName); | ||
| 70 | } else { | ||
| 71 | classMapping.setDeobfName(obf.getName()); | ||
| 72 | boolean wasAdded = m_mappings.m_classesByDeobf.put(obf.getName(), classMapping) == null; | ||
| 73 | assert (wasAdded); | ||
| 74 | } | ||
| 75 | } | 70 | } |
| 76 | 71 | ||
| 77 | public void setFieldName(FieldEntry obf, String deobfName) { | 72 | public void setFieldName(FieldEntry obf, String deobfName) { |
| @@ -81,17 +76,17 @@ public class MappingsRenamer { | |||
| 81 | throw new IllegalNameException(deobfName, "There is already a field with that name"); | 76 | throw new IllegalNameException(deobfName, "There is already a field with that name"); |
| 82 | } | 77 | } |
| 83 | 78 | ||
| 84 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 79 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 85 | classMapping.setFieldName(obf.getName(), obf.getType(), deobfName); | 80 | classMapping.setFieldName(obf.getName(), obf.getType(), deobfName); |
| 86 | } | 81 | } |
| 87 | 82 | ||
| 88 | public void removeFieldMapping(FieldEntry obf) { | 83 | public void removeFieldMapping(FieldEntry obf) { |
| 89 | ClassMapping classMapping = getClassMappingOrInnerClassMapping(obf.getClassEntry()); | 84 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 90 | classMapping.removeFieldMapping(classMapping.getFieldByObf(obf.getName(), obf.getType())); | 85 | classMapping.removeFieldMapping(classMapping.getFieldByObf(obf.getName(), obf.getType())); |
| 91 | } | 86 | } |
| 92 | 87 | ||
| 93 | public void markFieldAsDeobfuscated(FieldEntry obf) { | 88 | public void markFieldAsDeobfuscated(FieldEntry obf) { |
| 94 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 89 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 95 | classMapping.setFieldName(obf.getName(), obf.getType(), obf.getName()); | 90 | classMapping.setFieldName(obf.getName(), obf.getType(), obf.getName()); |
| 96 | } | 91 | } |
| 97 | 92 | ||
| @@ -121,7 +116,7 @@ public class MappingsRenamer { | |||
| 121 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); | 116 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); |
| 122 | } | 117 | } |
| 123 | 118 | ||
| 124 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 119 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 125 | classMapping.setMethodName(obf.getName(), obf.getSignature(), deobfName); | 120 | classMapping.setMethodName(obf.getName(), obf.getSignature(), deobfName); |
| 126 | } | 121 | } |
| 127 | 122 | ||
| @@ -132,7 +127,7 @@ public class MappingsRenamer { | |||
| 132 | } | 127 | } |
| 133 | 128 | ||
| 134 | public void removeMethodMapping(MethodEntry obf) { | 129 | public void removeMethodMapping(MethodEntry obf) { |
| 135 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 130 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 136 | classMapping.setMethodName(obf.getName(), obf.getSignature(), null); | 131 | classMapping.setMethodName(obf.getName(), obf.getSignature(), null); |
| 137 | } | 132 | } |
| 138 | 133 | ||
| @@ -143,7 +138,7 @@ public class MappingsRenamer { | |||
| 143 | } | 138 | } |
| 144 | 139 | ||
| 145 | public void markMethodAsDeobfuscated(MethodEntry obf) { | 140 | public void markMethodAsDeobfuscated(MethodEntry obf) { |
| 146 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 141 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 147 | classMapping.setMethodName(obf.getName(), obf.getSignature(), obf.getName()); | 142 | classMapping.setMethodName(obf.getName(), obf.getSignature(), obf.getName()); |
| 148 | } | 143 | } |
| 149 | 144 | ||
| @@ -154,17 +149,17 @@ public class MappingsRenamer { | |||
| 154 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); | 149 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); |
| 155 | } | 150 | } |
| 156 | 151 | ||
| 157 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 152 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 158 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), deobfName); | 153 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), deobfName); |
| 159 | } | 154 | } |
| 160 | 155 | ||
| 161 | public void removeArgumentMapping(ArgumentEntry obf) { | 156 | public void removeArgumentMapping(ArgumentEntry obf) { |
| 162 | ClassMapping classMapping = getClassMappingOrInnerClassMapping(obf.getClassEntry()); | 157 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 163 | classMapping.removeArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex()); | 158 | classMapping.removeArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex()); |
| 164 | } | 159 | } |
| 165 | 160 | ||
| 166 | public void markArgumentAsDeobfuscated(ArgumentEntry obf) { | 161 | public void markArgumentAsDeobfuscated(ArgumentEntry obf) { |
| 167 | ClassMapping classMapping = getOrCreateClassMappingOrInnerClassMapping(obf.getClassEntry()); | 162 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 168 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName()); | 163 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName()); |
| 169 | } | 164 | } |
| 170 | 165 | ||
| @@ -204,34 +199,31 @@ public class MappingsRenamer { | |||
| 204 | gzipout.finish(); | 199 | gzipout.finish(); |
| 205 | } | 200 | } |
| 206 | 201 | ||
| 207 | private ClassMapping getClassMapping(ClassEntry obfClassEntry) { | ||
| 208 | return m_mappings.m_classesByObf.get(obfClassEntry.getOuterClassName()); | ||
| 209 | } | ||
| 210 | |||
| 211 | private ClassMapping getOrCreateClassMapping(ClassEntry obfClassEntry) { | 202 | private ClassMapping getOrCreateClassMapping(ClassEntry obfClassEntry) { |
| 212 | String obfClassName = obfClassEntry.getOuterClassName(); | 203 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obfClassEntry); |
| 213 | ClassMapping classMapping = m_mappings.m_classesByObf.get(obfClassName); | 204 | return mappingChain.get(mappingChain.size() - 1); |
| 214 | if (classMapping == null) { | 205 | } |
| 215 | classMapping = new ClassMapping(obfClassName); | 206 | |
| 216 | boolean obfWasAdded = m_mappings.m_classesByObf.put(classMapping.getObfFullName(), classMapping) == null; | 207 | private List<ClassMapping> getOrCreateClassMappingChain(ClassEntry obfClassEntry) { |
| 217 | assert (obfWasAdded); | 208 | List<ClassEntry> classChain = obfClassEntry.getClassChain(); |
| 218 | } | 209 | List<ClassMapping> mappingChain = m_mappings.getClassMappingChain(obfClassEntry); |
| 219 | return classMapping; | 210 | for (int i=0; i<classChain.size(); i++) { |
| 220 | } | 211 | ClassEntry classEntry = classChain.get(i); |
| 221 | 212 | ClassMapping classMapping = mappingChain.get(i); | |
| 222 | private ClassMapping getClassMappingOrInnerClassMapping(ClassEntry obfClassEntry) { | 213 | if (classMapping == null) { |
| 223 | ClassMapping classMapping = getClassMapping(obfClassEntry); | 214 | |
| 224 | if (obfClassEntry.isInDefaultPackage()) { | 215 | // create it |
| 225 | classMapping = classMapping.getInnerClassByObf(obfClassEntry.getInnerClassName()); | 216 | classMapping = new ClassMapping(classEntry.getName()); |
| 226 | } | 217 | mappingChain.set(i, classMapping); |
| 227 | return classMapping; | 218 | |
| 228 | } | 219 | // add it to the right parent |
| 229 | 220 | if (i == 0) { | |
| 230 | private ClassMapping getOrCreateClassMappingOrInnerClassMapping(ClassEntry obfClassEntry) { | 221 | m_mappings.addClassMapping(classMapping); |
| 231 | ClassMapping classMapping = getOrCreateClassMapping(obfClassEntry); | 222 | } else { |
| 232 | if (obfClassEntry.isInnerClass()) { | 223 | mappingChain.get(i-1).addInnerClassMapping(classMapping); |
| 233 | classMapping = classMapping.getOrCreateInnerClass(obfClassEntry.getInnerClassName()); | 224 | } |
| 225 | } | ||
| 234 | } | 226 | } |
| 235 | return classMapping; | 227 | return mappingChain; |
| 236 | } | 228 | } |
| 237 | } | 229 | } |
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index d3b6e771..fb187b90 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java | |||
| @@ -24,6 +24,13 @@ public class Translator { | |||
| 24 | private Map<String,ClassMapping> m_classes; | 24 | private Map<String,ClassMapping> m_classes; |
| 25 | private TranslationIndex m_index; | 25 | private TranslationIndex m_index; |
| 26 | 26 | ||
| 27 | private ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { | ||
| 28 | @Override | ||
| 29 | public String replace(String className) { | ||
| 30 | return translateEntry(new ClassEntry(className)).getName(); | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 27 | public Translator() { | 34 | public Translator() { |
| 28 | m_direction = null; | 35 | m_direction = null; |
| 29 | m_classes = Maps.newHashMap(); | 36 | m_classes = Maps.newHashMap(); |
| @@ -69,48 +76,16 @@ public class Translator { | |||
| 69 | } | 76 | } |
| 70 | } | 77 | } |
| 71 | 78 | ||
| 72 | public String translateClass(String className) { | ||
| 73 | return translate(new ClassEntry(className)); | ||
| 74 | } | ||
| 75 | |||
| 76 | public String translate(ClassEntry in) { | 79 | public String translate(ClassEntry in) { |
| 77 | 80 | ClassEntry translated = translateEntry(in); | |
| 78 | if (in.isInnerClass()) { | 81 | if (translated.equals(in)) { |
| 79 | 82 | return null; | |
| 80 | // translate everything in the class chain, or return null | ||
| 81 | List<ClassMapping> mappingsChain = getClassMappingChain(in); | ||
| 82 | StringBuilder buf = new StringBuilder(); | ||
| 83 | for (ClassMapping classMapping : mappingsChain) { | ||
| 84 | if (classMapping == null) { | ||
| 85 | return null; | ||
| 86 | } | ||
| 87 | boolean isFirstClass = buf.length() == 0; | ||
| 88 | String name = m_direction.choose( | ||
| 89 | classMapping.getDeobfName(), | ||
| 90 | isFirstClass ? classMapping.getObfFullName() : classMapping.getObfSimpleName() | ||
| 91 | ); | ||
| 92 | if (name == null) { | ||
| 93 | return null; | ||
| 94 | } | ||
| 95 | if (!isFirstClass) { | ||
| 96 | buf.append("$"); | ||
| 97 | } | ||
| 98 | buf.append(name); | ||
| 99 | } | ||
| 100 | return buf.toString(); | ||
| 101 | |||
| 102 | } else { | ||
| 103 | |||
| 104 | // normal classes are easier | ||
| 105 | ClassMapping classMapping = m_classes.get(in.getName()); | ||
| 106 | if (classMapping == null) { | ||
| 107 | return null; | ||
| 108 | } | ||
| 109 | return m_direction.choose( | ||
| 110 | classMapping.getDeobfName(), | ||
| 111 | classMapping.getObfFullName() | ||
| 112 | ); | ||
| 113 | } | 83 | } |
| 84 | return translated.getName(); | ||
| 85 | } | ||
| 86 | |||
| 87 | public String translateClass(String className) { | ||
| 88 | return translate(new ClassEntry(className)); | ||
| 114 | } | 89 | } |
| 115 | 90 | ||
| 116 | public ClassEntry translateEntry(ClassEntry in) { | 91 | public ClassEntry translateEntry(ClassEntry in) { |
| @@ -264,21 +239,11 @@ public class Translator { | |||
| 264 | } | 239 | } |
| 265 | 240 | ||
| 266 | public Type translateType(Type type) { | 241 | public Type translateType(Type type) { |
| 267 | return new Type(type, new ClassNameReplacer() { | 242 | return new Type(type, m_classNameReplacer); |
| 268 | @Override | ||
| 269 | public String replace(String className) { | ||
| 270 | return translateClass(className); | ||
| 271 | } | ||
| 272 | }); | ||
| 273 | } | 243 | } |
| 274 | 244 | ||
| 275 | public Signature translateSignature(Signature signature) { | 245 | public Signature translateSignature(Signature signature) { |
| 276 | return new Signature(signature, new ClassNameReplacer() { | 246 | return new Signature(signature, m_classNameReplacer); |
| 277 | @Override | ||
| 278 | public String replace(String className) { | ||
| 279 | return translateClass(className); | ||
| 280 | } | ||
| 281 | }); | ||
| 282 | } | 247 | } |
| 283 | 248 | ||
| 284 | private ClassMapping findClassMapping(ClassEntry in) { | 249 | private ClassMapping findClassMapping(ClassEntry in) { |
| @@ -302,8 +267,8 @@ public class Translator { | |||
| 302 | ClassMapping innerClassMapping = null; | 267 | ClassMapping innerClassMapping = null; |
| 303 | if (outerClassMapping != null) { | 268 | if (outerClassMapping != null) { |
| 304 | innerClassMapping = m_direction.choose( | 269 | innerClassMapping = m_direction.choose( |
| 305 | outerClassMapping.getInnerClassByObf(parts[i]), | 270 | outerClassMapping.getInnerClassByObfSimple(parts[i]), |
| 306 | outerClassMapping.getInnerClassByDeobfThenObf(parts[i]) | 271 | outerClassMapping.getInnerClassByDeobfThenObfSimple(parts[i]) |
| 307 | ); | 272 | ); |
| 308 | } | 273 | } |
| 309 | mappingsChain.add(innerClassMapping); | 274 | mappingsChain.add(innerClassMapping); |
diff --git a/test/cuchaz/enigma/TestDeobfed.java b/test/cuchaz/enigma/TestDeobfed.java index 3c2ae51d..ca349d7c 100644 --- a/test/cuchaz/enigma/TestDeobfed.java +++ b/test/cuchaz/enigma/TestDeobfed.java | |||
| @@ -34,21 +34,24 @@ public class TestDeobfed { | |||
| 34 | newClass("none/b"), | 34 | newClass("none/b"), |
| 35 | newClass("none/c"), | 35 | newClass("none/c"), |
| 36 | newClass("none/d"), | 36 | newClass("none/d"), |
| 37 | newClass("none/d$e"), | 37 | newClass("none/d$1"), |
| 38 | newClass("none/e"), | ||
| 38 | newClass("none/f"), | 39 | newClass("none/f"), |
| 39 | newClass("none/g"), | 40 | newClass("none/g"), |
| 41 | newClass("none/g$a"), | ||
| 42 | newClass("none/g$a$a"), | ||
| 43 | newClass("none/g$b"), | ||
| 44 | newClass("none/g$b$a"), | ||
| 40 | newClass("none/h"), | 45 | newClass("none/h"), |
| 41 | newClass("none/h$i"), | 46 | newClass("none/h$a"), |
| 42 | newClass("none/h$i$j"), | 47 | newClass("none/h$a$a"), |
| 43 | newClass("none/h$k"), | 48 | newClass("none/h$b"), |
| 44 | newClass("none/h$k$l"), | 49 | newClass("none/h$b$a"), |
| 45 | newClass("none/m"), | 50 | newClass("none/h$b$a$a"), |
| 46 | newClass("none/m$n"), | 51 | newClass("none/h$b$a$b"), |
| 47 | newClass("none/m$n$o"), | 52 | newClass("none/i"), |
| 48 | newClass("none/m$p"), | 53 | newClass("none/i$a"), |
| 49 | newClass("none/m$p$q"), | 54 | newClass("none/i$b") |
| 50 | newClass("none/m$p$q$r"), | ||
| 51 | newClass("none/m$p$q$s") | ||
| 52 | )); | 55 | )); |
| 53 | } | 56 | } |
| 54 | 57 | ||
| @@ -60,20 +63,23 @@ public class TestDeobfed { | |||
| 60 | deobfuscator.getSourceTree("none/b"); | 63 | deobfuscator.getSourceTree("none/b"); |
| 61 | deobfuscator.getSourceTree("none/c"); | 64 | deobfuscator.getSourceTree("none/c"); |
| 62 | deobfuscator.getSourceTree("none/d"); | 65 | deobfuscator.getSourceTree("none/d"); |
| 63 | deobfuscator.getSourceTree("none/d$e"); | 66 | deobfuscator.getSourceTree("none/d$1"); |
| 67 | deobfuscator.getSourceTree("none/e"); | ||
| 64 | deobfuscator.getSourceTree("none/f"); | 68 | deobfuscator.getSourceTree("none/f"); |
| 65 | deobfuscator.getSourceTree("none/g"); | 69 | deobfuscator.getSourceTree("none/g"); |
| 70 | deobfuscator.getSourceTree("none/g$a"); | ||
| 71 | deobfuscator.getSourceTree("none/g$a$a"); | ||
| 72 | deobfuscator.getSourceTree("none/g$b"); | ||
| 73 | deobfuscator.getSourceTree("none/g$b$a"); | ||
| 66 | deobfuscator.getSourceTree("none/h"); | 74 | deobfuscator.getSourceTree("none/h"); |
| 67 | deobfuscator.getSourceTree("none/h$i"); | 75 | deobfuscator.getSourceTree("none/h$a"); |
| 68 | deobfuscator.getSourceTree("none/h$i$j"); | 76 | deobfuscator.getSourceTree("none/h$a$a"); |
| 69 | deobfuscator.getSourceTree("none/h$k"); | 77 | deobfuscator.getSourceTree("none/h$b"); |
| 70 | deobfuscator.getSourceTree("none/h$k$l"); | 78 | deobfuscator.getSourceTree("none/h$b$a"); |
| 71 | deobfuscator.getSourceTree("none/m"); | 79 | deobfuscator.getSourceTree("none/h$b$a$a"); |
| 72 | deobfuscator.getSourceTree("none/m$n"); | 80 | deobfuscator.getSourceTree("none/h$b$a$b"); |
| 73 | deobfuscator.getSourceTree("none/m$n$o"); | 81 | deobfuscator.getSourceTree("none/i"); |
| 74 | deobfuscator.getSourceTree("none/m$p"); | 82 | deobfuscator.getSourceTree("none/i$a"); |
| 75 | deobfuscator.getSourceTree("none/m$p$q"); | 83 | deobfuscator.getSourceTree("none/i$b"); |
| 76 | deobfuscator.getSourceTree("none/m$p$q$r"); | ||
| 77 | deobfuscator.getSourceTree("none/m$p$q$s"); | ||
| 78 | } | 84 | } |
| 79 | } | 85 | } |
diff --git a/test/cuchaz/enigma/TestInnerClasses.java b/test/cuchaz/enigma/TestInnerClasses.java index 2eb5accc..014a4613 100644 --- a/test/cuchaz/enigma/TestInnerClasses.java +++ b/test/cuchaz/enigma/TestInnerClasses.java | |||
| @@ -29,19 +29,19 @@ public class TestInnerClasses { | |||
| 29 | private Deobfuscator m_deobfuscator; | 29 | private Deobfuscator m_deobfuscator; |
| 30 | 30 | ||
| 31 | private static final ClassEntry AnonymousOuter = newClass("none/a"); | 31 | private static final ClassEntry AnonymousOuter = newClass("none/a"); |
| 32 | private static final ClassEntry AnonymousInner = newClass("none/b"); | 32 | private static final ClassEntry AnonymousInner = newClass("none/a$1"); |
| 33 | private static final ClassEntry SimpleOuter = newClass("none/g"); | 33 | private static final ClassEntry SimpleOuter = newClass("none/d"); |
| 34 | private static final ClassEntry SimpleInner = newClass("none/h"); | 34 | private static final ClassEntry SimpleInner = newClass("none/d$a"); |
| 35 | private static final ClassEntry ConstructorArgsOuter = newClass("none/e"); | 35 | private static final ClassEntry ConstructorArgsOuter = newClass("none/c"); |
| 36 | private static final ClassEntry ConstructorArgsInner = newClass("none/f"); | 36 | private static final ClassEntry ConstructorArgsInner = newClass("none/c$a"); |
| 37 | private static final ClassEntry AnonymousWithScopeArgsOuter = newClass("none/c"); | 37 | private static final ClassEntry AnonymousWithScopeArgsOuter = newClass("none/b"); |
| 38 | private static final ClassEntry AnonymousWithScopeArgsInner = newClass("none/d"); | 38 | private static final ClassEntry AnonymousWithScopeArgsInner = newClass("none/b$1"); |
| 39 | private static final ClassEntry AnonymousWithOuterAccessOuter = newClass("none/i"); | 39 | private static final ClassEntry AnonymousWithOuterAccessOuter = newClass("none/e"); |
| 40 | private static final ClassEntry AnonymousWithOuterAccessInner = newClass("none/j"); | 40 | private static final ClassEntry AnonymousWithOuterAccessInner = newClass("none/e$1"); |
| 41 | private static final ClassEntry ClassTreeRoot = newClass("none/k"); | 41 | private static final ClassEntry ClassTreeRoot = newClass("none/f"); |
| 42 | private static final ClassEntry ClassTreeLevel1 = newClass("none/l"); | 42 | private static final ClassEntry ClassTreeLevel1 = newClass("none/f$a"); |
| 43 | private static final ClassEntry ClassTreeLevel2 = newClass("none/m"); | 43 | private static final ClassEntry ClassTreeLevel2 = newClass("none/f$a$a"); |
| 44 | private static final ClassEntry ClassTreeLevel3 = newClass("none/n"); | 44 | private static final ClassEntry ClassTreeLevel3 = newClass("none/f$a$a$a"); |
| 45 | 45 | ||
| 46 | public TestInnerClasses() | 46 | public TestInnerClasses() |
| 47 | throws Exception { | 47 | throws Exception { |
| @@ -101,7 +101,7 @@ public class TestInnerClasses { | |||
| 101 | 101 | ||
| 102 | // level 1 | 102 | // level 1 |
| 103 | ClassEntry fullClassEntry = new ClassEntry(ClassTreeRoot.getName() | 103 | ClassEntry fullClassEntry = new ClassEntry(ClassTreeRoot.getName() |
| 104 | + "$" + ClassTreeLevel1.getSimpleName() | 104 | + "$" + ClassTreeLevel1.getInnermostClassName() |
| 105 | ); | 105 | ); |
| 106 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); | 106 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); |
| 107 | assertThat(m_index.getOuterClass(ClassTreeLevel1), is(ClassTreeRoot)); | 107 | assertThat(m_index.getOuterClass(ClassTreeLevel1), is(ClassTreeRoot)); |
| @@ -109,8 +109,8 @@ public class TestInnerClasses { | |||
| 109 | 109 | ||
| 110 | // level 2 | 110 | // level 2 |
| 111 | fullClassEntry = new ClassEntry(ClassTreeRoot.getName() | 111 | fullClassEntry = new ClassEntry(ClassTreeRoot.getName() |
| 112 | + "$" + ClassTreeLevel1.getSimpleName() | 112 | + "$" + ClassTreeLevel1.getInnermostClassName() |
| 113 | + "$" + ClassTreeLevel2.getSimpleName() | 113 | + "$" + ClassTreeLevel2.getInnermostClassName() |
| 114 | ); | 114 | ); |
| 115 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); | 115 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); |
| 116 | assertThat(m_index.getOuterClass(ClassTreeLevel2), is(ClassTreeLevel1)); | 116 | assertThat(m_index.getOuterClass(ClassTreeLevel2), is(ClassTreeLevel1)); |
| @@ -118,9 +118,9 @@ public class TestInnerClasses { | |||
| 118 | 118 | ||
| 119 | // level 3 | 119 | // level 3 |
| 120 | fullClassEntry = new ClassEntry(ClassTreeRoot.getName() | 120 | fullClassEntry = new ClassEntry(ClassTreeRoot.getName() |
| 121 | + "$" + ClassTreeLevel1.getSimpleName() | 121 | + "$" + ClassTreeLevel1.getInnermostClassName() |
| 122 | + "$" + ClassTreeLevel2.getSimpleName() | 122 | + "$" + ClassTreeLevel2.getInnermostClassName() |
| 123 | + "$" + ClassTreeLevel3.getSimpleName() | 123 | + "$" + ClassTreeLevel3.getInnermostClassName() |
| 124 | ); | 124 | ); |
| 125 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); | 125 | assertThat(m_index.containsObfClass(fullClassEntry), is(true)); |
| 126 | assertThat(m_index.getOuterClass(ClassTreeLevel3), is(ClassTreeLevel2)); | 126 | assertThat(m_index.getOuterClass(ClassTreeLevel3), is(ClassTreeLevel2)); |
diff --git a/test/cuchaz/enigma/TestSourceIndex.java b/test/cuchaz/enigma/TestSourceIndex.java index 94bf941d..13971249 100644 --- a/test/cuchaz/enigma/TestSourceIndex.java +++ b/test/cuchaz/enigma/TestSourceIndex.java | |||
| @@ -24,7 +24,7 @@ import cuchaz.enigma.mapping.ClassEntry; | |||
| 24 | 24 | ||
| 25 | public class TestSourceIndex { | 25 | public class TestSourceIndex { |
| 26 | 26 | ||
| 27 | @Test | 27 | // TEMP @Test |
| 28 | public void indexEverything() | 28 | public void indexEverything() |
| 29 | throws Exception { | 29 | throws Exception { |
| 30 | 30 | ||
diff --git a/test/cuchaz/enigma/TestTranslator.java b/test/cuchaz/enigma/TestTranslator.java index 02526050..45c69bb2 100644 --- a/test/cuchaz/enigma/TestTranslator.java +++ b/test/cuchaz/enigma/TestTranslator.java | |||
| @@ -101,26 +101,31 @@ public class TestTranslator { | |||
| 101 | public void innerClasses() { | 101 | public void innerClasses() { |
| 102 | 102 | ||
| 103 | // classes | 103 | // classes |
| 104 | assertMapping(newClass("none/h"), newClass("deobf/H_OuterClass")); | 104 | assertMapping(newClass("none/g"), newClass("deobf/G_OuterClass")); |
| 105 | assertMapping(newClass("none/h$i"), newClass("deobf/H_OuterClass$I_InnerClass")); | 105 | assertMapping(newClass("none/g$a"), newClass("deobf/G_OuterClass$A_InnerClass")); |
| 106 | assertMapping(newClass("none/h$i$j"), newClass("deobf/H_OuterClass$I_InnerClass$J_InnerInnerClass")); | 106 | assertMapping(newClass("none/g$a$a"), newClass("deobf/G_OuterClass$A_InnerClass$A_InnerInnerClass")); |
| 107 | assertMapping(newClass("none/h$k"), newClass("deobf/H_OuterClass$k")); | 107 | assertMapping(newClass("none/g$b"), newClass("deobf/G_OuterClass$b")); |
| 108 | assertMapping(newClass("none/h$k$l"), newClass("deobf/H_OuterClass$k$L_NamedInnerClass")); | 108 | assertMapping(newClass("none/g$b$a"), newClass("deobf/G_OuterClass$b$A_NamedInnerClass")); |
| 109 | 109 | ||
| 110 | // fields | 110 | // fields |
| 111 | assertMapping(newField("none/h$i", "a", "I"), newField("deobf/H_OuterClass$I_InnerClass", "f1", "I")); | 111 | assertMapping(newField("none/g$a", "a", "I"), newField("deobf/G_OuterClass$A_InnerClass", "f1", "I")); |
| 112 | assertMapping(newField("none/h$i", "a", "Ljava/lang/String;"), newField("deobf/H_OuterClass$I_InnerClass", "f2", "Ljava/lang/String;")); | 112 | assertMapping(newField("none/g$a", "a", "Ljava/lang/String;"), newField("deobf/G_OuterClass$A_InnerClass", "f2", "Ljava/lang/String;")); |
| 113 | assertMapping(newField("none/h$i$j", "a", "I"), newField("deobf/H_OuterClass$I_InnerClass$J_InnerInnerClass", "f3", "I")); | 113 | assertMapping(newField("none/g$a$a", "a", "I"), newField("deobf/G_OuterClass$A_InnerClass$A_InnerInnerClass", "f3", "I")); |
| 114 | assertMapping(newField("none/h$k$l", "a", "I"), newField("deobf/H_OuterClass$k$L_NamedInnerClass", "f4", "I")); | 114 | assertMapping(newField("none/g$b$a", "a", "I"), newField("deobf/G_OuterClass$b$A_NamedInnerClass", "f4", "I")); |
| 115 | 115 | ||
| 116 | // methods | 116 | // methods |
| 117 | assertMapping(newMethod("none/h$i", "a", "()V"), newMethod("deobf/H_OuterClass$I_InnerClass", "m1", "()V")); | 117 | assertMapping(newMethod("none/g$a", "a", "()V"), newMethod("deobf/G_OuterClass$A_InnerClass", "m1", "()V")); |
| 118 | assertMapping(newMethod("none/h$i$j", "a", "()V"), newMethod("deobf/H_OuterClass$I_InnerClass$J_InnerInnerClass", "m2", "()V")); | 118 | assertMapping(newMethod("none/g$a$a", "a", "()V"), newMethod("deobf/G_OuterClass$A_InnerClass$A_InnerInnerClass", "m2", "()V")); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | @Test | 121 | @Test |
| 122 | public void namelessClass() { | 122 | public void namelessClass() { |
| 123 | assertMapping(newClass("none/m"), newClass("none/m")); | 123 | assertMapping(newClass("none/h"), newClass("none/h")); |
| 124 | } | ||
| 125 | |||
| 126 | @Test | ||
| 127 | public void testGenerics() { | ||
| 128 | // TODO | ||
| 124 | } | 129 | } |
| 125 | 130 | ||
| 126 | private void assertMapping(Entry obf, Entry deobf) { | 131 | private void assertMapping(Entry obf, Entry deobf) { |
diff --git a/test/cuchaz/enigma/inputs/translation/G_ObjectMethods.java b/test/cuchaz/enigma/inputs/translation/F_ObjectMethods.java index ebad5a38..4e091797 100644 --- a/test/cuchaz/enigma/inputs/translation/G_ObjectMethods.java +++ b/test/cuchaz/enigma/inputs/translation/F_ObjectMethods.java | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | package cuchaz.enigma.inputs.translation; | 1 | package cuchaz.enigma.inputs.translation; |
| 2 | 2 | ||
| 3 | public class G_ObjectMethods { | 3 | public class F_ObjectMethods { |
| 4 | 4 | ||
| 5 | public void callEmAll() | 5 | public void callEmAll() |
| 6 | throws Throwable { | 6 | throws Throwable { |
diff --git a/test/cuchaz/enigma/inputs/translation/H_OuterClass.java b/test/cuchaz/enigma/inputs/translation/G_OuterClass.java index 995c65d2..0856afed 100644 --- a/test/cuchaz/enigma/inputs/translation/H_OuterClass.java +++ b/test/cuchaz/enigma/inputs/translation/G_OuterClass.java | |||
| @@ -1,16 +1,16 @@ | |||
| 1 | package cuchaz.enigma.inputs.translation; | 1 | package cuchaz.enigma.inputs.translation; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | public class H_OuterClass { | 4 | public class G_OuterClass { |
| 5 | 5 | ||
| 6 | public class I_InnerClass { | 6 | public class A_InnerClass { |
| 7 | 7 | ||
| 8 | public int f1; | 8 | public int f1; |
| 9 | public String f2; | 9 | public String f2; |
| 10 | 10 | ||
| 11 | public void m1() {} | 11 | public void m1() {} |
| 12 | 12 | ||
| 13 | public class J_InnerInnerClass { | 13 | public class A_InnerInnerClass { |
| 14 | 14 | ||
| 15 | public int f3; | 15 | public int f3; |
| 16 | 16 | ||
| @@ -18,8 +18,8 @@ public class H_OuterClass { | |||
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | public class K_NamelessClass { | 21 | public class B_NamelessClass { |
| 22 | public class L_NamedInnerClass { | 22 | public class A_NamedInnerClass { |
| 23 | public int f4; | 23 | public int f4; |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
diff --git a/test/cuchaz/enigma/inputs/translation/H_NamelessClass.java b/test/cuchaz/enigma/inputs/translation/H_NamelessClass.java new file mode 100644 index 00000000..5802d789 --- /dev/null +++ b/test/cuchaz/enigma/inputs/translation/H_NamelessClass.java | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | package cuchaz.enigma.inputs.translation; | ||
| 2 | |||
| 3 | |||
| 4 | public class H_NamelessClass { | ||
| 5 | |||
| 6 | public class A_InnerClass { | ||
| 7 | |||
| 8 | public int f1; | ||
| 9 | public String f2; | ||
| 10 | |||
| 11 | public void m1() {} | ||
| 12 | |||
| 13 | public class A_InnerInnerClass { | ||
| 14 | |||
| 15 | public int f3; | ||
| 16 | |||
| 17 | public void m2() {} | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | public class B_NamelessClass { | ||
| 22 | public class A_NamedInnerClass { | ||
| 23 | public int f4; | ||
| 24 | public class A_AnotherInnerClass {} | ||
| 25 | public class B_YetAnotherInnerClass {} | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/test/cuchaz/enigma/inputs/translation/I_Generics.java b/test/cuchaz/enigma/inputs/translation/I_Generics.java new file mode 100644 index 00000000..191931a8 --- /dev/null +++ b/test/cuchaz/enigma/inputs/translation/I_Generics.java | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | package cuchaz.enigma.inputs.translation; | ||
| 2 | |||
| 3 | import java.util.List; | ||
| 4 | import java.util.Map; | ||
| 5 | |||
| 6 | |||
| 7 | public class I_Generics { | ||
| 8 | |||
| 9 | public class A_Type { | ||
| 10 | } | ||
| 11 | |||
| 12 | public List<Integer> f1; | ||
| 13 | public List<A_Type> f2; | ||
| 14 | public Map<A_Type,A_Type> f3; | ||
| 15 | |||
| 16 | public class B_Generic<T> { | ||
| 17 | public T f4; | ||
| 18 | public T m1() { | ||
| 19 | return null; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | public B_Generic<Integer> f5; | ||
| 24 | public B_Generic<A_Type> f6; | ||
| 25 | } | ||
diff --git a/test/cuchaz/enigma/inputs/translation/M_NamelessClass.java b/test/cuchaz/enigma/inputs/translation/M_NamelessClass.java deleted file mode 100644 index 5d8acbc7..00000000 --- a/test/cuchaz/enigma/inputs/translation/M_NamelessClass.java +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | package cuchaz.enigma.inputs.translation; | ||
| 2 | |||
| 3 | |||
| 4 | public class M_NamelessClass { | ||
| 5 | |||
| 6 | public class N_InnerClass { | ||
| 7 | |||
| 8 | public int f1; | ||
| 9 | public String f2; | ||
| 10 | |||
| 11 | public void m1() {} | ||
| 12 | |||
| 13 | public class O_InnerInnerClass { | ||
| 14 | |||
| 15 | public int f3; | ||
| 16 | |||
| 17 | public void m2() {} | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | public class P_NamelessClass { | ||
| 22 | public class Q_NamedInnerClass { | ||
| 23 | public int f4; | ||
| 24 | public class R_AnotherInnerClass {} | ||
| 25 | public class S_YetAnotherInnerClass {} | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/test/cuchaz/enigma/resources/translation.mappings b/test/cuchaz/enigma/resources/translation.mappings index 5dffaf1d..55bd7e5c 100644 --- a/test/cuchaz/enigma/resources/translation.mappings +++ b/test/cuchaz/enigma/resources/translation.mappings | |||
| @@ -17,15 +17,16 @@ CLASS none/c deobf/C_SubClass | |||
| 17 | FIELD c f4 I | 17 | FIELD c f4 I |
| 18 | METHOD a m1 ()I | 18 | METHOD a m1 ()I |
| 19 | METHOD c m3 ()I | 19 | METHOD c m3 ()I |
| 20 | CLASS none/h deobf/H_OuterClass | 20 | CLASS none/g deobf/G_OuterClass |
| 21 | CLASS none/i I_InnerClass | 21 | CLASS none/g$a A_InnerClass |
| 22 | CLASS none/j J_InnerInnerClass | 22 | CLASS none/g$a$a A_InnerInnerClass |
| 23 | FIELD a f3 I | 23 | FIELD a f3 I |
| 24 | METHOD a m2 ()V | 24 | METHOD a m2 ()V |
| 25 | FIELD a f1 I | 25 | FIELD a f1 I |
| 26 | FIELD a f2 Ljava/lang/String; | 26 | FIELD a f2 Ljava/lang/String; |
| 27 | METHOD a m1 ()V | 27 | METHOD a m1 ()V |
| 28 | CLASS none/k | 28 | CLASS none/g$b |
| 29 | CLASS none/l L_NamedInnerClass | 29 | CLASS none/g$b$a A_NamedInnerClass |
| 30 | FIELD a f4 I | 30 | FIELD a f4 I |
| 31 | CLASS none/m \ No newline at end of file | 31 | CLASS none/h |
| 32 | CLASS none/i I_Generics | ||