summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/bytecode
diff options
context:
space:
mode:
authorGravatar Gegy2019-01-30 21:05:32 +0200
committerGravatar GitHub2019-01-30 21:05:32 +0200
commitba7a354efae7d49833c887cf147ac940c975a1fa (patch)
tree02e14fda81dd5984e24f2df392c57c6e829fc875 /src/main/java/cuchaz/enigma/bytecode
parentRewrite the Jenkinsfile to use the new declarative pipeline syntax, lets hope... (diff)
downloadenigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.tar.gz
enigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.tar.xz
enigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.zip
Remap sources (#106)
* Source remapping beginnings * Fix navigation to remapped classes * Translate identifier info reference * Remap local variables with default names in source * Caching translator * Fix lack of highlighting for first opened class * Fix unicode variable names * Unicode checker shouldn't be checking just alphanumeric * Fix package tree being built from obf names * Don't index `this` as method call for method::reference * Apply proposed names * Fix source export issues * Replace unicode var names at bytecode level uniquely * Drop imports from editor source * Class selector fixes * Delta keep track of base mappings to enable lookup of old names * Optimize source remapping by remapping source with a StringBuffer instead of copying * Bump version
Diffstat (limited to 'src/main/java/cuchaz/enigma/bytecode')
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/LocalVariableFixVisitor.java80
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java7
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java111
3 files changed, 119 insertions, 79 deletions
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/LocalVariableFixVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/LocalVariableFixVisitor.java
new file mode 100644
index 0000000..16dbba1
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/LocalVariableFixVisitor.java
@@ -0,0 +1,80 @@
1package cuchaz.enigma.bytecode.translators;
2
3import com.google.common.base.CharMatcher;
4import cuchaz.enigma.translation.representation.TypeDescriptor;
5import cuchaz.enigma.translation.representation.entry.ClassDefEntry;
6import cuchaz.enigma.translation.representation.entry.MethodDefEntry;
7import org.objectweb.asm.ClassVisitor;
8import org.objectweb.asm.Label;
9import org.objectweb.asm.MethodVisitor;
10
11import java.util.List;
12
13public class LocalVariableFixVisitor extends ClassVisitor {
14 private ClassDefEntry ownerEntry;
15
16 public LocalVariableFixVisitor(int api, ClassVisitor visitor) {
17 super(api, visitor);
18 }
19
20 @Override
21 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
22 ownerEntry = ClassDefEntry.parse(access, name, signature, superName, interfaces);
23 super.visit(version, access, name, signature, superName, interfaces);
24 }
25
26 @Override
27 public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
28 MethodDefEntry methodEntry = MethodDefEntry.parse(ownerEntry, access, name, descriptor, signature);
29 return new Method(api, methodEntry, super.visitMethod(access, name, descriptor, signature, exceptions));
30 }
31
32 private class Method extends MethodVisitor {
33 private final MethodDefEntry methodEntry;
34 private boolean hasLvt;
35
36 Method(int api, MethodDefEntry methodEntry, MethodVisitor visitor) {
37 super(api, visitor);
38 this.methodEntry = methodEntry;
39 }
40
41 @Override
42 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
43 hasLvt = true;
44
45 String translatedName = name;
46
47 if (isInvalidName(name)) {
48 int argumentIndex = methodEntry.getArgumentIndex(ownerEntry, index);
49
50 if (argumentIndex >= 0) {
51 List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs();
52 boolean argument = argumentIndex < arguments.size();
53 if (argument) {
54 translatedName = "arg" + (argumentIndex + 1);
55 } else {
56 translatedName = "var" + (argumentIndex + 1);
57 }
58 }
59 }
60
61 super.visitLocalVariable(translatedName, desc, signature, start, end, index);
62 }
63
64 private boolean isInvalidName(String name) {
65 return !CharMatcher.ascii().matchesAllOf(name);
66 }
67
68 @Override
69 public void visitEnd() {
70 if (!hasLvt) {
71 List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs();
72 for (int argumentIndex = 0; argumentIndex < arguments.size(); argumentIndex++) {
73 super.visitParameter("arg" + (argumentIndex + 1), 0);
74 }
75 }
76
77 super.visitEnd();
78 }
79 }
80}
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
index 53d09bb..e4c41d3 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
@@ -13,7 +13,6 @@ package cuchaz.enigma.bytecode.translators;
13 13
14import cuchaz.enigma.translation.Translator; 14import cuchaz.enigma.translation.Translator;
15import cuchaz.enigma.translation.representation.MethodDescriptor; 15import cuchaz.enigma.translation.representation.MethodDescriptor;
16import cuchaz.enigma.translation.representation.ReferencedEntryPool;
17import cuchaz.enigma.translation.representation.TypeDescriptor; 16import cuchaz.enigma.translation.representation.TypeDescriptor;
18import cuchaz.enigma.translation.representation.entry.*; 17import cuchaz.enigma.translation.representation.entry.*;
19import org.objectweb.asm.*; 18import org.objectweb.asm.*;
@@ -22,14 +21,12 @@ import java.util.Arrays;
22 21
23public class TranslationClassVisitor extends ClassVisitor { 22public class TranslationClassVisitor extends ClassVisitor {
24 private final Translator translator; 23 private final Translator translator;
25 private final ReferencedEntryPool entryPool;
26 24
27 private ClassDefEntry obfClassEntry; 25 private ClassDefEntry obfClassEntry;
28 26
29 public TranslationClassVisitor(Translator translator, ReferencedEntryPool entryPool, int api, ClassVisitor cv) { 27 public TranslationClassVisitor(Translator translator, int api, ClassVisitor cv) {
30 super(api, cv); 28 super(api, cv);
31 this.translator = translator; 29 this.translator = translator;
32 this.entryPool = entryPool;
33 } 30 }
34 31
35 @Override 32 @Override
@@ -57,7 +54,7 @@ public class TranslationClassVisitor extends ClassVisitor {
57 MethodDefEntry translatedEntry = translator.translate(entry); 54 MethodDefEntry translatedEntry = translator.translate(entry);
58 String[] translatedExceptions = new String[exceptions.length]; 55 String[] translatedExceptions = new String[exceptions.length];
59 for (int i = 0; i < exceptions.length; i++) { 56 for (int i = 0; i < exceptions.length; i++) {
60 translatedExceptions[i] = translator.translate(entryPool.getClass(exceptions[i])).getFullName(); 57 translatedExceptions[i] = translator.translate(new ClassEntry(exceptions[i])).getFullName();
61 } 58 }
62 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedEntry.getSignature().toString(), translatedExceptions); 59 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedEntry.getSignature().toString(), translatedExceptions);
63 return new TranslationMethodVisitor(translator, obfClassEntry, entry, api, mv); 60 return new TranslationMethodVisitor(translator, obfClassEntry, entry, api, mv);
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
index a5a33e6..c824265 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
@@ -1,16 +1,14 @@
1package cuchaz.enigma.bytecode.translators; 1package cuchaz.enigma.bytecode.translators;
2 2
3import cuchaz.enigma.translation.LocalNameGenerator;
3import cuchaz.enigma.translation.Translator; 4import cuchaz.enigma.translation.Translator;
4import cuchaz.enigma.translation.mapping.NameValidator;
5import cuchaz.enigma.translation.representation.MethodDescriptor; 5import cuchaz.enigma.translation.representation.MethodDescriptor;
6import cuchaz.enigma.translation.representation.Signature; 6import cuchaz.enigma.translation.representation.Signature;
7import cuchaz.enigma.translation.representation.TypeDescriptor; 7import cuchaz.enigma.translation.representation.TypeDescriptor;
8import cuchaz.enigma.translation.representation.entry.*; 8import cuchaz.enigma.translation.representation.entry.*;
9import org.objectweb.asm.*; 9import org.objectweb.asm.*;
10 10
11import java.util.Collection;
12import java.util.List; 11import java.util.List;
13import java.util.Locale;
14import java.util.stream.Collectors; 12import java.util.stream.Collectors;
15 13
16public class TranslationMethodVisitor extends MethodVisitor { 14public class TranslationMethodVisitor extends MethodVisitor {
@@ -84,40 +82,6 @@ public class TranslationMethodVisitor extends MethodVisitor {
84 } 82 }
85 83
86 @Override 84 @Override
87 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
88 hasParameterMeta = true;
89
90 String translatedSignature = translator.translate(Signature.createTypedSignature(signature)).toString();
91 int argumentIndex = methodEntry.getArgumentIndex(ownerEntry, index);
92
93 if (argumentIndex >= 0) {
94 LocalVariableDefEntry entry = new LocalVariableDefEntry(methodEntry, index, name, true, new TypeDescriptor(desc));
95 LocalVariableDefEntry translatedEntry = translator.translate(entry);
96 String translatedName = translatedEntry.getName();
97
98 if (translatedName.equals(entry.getName())) {
99 List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs();
100 List<TypeDescriptor> translatedArguments = arguments.stream()
101 .map(translator::translate)
102 .collect(Collectors.toList());
103
104 boolean argument = argumentIndex < arguments.size();
105 if (argument) {
106 translatedName = inferArgumentName(argumentIndex, translatedEntry.getDesc(), translatedArguments);
107 } else {
108 translatedName = inferLocalVariableName(argumentIndex, translatedEntry.getDesc());
109 }
110 }
111
112 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index);
113 } else {
114 // Handle "this" variable
115 TypeDescriptor translatedDesc = translator.translate(new TypeDescriptor(desc));
116 super.visitLocalVariable(name, translatedDesc.toString(), translatedSignature, start, end, index);
117 }
118 }
119
120 @Override
121 public void visitTypeInsn(int opcode, String type) { 85 public void visitTypeInsn(int opcode, String type) {
122 ClassEntry translatedEntry = translator.translate(new ClassEntry(type)); 86 ClassEntry translatedEntry = translator.translate(new ClassEntry(type));
123 super.visitTypeInsn(opcode, translatedEntry.getFullName()); 87 super.visitTypeInsn(opcode, translatedEntry.getFullName());
@@ -154,10 +118,44 @@ public class TranslationMethodVisitor extends MethodVisitor {
154 } 118 }
155 119
156 @Override 120 @Override
121 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
122 hasParameterMeta = true;
123
124 String translatedSignature = translator.translate(Signature.createTypedSignature(signature)).toString();
125 int argumentIndex = methodEntry.getArgumentIndex(ownerEntry, index);
126
127 if (argumentIndex >= 0) {
128 LocalVariableDefEntry entry = new LocalVariableDefEntry(methodEntry, index, name, true, new TypeDescriptor(desc));
129 LocalVariableDefEntry translatedEntry = translator.translate(entry);
130 String translatedName = translatedEntry.getName();
131
132 if (translatedName.equals(entry.getName())) {
133 List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs();
134 List<TypeDescriptor> translatedArguments = arguments.stream()
135 .map(translator::translate)
136 .collect(Collectors.toList());
137
138 boolean argument = argumentIndex < arguments.size();
139 if (argument) {
140 translatedName = LocalNameGenerator.generateArgumentName(argumentIndex, translatedEntry.getDesc(), translatedArguments);
141 } else {
142 translatedName = LocalNameGenerator.generateLocalVariableName(argumentIndex, translatedEntry.getDesc());
143 }
144 }
145
146 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index);
147 } else {
148 // Handle "this" variable
149 TypeDescriptor translatedDesc = translator.translate(new TypeDescriptor(desc));
150 super.visitLocalVariable(name, translatedDesc.toString(), translatedSignature, start, end, index);
151 }
152 }
153
154 @Override
157 public void visitEnd() { 155 public void visitEnd() {
158 // If we didn't receive any parameter metadata, generate it 156 // If we didn't receive any parameter metadata, generate it
159 if (!hasParameterMeta) { 157 if (!hasParameterMeta) {
160 List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs(); 158 List<TypeDescriptor> arguments = translator.translate(methodEntry.getDesc()).getArgumentDescs();
161 int offset = ((methodEntry.getAccess().getFlags() & Opcodes.ACC_ABSTRACT) != 0) ? 1 : 0; 159 int offset = ((methodEntry.getAccess().getFlags() & Opcodes.ACC_ABSTRACT) != 0) ? 1 : 0;
162 160
163 for (int argumentIndex = 0; argumentIndex < arguments.size(); argumentIndex++) { 161 for (int argumentIndex = 0; argumentIndex < arguments.size(); argumentIndex++) {
@@ -165,7 +163,7 @@ public class TranslationMethodVisitor extends MethodVisitor {
165 LocalVariableEntry translatedEntry = translator.translate(entry); 163 LocalVariableEntry translatedEntry = translator.translate(entry);
166 String translatedName = translatedEntry.getName(); 164 String translatedName = translatedEntry.getName();
167 if (translatedName.equals(entry.getName())) { 165 if (translatedName.equals(entry.getName())) {
168 super.visitParameter(inferArgumentName(argumentIndex, arguments.get(argumentIndex), arguments), 0); 166 super.visitParameter(LocalNameGenerator.generateArgumentName(argumentIndex, arguments.get(argumentIndex), arguments), 0);
169 } else { 167 } else {
170 super.visitParameter(translatedName, 0); 168 super.visitParameter(translatedName, 0);
171 } 169 }
@@ -175,39 +173,4 @@ public class TranslationMethodVisitor extends MethodVisitor {
175 } 173 }
176 super.visitEnd(); 174 super.visitEnd();
177 } 175 }
178
179 private String inferArgumentName(int index, TypeDescriptor desc, Collection<TypeDescriptor> arguments) {
180 boolean uniqueType = arguments.stream().filter(desc::equals).count() <= 1;
181 String translatedName;
182 int nameIndex = index + 1;
183 StringBuilder nameBuilder = new StringBuilder(getTypeName(desc));
184 if (!uniqueType || NameValidator.isReserved(nameBuilder.toString())) {
185 nameBuilder.append(nameIndex);
186 }
187 translatedName = nameBuilder.toString();
188 return translatedName;
189 }
190
191 private String inferLocalVariableName(int index, TypeDescriptor desc) {
192 int nameIndex = index + 1;
193 return getTypeName(desc) + nameIndex;
194 }
195
196 private String getTypeName(TypeDescriptor desc) {
197 // Unfortunately each of these have different name getters, so they have different code paths
198 if (desc.isPrimitive()) {
199 TypeDescriptor.Primitive argCls = desc.getPrimitive();
200 return argCls.name().toLowerCase(Locale.ROOT);
201 } else if (desc.isArray()) {
202 // List types would require this whole block again, so just go with aListx
203 return "arr";
204 } else if (desc.isType()) {
205 String typeName = desc.getTypeEntry().getSimpleName().replace("$", "");
206 typeName = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1);
207 return typeName;
208 } else {
209 System.err.println("Encountered invalid argument type descriptor " + desc.toString());
210 return "var";
211 }
212 }
213} 176}