summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar gegy10002018-05-19 20:00:12 +0200
committerGravatar gegy10002018-05-19 20:00:12 +0200
commit227ccb35a48529724ecf28c94a9156af2f699481 (patch)
treecd6333351b06a2fe0fcae29cf410721856af4f69
parentFix inner class mapping (diff)
downloadenigma-227ccb35a48529724ecf28c94a9156af2f699481.tar.gz
enigma-227ccb35a48529724ecf28c94a9156af2f699481.tar.xz
enigma-227ccb35a48529724ecf28c94a9156af2f699481.zip
More bytecode translation
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java6
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java13
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java26
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java81
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java122
-rw-r--r--src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java58
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Translator.java48
7 files changed, 304 insertions, 50 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index 3433ca9c..cb03d45b 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -532,15 +532,15 @@ public class Deobfuscator {
532 ClassMapping classMapping = mappingChain.get(mappingChain.size() - 1); 532 ClassMapping classMapping = mappingChain.get(mappingChain.size() - 1);
533 return classMapping != null && classMapping.getDeobfName() != null; 533 return classMapping != null && classMapping.getDeobfName() != null;
534 } else if (obfEntry instanceof FieldEntry) { 534 } else if (obfEntry instanceof FieldEntry) {
535 return translator.getTranslatedField((FieldEntry) obfEntry) != null; 535 return translator.hasFieldMapping((FieldEntry) obfEntry);
536 } else if (obfEntry instanceof MethodEntry) { 536 } else if (obfEntry instanceof MethodEntry) {
537 MethodEntry methodEntry = (MethodEntry) obfEntry; 537 MethodEntry methodEntry = (MethodEntry) obfEntry;
538 if (methodEntry.isConstructor()) { 538 if (methodEntry.isConstructor()) {
539 return false; 539 return false;
540 } 540 }
541 return translator.getTranslatedMethod(methodEntry) != null; 541 return translator.hasMethodMapping(methodEntry);
542 } else if (obfEntry instanceof LocalVariableEntry) { 542 } else if (obfEntry instanceof LocalVariableEntry) {
543 return translator.getTranslatedVariable((LocalVariableEntry) obfEntry) != null; 543 return translator.hasLocalVariableMapping((LocalVariableEntry) obfEntry);
544 } else { 544 } else {
545 throw new Error("Unknown entry desc: " + obfEntry.getClass().getName()); 545 throw new Error("Unknown entry desc: " + obfEntry.getClass().getName());
546 } 546 }
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java
index 177691b4..7cc37719 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java
@@ -6,7 +6,6 @@ import cuchaz.enigma.mapping.TypeDescriptor;
6import cuchaz.enigma.mapping.entry.ClassEntry; 6import cuchaz.enigma.mapping.entry.ClassEntry;
7import cuchaz.enigma.mapping.entry.FieldDefEntry; 7import cuchaz.enigma.mapping.entry.FieldDefEntry;
8import org.objectweb.asm.AnnotationVisitor; 8import org.objectweb.asm.AnnotationVisitor;
9import org.objectweb.asm.Type;
10 9
11public class TranslationAnnotationVisitor extends AnnotationVisitor { 10public class TranslationAnnotationVisitor extends AnnotationVisitor {
12 private final Translator translator; 11 private final Translator translator;
@@ -20,12 +19,12 @@ public class TranslationAnnotationVisitor extends AnnotationVisitor {
20 19
21 @Override 20 @Override
22 public void visit(String name, Object value) { 21 public void visit(String name, Object value) {
23 if (value instanceof Type) { 22 super.visit(name, translator.getTranslatedValue(value));
24 Type type = (Type) value; 23 }
25 super.visit(name, translator.getTranslatedType(type)); 24
26 } else { 25 @Override
27 super.visit(name, value); 26 public AnnotationVisitor visitArray(String name) {
28 } 27 return this;
29 } 28 }
30 29
31 @Override 30 @Override
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
index dcc221e3..89772dbb 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
@@ -19,11 +19,7 @@ import cuchaz.enigma.mapping.TypeDescriptor;
19import cuchaz.enigma.mapping.entry.*; 19import cuchaz.enigma.mapping.entry.*;
20import org.objectweb.asm.*; 20import org.objectweb.asm.*;
21 21
22import java.util.regex.Pattern;
23
24public class TranslationClassVisitor extends ClassVisitor { 22public class TranslationClassVisitor extends ClassVisitor {
25 private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*");
26
27 private final Translator translator; 23 private final Translator translator;
28 private final JarIndex jarIndex; 24 private final JarIndex jarIndex;
29 private final ReferencedEntryPool entryPool; 25 private final ReferencedEntryPool entryPool;
@@ -39,9 +35,6 @@ public class TranslationClassVisitor extends ClassVisitor {
39 35
40 @Override 36 @Override
41 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { 37 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
42 if (signature != null && OBJECT_PATTERN.matcher(signature).matches()) {
43 signature = signature.replaceAll(":Ljava/lang/Object;:", "::");
44 }
45 obfClassEntry = new ClassDefEntry(name, new AccessFlags(access)); 38 obfClassEntry = new ClassDefEntry(name, new AccessFlags(access));
46 ClassDefEntry entry = translator.getTranslatedClassDef(obfClassEntry); 39 ClassDefEntry entry = translator.getTranslatedClassDef(obfClassEntry);
47 ClassEntry superEntry = translator.getTranslatedClass(entryPool.getClass(superName)); 40 ClassEntry superEntry = translator.getTranslatedClass(entryPool.getClass(superName));
@@ -49,14 +42,16 @@ public class TranslationClassVisitor extends ClassVisitor {
49 for (int i = 0; i < interfaces.length; i++) { 42 for (int i = 0; i < interfaces.length; i++) {
50 translatedInterfaces[i] = translator.getTranslatedClass(entryPool.getClass(interfaces[i])).getName(); 43 translatedInterfaces[i] = translator.getTranslatedClass(entryPool.getClass(interfaces[i])).getName();
51 } 44 }
52 super.visit(version, entry.getAccess().getFlags(), entry.getName(), signature, superEntry.getName(), translatedInterfaces); 45 String translatedSignature = translator.getTranslatedSignature(signature, false, api);
46 super.visit(version, entry.getAccess().getFlags(), entry.getName(), translatedSignature, superEntry.getName(), translatedInterfaces);
53 } 47 }
54 48
55 @Override 49 @Override
56 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { 50 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
57 FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access)); 51 FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access));
58 FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry); 52 FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry);
59 FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, value); 53 String translatedSignature = translator.getTranslatedSignature(signature, true, api);
54 FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, value);
60 return new TranslationFieldVisitor(translator, translatedEntry, api, fv); 55 return new TranslationFieldVisitor(translator, translatedEntry, api, fv);
61 } 56 }
62 57
@@ -71,19 +66,18 @@ public class TranslationClassVisitor extends ClassVisitor {
71 for (int i = 0; i < exceptions.length; i++) { 66 for (int i = 0; i < exceptions.length; i++) {
72 translatedExceptions[i] = translator.getTranslatedClass(entryPool.getClass(exceptions[i])).getName(); 67 translatedExceptions[i] = translator.getTranslatedClass(entryPool.getClass(exceptions[i])).getName();
73 } 68 }
74 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, translatedExceptions); 69 String translatedSignature = translator.getTranslatedSignature(signature, false, api);
70 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, translatedExceptions);
75 return new TranslationMethodVisitor(translator, translatedEntry, api, mv); 71 return new TranslationMethodVisitor(translator, translatedEntry, api, mv);
76 } 72 }
77 73
78 @Override 74 @Override
79 public void visitOuterClass(String owner, String name, String desc) { 75 public void visitOuterClass(String owner, String name, String desc) {
80 ClassEntry ownerEntry = translator.getTranslatedClass(entryPool.getClass(owner)); 76 if (desc != null) {
81 String translatedDesc = desc != null ? translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString() : desc; 77 MethodEntry translatedEntry = translator.getTranslatedMethod(new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc)));
82 if (name != null) { 78 super.visitOuterClass(translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString());
83 ClassEntry entry = translator.getTranslatedClass(entryPool.getClass(name));
84 super.visitOuterClass(ownerEntry.getName(), entry.getName(), translatedDesc);
85 } else { 79 } else {
86 super.visitOuterClass(ownerEntry.getName(), name, translatedDesc); 80 super.visitOuterClass(owner, name, desc);
87 } 81 }
88 } 82 }
89 83
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
index c7299628..cce91db3 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
@@ -1,6 +1,8 @@
1package cuchaz.enigma.bytecode.translators; 1package cuchaz.enigma.bytecode.translators;
2 2
3import cuchaz.enigma.mapping.*; 3import cuchaz.enigma.mapping.MethodDescriptor;
4import cuchaz.enigma.mapping.Translator;
5import cuchaz.enigma.mapping.TypeDescriptor;
4import cuchaz.enigma.mapping.entry.*; 6import cuchaz.enigma.mapping.entry.*;
5import org.objectweb.asm.*; 7import org.objectweb.asm.*;
6 8
@@ -20,22 +22,35 @@ public class TranslationMethodVisitor extends MethodVisitor {
20 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 22 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
21 FieldEntry entry = new FieldEntry(new ClassEntry(owner), name, new TypeDescriptor(desc)); 23 FieldEntry entry = new FieldEntry(new ClassEntry(owner), name, new TypeDescriptor(desc));
22 FieldEntry translatedEntry = translator.getTranslatedField(entry); 24 FieldEntry translatedEntry = translator.getTranslatedField(entry);
23 if (translatedEntry != null) { 25 super.visitFieldInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString());
24 super.visitFieldInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString());
25 } else {
26 super.visitFieldInsn(opcode, owner, name, desc);
27 }
28 } 26 }
29 27
30 @Override 28 @Override
31 public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 29 public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
32 MethodEntry entry = new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc)); 30 MethodEntry entry = new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc));
33 MethodEntry translatedEntry = translator.getTranslatedMethod(entry); 31 MethodEntry translatedEntry = translator.getTranslatedMethod(entry);
34 if (translatedEntry != null) { 32 super.visitMethodInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString(), itf);
35 super.visitMethodInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString(), itf); 33 }
36 } else { 34
37 super.visitMethodInsn(opcode, owner, name, desc, itf); 35 @Override
36 public void visitFrame(int type, int localCount, Object[] locals, int stackCount, Object[] stack) {
37 Object[] translatedLocals = this.getTranslatedFrame(locals, localCount);
38 Object[] translatedStack = this.getTranslatedFrame(stack, stackCount);
39 super.visitFrame(type, localCount, translatedLocals, stackCount, translatedStack);
40 }
41
42 private Object[] getTranslatedFrame(Object[] array, int count) {
43 if (array == null) {
44 return null;
38 } 45 }
46 for (int i = 0; i < count; i++) {
47 Object object = array[i];
48 if (object instanceof String) {
49 ClassEntry entry = new ClassEntry((String) object);
50 array[i] = translator.getTranslatedClass(entry).getName();
51 }
52 }
53 return array;
39 } 54 }
40 55
41 @Override 56 @Override
@@ -46,6 +61,13 @@ public class TranslationMethodVisitor extends MethodVisitor {
46 } 61 }
47 62
48 @Override 63 @Override
64 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
65 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
66 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
67 return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av);
68 }
69
70 @Override
49 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { 71 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
50 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc)); 72 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
51 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); 73 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
@@ -80,6 +102,43 @@ public class TranslationMethodVisitor extends MethodVisitor {
80 } 102 }
81 translatedName = nameBuilder.toString(); 103 translatedName = nameBuilder.toString();
82 } 104 }
83 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), signature, start, end, index); 105 String translatedSignature = translator.getTranslatedSignature(signature, true, api);
106 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index);
107 }
108
109 @Override
110 public void visitTypeInsn(int opcode, String type) {
111 ClassEntry translatedEntry = translator.getTranslatedClass(new ClassEntry(type));
112 super.visitTypeInsn(opcode, translatedEntry.getName());
113 }
114
115 @Override
116 public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
117 MethodDescriptor translatedMethodDesc = translator.getTranslatedMethodDesc(new MethodDescriptor(desc));
118 Object[] translatedBsmArgs = new Object[bsmArgs.length];
119 for (int i = 0; i < bsmArgs.length; i++) {
120 translatedBsmArgs[i] = translator.getTranslatedValue(bsmArgs[i]);
121 }
122 super.visitInvokeDynamicInsn(name, translatedMethodDesc.toString(), translator.getTranslatedHandle(bsm), translatedBsmArgs);
123 }
124
125 @Override
126 public void visitLdcInsn(Object cst) {
127 super.visitLdcInsn(translator.getTranslatedValue(cst));
128 }
129
130 @Override
131 public void visitMultiANewArrayInsn(String desc, int dims) {
132 super.visitMultiANewArrayInsn(translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString(), dims);
133 }
134
135 @Override
136 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
137 if (type != null) {
138 ClassEntry translatedEntry = translator.getTranslatedClass(new ClassEntry(type));
139 super.visitTryCatchBlock(start, end, handler, translatedEntry.getName());
140 } else {
141 super.visitTryCatchBlock(start, end, handler, type);
142 }
84 } 143 }
85} 144}
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java
new file mode 100644
index 00000000..e1dcea5c
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java
@@ -0,0 +1,122 @@
1package cuchaz.enigma.bytecode.translators;
2
3import cuchaz.enigma.mapping.Translator;
4import cuchaz.enigma.mapping.entry.ClassEntry;
5import org.objectweb.asm.signature.SignatureVisitor;
6
7import java.util.Stack;
8
9public class TranslationSignatureVisitor extends SignatureVisitor {
10 private final Translator translator;
11
12 private final SignatureVisitor sv;
13 private final Stack<ClassEntry> classes = new Stack<>();
14
15 public TranslationSignatureVisitor(Translator translator, int api, SignatureVisitor sv) {
16 super(api);
17 this.translator = translator;
18 this.sv = sv;
19 }
20
21 @Override
22 public void visitClassType(String name) {
23 ClassEntry entry = new ClassEntry(name);
24 ClassEntry translatedEntry = this.translator.getTranslatedClass(entry);
25 this.classes.push(entry);
26 this.sv.visitClassType(translatedEntry.getName());
27 }
28
29 @Override
30 public void visitInnerClassType(String name) {
31 ClassEntry outerEntry = this.classes.pop();
32 ClassEntry entry = new ClassEntry(outerEntry + "$" + name);
33 this.classes.push(entry);
34 String translatedEntry = this.translator.getTranslatedClass(entry).getName();
35 this.sv.visitInnerClassType(translatedEntry.substring(translatedEntry.lastIndexOf('$') + 1));
36 }
37
38 @Override
39 public void visitFormalTypeParameter(String name) {
40 this.sv.visitFormalTypeParameter(name);
41 }
42
43 @Override
44 public void visitTypeVariable(String name) {
45 this.sv.visitTypeVariable(name);
46 }
47
48 @Override
49 public SignatureVisitor visitArrayType() {
50 this.sv.visitArrayType();
51 return this;
52 }
53
54 @Override
55 public void visitBaseType(char descriptor) {
56 this.sv.visitBaseType(descriptor);
57 }
58
59 @Override
60 public SignatureVisitor visitClassBound() {
61 this.sv.visitClassBound();
62 return this;
63 }
64
65 @Override
66 public SignatureVisitor visitExceptionType() {
67 this.sv.visitExceptionType();
68 return this;
69 }
70
71 @Override
72 public SignatureVisitor visitInterface() {
73 this.sv.visitInterface();
74 return this;
75 }
76
77 @Override
78 public SignatureVisitor visitInterfaceBound() {
79 this.sv.visitInterfaceBound();
80 return this;
81 }
82
83 @Override
84 public SignatureVisitor visitParameterType() {
85 this.sv.visitParameterType();
86 return this;
87 }
88
89 @Override
90 public SignatureVisitor visitReturnType() {
91 this.sv.visitReturnType();
92 return this;
93 }
94
95 @Override
96 public SignatureVisitor visitSuperclass() {
97 this.sv.visitSuperclass();
98 return this;
99 }
100
101 @Override
102 public void visitTypeArgument() {
103 this.sv.visitTypeArgument();
104 }
105
106 @Override
107 public SignatureVisitor visitTypeArgument(char wildcard) {
108 this.sv.visitTypeArgument(wildcard);
109 return this;
110 }
111
112 @Override
113 public void visitEnd() {
114 this.sv.visitEnd();
115 this.classes.pop();
116 }
117
118 @Override
119 public String toString() {
120 return this.sv.toString();
121 }
122}
diff --git a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
index 7af1a523..dec5acf4 100644
--- a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
+++ b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
@@ -15,13 +15,19 @@ import com.google.common.collect.Lists;
15import com.google.common.collect.Maps; 15import com.google.common.collect.Maps;
16import cuchaz.enigma.analysis.TranslationIndex; 16import cuchaz.enigma.analysis.TranslationIndex;
17import cuchaz.enigma.bytecode.AccessFlags; 17import cuchaz.enigma.bytecode.AccessFlags;
18import cuchaz.enigma.bytecode.translators.TranslationSignatureVisitor;
18import cuchaz.enigma.mapping.entry.*; 19import cuchaz.enigma.mapping.entry.*;
20import org.objectweb.asm.signature.SignatureReader;
21import org.objectweb.asm.signature.SignatureVisitor;
22import org.objectweb.asm.signature.SignatureWriter;
19 23
20import java.util.ArrayList; 24import java.util.ArrayList;
21import java.util.List; 25import java.util.List;
22import java.util.Map; 26import java.util.Map;
27import java.util.regex.Pattern;
23 28
24public class DirectionalTranslator implements Translator { 29public class DirectionalTranslator implements Translator {
30 private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*");
25 31
26 private final TranslationDirection direction; 32 private final TranslationDirection direction;
27 private final Map<String, ClassMapping> classes; 33 private final Map<String, ClassMapping> classes;
@@ -98,7 +104,7 @@ public class DirectionalTranslator implements Translator {
98 public FieldDefEntry getTranslatedFieldDef(FieldDefEntry entry) { 104 public FieldDefEntry getTranslatedFieldDef(FieldDefEntry entry) {
99 String translatedName = translateFieldName(entry); 105 String translatedName = translateFieldName(entry);
100 if (translatedName == null) { 106 if (translatedName == null) {
101 return entry; 107 translatedName = entry.getName();
102 } 108 }
103 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); 109 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry());
104 TypeDescriptor translatedDesc = getTranslatedTypeDesc(entry.getDesc()); 110 TypeDescriptor translatedDesc = getTranslatedTypeDesc(entry.getDesc());
@@ -110,7 +116,7 @@ public class DirectionalTranslator implements Translator {
110 public FieldEntry getTranslatedField(FieldEntry entry) { 116 public FieldEntry getTranslatedField(FieldEntry entry) {
111 String translatedName = translateFieldName(entry); 117 String translatedName = translateFieldName(entry);
112 if (translatedName == null) { 118 if (translatedName == null) {
113 return null; 119 translatedName = entry.getName();
114 } 120 }
115 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); 121 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry());
116 TypeDescriptor translatedDesc = getTranslatedTypeDesc(entry.getDesc()); 122 TypeDescriptor translatedDesc = getTranslatedTypeDesc(entry.getDesc());
@@ -138,7 +144,7 @@ public class DirectionalTranslator implements Translator {
138 public MethodDefEntry getTranslatedMethodDef(MethodDefEntry entry) { 144 public MethodDefEntry getTranslatedMethodDef(MethodDefEntry entry) {
139 String translatedName = translateMethodName(entry); 145 String translatedName = translateMethodName(entry);
140 if (translatedName == null) { 146 if (translatedName == null) {
141 return entry; 147 translatedName = entry.getName();
142 } 148 }
143 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); 149 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry());
144 MethodDescriptor translatedDesc = getTranslatedMethodDesc(entry.getDesc()); 150 MethodDescriptor translatedDesc = getTranslatedMethodDesc(entry.getDesc());
@@ -150,7 +156,7 @@ public class DirectionalTranslator implements Translator {
150 public MethodEntry getTranslatedMethod(MethodEntry entry) { 156 public MethodEntry getTranslatedMethod(MethodEntry entry) {
151 String translatedName = translateMethodName(entry); 157 String translatedName = translateMethodName(entry);
152 if (translatedName == null) { 158 if (translatedName == null) {
153 return null; 159 translatedName = entry.getName();
154 } 160 }
155 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); 161 ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry());
156 MethodDescriptor translatedDesc = getTranslatedMethodDesc(entry.getDesc()); 162 MethodDescriptor translatedDesc = getTranslatedMethodDesc(entry.getDesc());
@@ -181,11 +187,11 @@ public class DirectionalTranslator implements Translator {
181 translatedArgumentName = inheritLocalVariableName(entry); 187 translatedArgumentName = inheritLocalVariableName(entry);
182 } 188 }
183 if (translatedArgumentName == null) { 189 if (translatedArgumentName == null) {
184 return null; 190 translatedArgumentName = entry.getName();
185 } 191 }
186 // TODO: Translating arguments calls method translation.. Can we refactor the code in such a way that we don't need this? 192 // TODO: Translating arguments calls method translation.. Can we refactor the code in such a way that we don't need this?
187 MethodEntry translatedOwner = getTranslatedMethod(entry.getOwnerEntry()); 193 MethodEntry translatedOwner = getTranslatedMethod(entry.getOwnerEntry());
188 return new LocalVariableEntry(translatedOwner != null ? translatedOwner : entry.getOwnerEntry(), entry.getIndex(), translatedArgumentName); 194 return new LocalVariableEntry(translatedOwner, entry.getIndex(), translatedArgumentName);
189 } 195 }
190 196
191 @Override 197 @Override
@@ -200,6 +206,26 @@ public class DirectionalTranslator implements Translator {
200 return new LocalVariableDefEntry(translatedOwner, entry.getIndex(), translatedArgumentName != null ? translatedArgumentName : entry.getName(), translatedTypeDesc); 206 return new LocalVariableDefEntry(translatedOwner, entry.getIndex(), translatedArgumentName != null ? translatedArgumentName : entry.getName(), translatedTypeDesc);
201 } 207 }
202 208
209 @Override
210 public boolean hasClassMapping(ClassEntry entry) {
211 return classes.containsKey(entry.getName());
212 }
213
214 @Override
215 public boolean hasFieldMapping(FieldEntry entry) {
216 return translateFieldName(entry) != null;
217 }
218
219 @Override
220 public boolean hasMethodMapping(MethodEntry entry) {
221 return translateMethodName(entry) != null;
222 }
223
224 @Override
225 public boolean hasLocalVariableMapping(LocalVariableEntry entry) {
226 return translateLocalVariableName(entry) != null || inheritLocalVariableName(entry) != null;
227 }
228
203 // TODO: support not identical behavior (specific to constructor) 229 // TODO: support not identical behavior (specific to constructor)
204 private String translateLocalVariableName(LocalVariableEntry entry) { 230 private String translateLocalVariableName(LocalVariableEntry entry) {
205 // look for identical behavior in superclasses 231 // look for identical behavior in superclasses
@@ -252,6 +278,26 @@ public class DirectionalTranslator implements Translator {
252 return new MethodDescriptor(translatedArguments, getTranslatedTypeDesc(descriptor.getReturnDesc())); 278 return new MethodDescriptor(translatedArguments, getTranslatedTypeDesc(descriptor.getReturnDesc()));
253 } 279 }
254 280
281 @Override
282 public String getTranslatedSignature(String signature, boolean isType, int api) {
283 if (signature == null) {
284 return null;
285 }
286 SignatureReader reader = new SignatureReader(signature);
287 SignatureWriter writer = new SignatureWriter();
288 SignatureVisitor visitor = new TranslationSignatureVisitor(this, api, writer);
289 if (isType) {
290 reader.acceptType(visitor);
291 } else {
292 reader.accept(visitor);
293 }
294 String translatedSignature = writer.toString();
295 if (OBJECT_PATTERN.matcher(signature).matches()) {
296 translatedSignature = signature.replaceAll(":Ljava/lang/Object;:", "::");
297 }
298 return translatedSignature;
299 }
300
255 private ClassMapping findClassMapping(ClassEntry entry) { 301 private ClassMapping findClassMapping(ClassEntry entry) {
256 List<ClassMapping> mappingChain = getClassMappingChain(entry); 302 List<ClassMapping> mappingChain = getClassMappingChain(entry);
257 return mappingChain.get(mappingChain.size() - 1); 303 return mappingChain.get(mappingChain.size() - 1);
diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java
index 6373da7b..1bc2f373 100644
--- a/src/main/java/cuchaz/enigma/mapping/Translator.java
+++ b/src/main/java/cuchaz/enigma/mapping/Translator.java
@@ -12,6 +12,7 @@
12package cuchaz.enigma.mapping; 12package cuchaz.enigma.mapping;
13 13
14import cuchaz.enigma.mapping.entry.*; 14import cuchaz.enigma.mapping.entry.*;
15import org.objectweb.asm.Handle;
15import org.objectweb.asm.Type; 16import org.objectweb.asm.Type;
16 17
17public interface Translator { 18public interface Translator {
@@ -31,20 +32,53 @@ public interface Translator {
31 32
32 LocalVariableDefEntry getTranslatedVariableDef(LocalVariableDefEntry entry); 33 LocalVariableDefEntry getTranslatedVariableDef(LocalVariableDefEntry entry);
33 34
35 boolean hasClassMapping(ClassEntry entry);
36
37 boolean hasFieldMapping(FieldEntry entry);
38
39 boolean hasMethodMapping(MethodEntry entry);
40
41 boolean hasLocalVariableMapping(LocalVariableEntry entry);
42
34 TypeDescriptor getTranslatedTypeDesc(TypeDescriptor desc); 43 TypeDescriptor getTranslatedTypeDesc(TypeDescriptor desc);
35 44
36 MethodDescriptor getTranslatedMethodDesc(MethodDescriptor descriptor); 45 MethodDescriptor getTranslatedMethodDesc(MethodDescriptor descriptor);
37 46
47 String getTranslatedSignature(String signature, boolean isType, int api);
48
38 default Type getTranslatedType(Type type) { 49 default Type getTranslatedType(Type type) {
39 String descString = type.getDescriptor(); 50 String descString = type.getDescriptor();
40 // If this is a method 51 switch (type.getSort()) {
41 if (descString.contains("(")) { 52 case Type.OBJECT: {
42 MethodDescriptor descriptor = new MethodDescriptor(descString); 53 ClassEntry classEntry = new ClassEntry(type.getInternalName());
43 return Type.getMethodType(getTranslatedMethodDesc(descriptor).toString()); 54 return Type.getObjectType(getTranslatedClass(classEntry).getName());
44 } else { 55 }
45 TypeDescriptor descriptor = new TypeDescriptor(descString); 56 case Type.ARRAY: {
46 return Type.getType(getTranslatedTypeDesc(descriptor).toString()); 57 TypeDescriptor descriptor = new TypeDescriptor(descString);
58 return Type.getType(getTranslatedTypeDesc(descriptor).toString());
59 }
60 case Type.METHOD: {
61 MethodDescriptor descriptor = new MethodDescriptor(descString);
62 return Type.getMethodType(getTranslatedMethodDesc(descriptor).toString());
63 }
64 }
65 return type;
66 }
67
68 default Handle getTranslatedHandle(Handle handle) {
69 MethodEntry entry = new MethodEntry(new ClassEntry(handle.getOwner()), handle.getName(), new MethodDescriptor(handle.getDesc()));
70 MethodEntry translatedMethod = getTranslatedMethod(entry);
71 ClassEntry ownerClass = translatedMethod.getOwnerClassEntry();
72 return new Handle(handle.getTag(), ownerClass.getName(), translatedMethod.getName(), translatedMethod.getDesc().toString(), handle.isInterface());
73 }
74
75 default Object getTranslatedValue(Object value) {
76 if (value instanceof Type) {
77 return this.getTranslatedType((Type) value);
78 } else if (value instanceof Handle) {
79 return getTranslatedHandle((Handle) value);
47 } 80 }
81 return value;
48 } 82 }
49 83
50 @SuppressWarnings("unchecked") 84 @SuppressWarnings("unchecked")