summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java12
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java62
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java6
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java19
-rw-r--r--src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java10
5 files changed, 54 insertions, 55 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
index 1e2eed8d..dd5bcef0 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
@@ -17,16 +17,18 @@ import com.strobel.assembler.metadata.TypeDefinition;
17import com.strobel.assembler.metadata.TypeReference; 17import com.strobel.assembler.metadata.TypeReference;
18import com.strobel.decompiler.languages.TextLocation; 18import com.strobel.decompiler.languages.TextLocation;
19import com.strobel.decompiler.languages.java.ast.*; 19import com.strobel.decompiler.languages.java.ast.*;
20import cuchaz.enigma.bytecode.AccessFlags;
21import cuchaz.enigma.mapping.Signature;
20import cuchaz.enigma.mapping.entry.*; 22import cuchaz.enigma.mapping.entry.*;
21 23
22public class SourceIndexClassVisitor extends SourceIndexVisitor { 24public class SourceIndexClassVisitor extends SourceIndexVisitor {
23 private final ReferencedEntryPool entryPool; 25 private final ReferencedEntryPool entryPool;
24 private final ProcyonEntryFactory entryFactory; 26 private final ProcyonEntryFactory entryFactory;
25 27
26 private ClassEntry classEntry; 28 private ClassDefEntry classEntry;
27 private boolean isEnum; 29 private boolean isEnum;
28 30
29 public SourceIndexClassVisitor(ReferencedEntryPool entryPool, ClassEntry classEntry) { 31 public SourceIndexClassVisitor(ReferencedEntryPool entryPool, ClassDefEntry classEntry) {
30 super(entryPool); 32 super(entryPool);
31 this.entryPool = entryPool; 33 this.entryPool = entryPool;
32 this.entryFactory = new ProcyonEntryFactory(entryPool); 34 this.entryFactory = new ProcyonEntryFactory(entryPool);
@@ -37,7 +39,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor {
37 public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) { 39 public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) {
38 // is this this class, or a subtype? 40 // is this this class, or a subtype?
39 TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION); 41 TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION);
40 ClassEntry classEntry = new ClassEntry(def.getInternalName()); 42 ClassDefEntry classEntry = new ClassDefEntry(def.getInternalName(), Signature.createSignature(def.getSignature()), new AccessFlags(def.getModifiers()));
41 if (!classEntry.equals(this.classEntry)) { 43 if (!classEntry.equals(this.classEntry)) {
42 // it's a subtype, recurse 44 // it's a subtype, recurse
43 index.addDeclaration(node.getNameToken(), classEntry); 45 index.addDeclaration(node.getNameToken(), classEntry);
@@ -68,7 +70,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor {
68 tokenNode = node.getModifiers().firstOrNullObject(); 70 tokenNode = node.getModifiers().firstOrNullObject();
69 } 71 }
70 index.addDeclaration(tokenNode, methodEntry); 72 index.addDeclaration(tokenNode, methodEntry);
71 return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, methodEntry, false), index); 73 return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, classEntry, methodEntry), index);
72 } 74 }
73 75
74 @Override 76 @Override
@@ -76,7 +78,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor {
76 MethodDefinition def = node.getUserData(Keys.METHOD_DEFINITION); 78 MethodDefinition def = node.getUserData(Keys.METHOD_DEFINITION);
77 MethodDefEntry methodEntry = entryFactory.getMethodDefEntry(def); 79 MethodDefEntry methodEntry = entryFactory.getMethodDefEntry(def);
78 index.addDeclaration(node.getNameToken(), methodEntry); 80 index.addDeclaration(node.getNameToken(), methodEntry);
79 return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, methodEntry, isEnum), index); 81 return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, classEntry, methodEntry), index);
80 } 82 }
81 83
82 @Override 84 @Override
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java
index 01e773b3..51195a4d 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java
@@ -13,15 +13,14 @@ package cuchaz.enigma.analysis;
13 13
14import com.google.common.collect.HashMultimap; 14import com.google.common.collect.HashMultimap;
15import com.google.common.collect.Multimap; 15import com.google.common.collect.Multimap;
16import com.strobel.assembler.metadata.MemberReference; 16import com.strobel.assembler.metadata.*;
17import com.strobel.assembler.metadata.MethodReference; 17import com.strobel.decompiler.ast.Variable;
18import com.strobel.assembler.metadata.ParameterDefinition;
19import com.strobel.assembler.metadata.TypeReference;
20import com.strobel.decompiler.languages.TextLocation; 18import com.strobel.decompiler.languages.TextLocation;
21import com.strobel.decompiler.languages.java.ast.*; 19import com.strobel.decompiler.languages.java.ast.*;
22import cuchaz.enigma.mapping.*; 20import cuchaz.enigma.mapping.TypeDescriptor;
23import cuchaz.enigma.mapping.entry.*; 21import cuchaz.enigma.mapping.entry.*;
24 22
23import java.lang.Error;
25import java.util.HashMap; 24import java.util.HashMap;
26import java.util.Map; 25import java.util.Map;
27 26
@@ -29,21 +28,18 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor {
29 private final ReferencedEntryPool entryPool; 28 private final ReferencedEntryPool entryPool;
30 private final ProcyonEntryFactory entryFactory; 29 private final ProcyonEntryFactory entryFactory;
31 30
32 private MethodDefEntry methodEntry; 31 private final ClassDefEntry ownerEntry;
32 private final MethodDefEntry methodEntry;
33 33
34 // TODO: Really fix Procyon index problem with inner classes
35 private int argumentPosition;
36 private int localsPosition;
37 private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create(); 34 private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create();
38 private Map<String, Entry> identifierEntryCache = new HashMap<>(); 35 private Map<String, Entry> identifierEntryCache = new HashMap<>();
39 36
40 public SourceIndexMethodVisitor(ReferencedEntryPool entryPool, MethodDefEntry methodEntry, boolean isEnum) { 37 public SourceIndexMethodVisitor(ReferencedEntryPool entryPool, ClassDefEntry ownerEntry, MethodDefEntry methodEntry) {
41 super(entryPool); 38 super(entryPool);
42 this.entryPool = entryPool; 39 this.entryPool = entryPool;
43 this.entryFactory = new ProcyonEntryFactory(entryPool); 40 this.entryFactory = new ProcyonEntryFactory(entryPool);
41 this.ownerEntry = ownerEntry;
44 this.methodEntry = methodEntry; 42 this.methodEntry = methodEntry;
45 this.argumentPosition = isEnum ? 2 : 0;
46 this.localsPosition = 0;
47 } 43 }
48 44
49 @Override 45 @Override
@@ -112,14 +108,13 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor {
112 @Override 108 @Override
113 public Void visitParameterDeclaration(ParameterDeclaration node, SourceIndex index) { 109 public Void visitParameterDeclaration(ParameterDeclaration node, SourceIndex index) {
114 ParameterDefinition def = node.getUserData(Keys.PARAMETER_DEFINITION); 110 ParameterDefinition def = node.getUserData(Keys.PARAMETER_DEFINITION);
115 if (def.getMethod() instanceof MemberReference && def.getMethod() instanceof MethodReference) { 111
116 MethodEntry methodEntry = entryFactory.getMethodEntry((MethodReference) def.getMethod()); 112 int variableOffset = this.methodEntry.getVariableOffset(ownerEntry);
117 LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, argumentPosition++, node.getName()); 113 LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, def.getSlot() - variableOffset, node.getName());
118 Identifier identifier = node.getNameToken(); 114 Identifier identifier = node.getNameToken();
119 // cache the argument entry and the identifier 115 // cache the argument entry and the identifier
120 identifierEntryCache.put(identifier.getName(), localVariableEntry); 116 identifierEntryCache.put(identifier.getName(), localVariableEntry);
121 index.addDeclaration(identifier, localVariableEntry); 117 index.addDeclaration(identifier, localVariableEntry);
122 }
123 118
124 return recurse(node, index); 119 return recurse(node, index);
125 } 120 }
@@ -173,18 +168,6 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor {
173 } 168 }
174 169
175 @Override 170 @Override
176 public Void visitForEachStatement(ForEachStatement node, SourceIndex index) {
177 if (node.getVariableType() instanceof SimpleType) {
178 Identifier identifier = node.getVariableNameToken();
179 LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, argumentPosition + localsPosition++, identifier.getName());
180 identifierEntryCache.put(identifier.getName(), localVariableEntry);
181 addDeclarationToUnmatched(identifier.getName(), index);
182 index.addDeclaration(identifier, localVariableEntry);
183 }
184 return recurse(node, index);
185 }
186
187 @Override
188 public Void visitVariableDeclaration(VariableDeclarationStatement node, SourceIndex index) { 171 public Void visitVariableDeclaration(VariableDeclarationStatement node, SourceIndex index) {
189 AstNodeCollection<VariableInitializer> variables = node.getVariables(); 172 AstNodeCollection<VariableInitializer> variables = node.getVariables();
190 173
@@ -193,10 +176,17 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor {
193 VariableInitializer initializer = variables.firstOrNullObject(); 176 VariableInitializer initializer = variables.firstOrNullObject();
194 if (initializer != null && node.getType() instanceof SimpleType) { 177 if (initializer != null && node.getType() instanceof SimpleType) {
195 Identifier identifier = initializer.getNameToken(); 178 Identifier identifier = initializer.getNameToken();
196 LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, argumentPosition + localsPosition++, initializer.getName()); 179 Variable variable = initializer.getUserData(Keys.VARIABLE);
197 identifierEntryCache.put(identifier.getName(), localVariableEntry); 180 if (variable != null) {
198 addDeclarationToUnmatched(identifier.getName(), index); 181 VariableDefinition originalVariable = variable.getOriginalVariable();
199 index.addDeclaration(identifier, localVariableEntry); 182 if (originalVariable != null) {
183 int variableOffset = methodEntry.getVariableOffset(ownerEntry);
184 LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, originalVariable.getSlot() - variableOffset, initializer.getName());
185 identifierEntryCache.put(identifier.getName(), localVariableEntry);
186 addDeclarationToUnmatched(identifier.getName(), index);
187 index.addDeclaration(identifier, localVariableEntry);
188 }
189 }
200 } 190 }
201 } 191 }
202 return recurse(node, index); 192 return recurse(node, index);
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java
index 176f2838..e588d24b 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java
@@ -14,7 +14,9 @@ package cuchaz.enigma.analysis;
14import com.strobel.assembler.metadata.TypeDefinition; 14import com.strobel.assembler.metadata.TypeDefinition;
15import com.strobel.decompiler.languages.java.ast.*; 15import com.strobel.decompiler.languages.java.ast.*;
16import com.strobel.decompiler.patterns.Pattern; 16import com.strobel.decompiler.patterns.Pattern;
17import cuchaz.enigma.mapping.entry.ClassEntry; 17import cuchaz.enigma.bytecode.AccessFlags;
18import cuchaz.enigma.mapping.Signature;
19import cuchaz.enigma.mapping.entry.ClassDefEntry;
18import cuchaz.enigma.mapping.entry.ReferencedEntryPool; 20import cuchaz.enigma.mapping.entry.ReferencedEntryPool;
19 21
20public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void> { 22public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void> {
@@ -27,7 +29,7 @@ public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void> {
27 @Override 29 @Override
28 public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) { 30 public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) {
29 TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION); 31 TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION);
30 ClassEntry classEntry = new ClassEntry(def.getInternalName()); 32 ClassDefEntry classEntry = new ClassDefEntry(def.getInternalName(), Signature.createSignature(def.getSignature()), new AccessFlags(def.getModifiers()));
31 index.addDeclaration(node.getNameToken(), classEntry); 33 index.addDeclaration(node.getNameToken(), classEntry);
32 34
33 return node.acceptVisitor(new SourceIndexClassVisitor(entryPool, classEntry), index); 35 return node.acceptVisitor(new SourceIndexClassVisitor(entryPool, classEntry), index);
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
index 82a1263b..a6c7552a 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
@@ -86,12 +86,7 @@ public class TranslationMethodVisitor extends MethodVisitor {
86 86
87 String translatedSignature = translator.getTranslatedSignature(Signature.createTypedSignature(signature)).toString(); 87 String translatedSignature = translator.getTranslatedSignature(Signature.createTypedSignature(signature)).toString();
88 88
89 // If we're not static, "this" is bound to index 0 89 int offset = methodEntry.getVariableOffset(ownerEntry);
90 int offset = methodEntry.getAccess().isStatic() ? 0 : 1;
91 if (ownerEntry.getAccess().isEnum() && methodEntry.getName().startsWith("<")) {
92 // Enum constructors have an implicit "name" and "ordinal" parameter as well as "this"
93 offset = 3;
94 }
95 90
96 int offsetIndex = index - offset; 91 int offsetIndex = index - offset;
97 if (offsetIndex >= 0) { 92 if (offsetIndex >= 0) {
@@ -101,8 +96,8 @@ public class TranslationMethodVisitor extends MethodVisitor {
101 96
102 // TODO: Better name inference 97 // TODO: Better name inference
103 if (translatedName.equals(entry.getName())) { 98 if (translatedName.equals(entry.getName())) {
104 String prefix = offsetIndex < methodEntry.getDesc().getArgumentDescs().size() ? "a" : "v"; 99 boolean argument = offsetIndex < methodEntry.getDesc().getArgumentDescs().size();
105 translatedName = inferName(prefix, offsetIndex, translatedEntry.getDesc()); 100 translatedName = inferName(argument, offsetIndex, translatedEntry.getDesc());
106 } 101 }
107 102
108 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index); 103 super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index);
@@ -159,7 +154,7 @@ public class TranslationMethodVisitor extends MethodVisitor {
159 LocalVariableEntry translatedEntry = translator.getTranslatedVariable(entry); 154 LocalVariableEntry translatedEntry = translator.getTranslatedVariable(entry);
160 String translatedName = translatedEntry.getName(); 155 String translatedName = translatedEntry.getName();
161 if (translatedName.equals(entry.getName())) { 156 if (translatedName.equals(entry.getName())) {
162 super.visitParameter(inferName("a", index, arguments.get(index)), 0); 157 super.visitParameter(inferName(true, index, arguments.get(index)), 0);
163 } else { 158 } else {
164 super.visitParameter(translatedName, 0); 159 super.visitParameter(translatedName, 0);
165 } 160 }
@@ -168,10 +163,10 @@ public class TranslationMethodVisitor extends MethodVisitor {
168 super.visitEnd(); 163 super.visitEnd();
169 } 164 }
170 165
171 private String inferName(String prefix, int argumentIndex, TypeDescriptor desc) { 166 private String inferName(boolean argument, int argumentIndex, TypeDescriptor desc) {
172 String translatedName; 167 String translatedName;
173 int nameIndex = argumentIndex + 1; 168 int nameIndex = argumentIndex + 1;
174 StringBuilder nameBuilder = new StringBuilder(prefix); 169 StringBuilder nameBuilder = new StringBuilder(argument ? "a" : "v");
175 // Unfortunately each of these have different name getters, so they have different code paths 170 // Unfortunately each of these have different name getters, so they have different code paths
176 if (desc.isPrimitive()) { 171 if (desc.isPrimitive()) {
177 TypeDescriptor.Primitive argCls = desc.getPrimitive(); 172 TypeDescriptor.Primitive argCls = desc.getPrimitive();
@@ -184,7 +179,7 @@ public class TranslationMethodVisitor extends MethodVisitor {
184 typeName = typeName.substring(0, 1).toUpperCase(Locale.ROOT) + typeName.substring(1); 179 typeName = typeName.substring(0, 1).toUpperCase(Locale.ROOT) + typeName.substring(1);
185 nameBuilder.append(typeName); 180 nameBuilder.append(typeName);
186 } 181 }
187 if (methodEntry.getDesc().getArgumentDescs().size() > 1) { 182 if (!argument || methodEntry.getDesc().getArgumentDescs().size() > 1) {
188 nameBuilder.append(nameIndex); 183 nameBuilder.append(nameIndex);
189 } 184 }
190 translatedName = nameBuilder.toString(); 185 translatedName = nameBuilder.toString();
diff --git a/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java
index ec3af694..bb7c85eb 100644
--- a/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java
+++ b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java
@@ -37,6 +37,16 @@ public class MethodDefEntry extends MethodEntry {
37 return signature; 37 return signature;
38 } 38 }
39 39
40 public int getVariableOffset(ClassDefEntry ownerEntry) {
41 // Enum constructors have an implicit "name" and "ordinal" parameter as well as "this"
42 if (ownerEntry.getAccess().isEnum() && getName().startsWith("<")) {
43 return 3;
44 } else {
45 // If we're not static, "this" is bound to index 0
46 return getAccess().isStatic() ? 0 : 1;
47 }
48 }
49
40 @Override 50 @Override
41 public MethodDefEntry updateOwnership(ClassEntry classEntry) { 51 public MethodDefEntry updateOwnership(ClassEntry classEntry) {
42 return new MethodDefEntry(new ClassEntry(classEntry.getName()), name, descriptor, signature, access); 52 return new MethodDefEntry(new ClassEntry(classEntry.getName()), name, descriptor, signature, access);