summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis
diff options
context:
space:
mode:
authorGravatar Thog2016-10-19 17:44:04 +0200
committerGravatar Thog2016-10-19 17:47:26 +0200
commit72115a6e4c83422b7359a9ae4d60badc244b55ff (patch)
tree6882be6d90bc1ebd5eb849f1a069b9eb5c07c247 /src/main/java/cuchaz/enigma/analysis
parentLocalVariableRenamer: Support correctly Nested Class constructors (Fix #49) (diff)
downloadenigma-fork-72115a6e4c83422b7359a9ae4d60badc244b55ff.tar.gz
enigma-fork-72115a6e4c83422b7359a9ae4d60badc244b55ff.tar.xz
enigma-fork-72115a6e4c83422b7359a9ae4d60badc244b55ff.zip
Starting implementing local variables (#33)
TODO: - Store format (need to be defined) - Implement some translate operations This commit also fix some cases where argument tokens are not selected
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/JarIndex.java3
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java78
-rw-r--r--src/main/java/cuchaz/enigma/analysis/TranslationIndex.java2
3 files changed, 78 insertions, 5 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
index 619d862..f955a40 100644
--- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
@@ -791,6 +791,9 @@ public class JarIndex {
791 return containsObfBehavior((BehaviorEntry) obfEntry); 791 return containsObfBehavior((BehaviorEntry) obfEntry);
792 } else if (obfEntry instanceof ArgumentEntry) { 792 } else if (obfEntry instanceof ArgumentEntry) {
793 return containsObfArgument((ArgumentEntry) obfEntry); 793 return containsObfArgument((ArgumentEntry) obfEntry);
794 } else if (obfEntry instanceof LocalVariableEntry) {
795 // TODO: Implement it
796 return false;
794 } else { 797 } else {
795 throw new Error("Entry type not supported: " + obfEntry.getClass().getName()); 798 throw new Error("Entry type not supported: " + obfEntry.getClass().getName());
796 } 799 }
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
index c328f5f..e690abd 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
@@ -10,6 +10,9 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import com.google.common.collect.HashMultimap;
14import com.google.common.collect.Multimap;
15import com.google.common.collect.Multimaps;
13import com.strobel.assembler.metadata.MemberReference; 16import com.strobel.assembler.metadata.MemberReference;
14import com.strobel.assembler.metadata.MethodReference; 17import com.strobel.assembler.metadata.MethodReference;
15import com.strobel.assembler.metadata.ParameterDefinition; 18import com.strobel.assembler.metadata.ParameterDefinition;
@@ -17,6 +20,7 @@ import com.strobel.assembler.metadata.TypeReference;
17import com.strobel.decompiler.languages.TextLocation; 20import com.strobel.decompiler.languages.TextLocation;
18import com.strobel.decompiler.languages.java.ast.*; 21import com.strobel.decompiler.languages.java.ast.*;
19import cuchaz.enigma.mapping.*; 22import cuchaz.enigma.mapping.*;
23import javassist.bytecode.Descriptor;
20 24
21import java.util.HashMap; 25import java.util.HashMap;
22import java.util.Map; 26import java.util.Map;
@@ -27,11 +31,14 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
27 31
28 // TODO: Really fix Procyon index problem with inner classes 32 // TODO: Really fix Procyon index problem with inner classes
29 private int argumentPosition; 33 private int argumentPosition;
30 private Map<String, Entry> argumentCache = new HashMap<>(); 34 private int localsPosition;
35 private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create();
36 private Map<String, Entry> identifierEntryCache = new HashMap<>();
31 37
32 public SourceIndexBehaviorVisitor(BehaviorEntry behaviorEntry) { 38 public SourceIndexBehaviorVisitor(BehaviorEntry behaviorEntry) {
33 this.behaviorEntry = behaviorEntry; 39 this.behaviorEntry = behaviorEntry;
34 this.argumentPosition = 0; 40 this.argumentPosition = 0;
41 this.localsPosition = 0;
35 } 42 }
36 43
37 @Override 44 @Override
@@ -66,6 +73,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
66 } 73 }
67 } 74 }
68 75
76 // Check for identifier
77 node.getArguments().stream().filter(expression -> expression instanceof IdentifierExpression)
78 .forEach(expression -> this.checkIdentifier((IdentifierExpression) expression, index));
69 return recurse(node, index); 79 return recurse(node, index);
70 } 80 }
71 81
@@ -106,7 +116,7 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
106 argumentPosition++, node.getName()); 116 argumentPosition++, node.getName());
107 Identifier identifier = node.getNameToken(); 117 Identifier identifier = node.getNameToken();
108 // cache the argument entry and the identifier 118 // cache the argument entry and the identifier
109 argumentCache.put(identifier.getName(), argumentEntry); 119 identifierEntryCache.put(identifier.getName(), argumentEntry);
110 index.addDeclaration(identifier, argumentEntry); 120 index.addDeclaration(identifier, argumentEntry);
111 } 121 }
112 122
@@ -121,12 +131,31 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
121 FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new Type(ref.getErasedSignature())); 131 FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new Type(ref.getErasedSignature()));
122 index.addReference(node.getIdentifierToken(), fieldEntry, this.behaviorEntry); 132 index.addReference(node.getIdentifierToken(), fieldEntry, this.behaviorEntry);
123 } 133 }
124 else if (argumentCache.containsKey(node.getIdentifier())) // If it's in the argument cache, create a token! 134 else
125 index.addDeclaration(node.getIdentifierToken(), argumentCache.get(node.getIdentifier())); 135 this.checkIdentifier(node, index);
126
127 return recurse(node, index); 136 return recurse(node, index);
128 } 137 }
129 138
139 private void checkIdentifier(IdentifierExpression node, SourceIndex index)
140 {
141 if (identifierEntryCache.containsKey(node.getIdentifier())) // If it's in the argument cache, create a token!
142 index.addDeclaration(node.getIdentifierToken(), identifierEntryCache.get(node.getIdentifier()));
143 else
144 unmatchedIdentifier.put(node.getIdentifier(), node.getIdentifierToken()); // Not matched actually, put it!
145 }
146
147 private void addDeclarationToUnmatched(String key, SourceIndex index)
148 {
149 Entry entry = identifierEntryCache.get(key);
150
151 // This cannot happened in theory
152 if (entry == null)
153 return;
154 for (Identifier identifier : unmatchedIdentifier.get(key))
155 index.addDeclaration(identifier, entry);
156 unmatchedIdentifier.removeAll(key);
157 }
158
130 @Override 159 @Override
131 public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) { 160 public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) {
132 MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); 161 MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE);
@@ -141,4 +170,43 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
141 170
142 return recurse(node, index); 171 return recurse(node, index);
143 } 172 }
173
174 @Override
175 public Void visitForEachStatement(ForEachStatement node, SourceIndex index) {
176 if (node.getVariableType() instanceof SimpleType)
177 {
178 SimpleType type = (SimpleType) node.getVariableType();
179 TypeReference typeReference = type.getUserData(Keys.TYPE_REFERENCE);
180 Identifier identifier = node.getVariableNameToken();
181 String signature = Descriptor.of(typeReference.getErasedDescription());
182 LocalVariableEntry localVariableEntry = new LocalVariableEntry(behaviorEntry, localsPosition++, identifier.getName(), new Type(signature));
183 identifierEntryCache.put(identifier.getName(), localVariableEntry);
184 addDeclarationToUnmatched(identifier.getName(), index);
185 index.addDeclaration(identifier, localVariableEntry);
186 }
187 return recurse(node, index);
188 }
189
190 @Override
191 public Void visitVariableDeclaration(VariableDeclarationStatement node, SourceIndex index) {
192 AstNodeCollection<VariableInitializer> variables = node.getVariables();
193
194 // Single assignation
195 if (variables.size() == 1)
196 {
197 VariableInitializer initializer = variables.firstOrNullObject();
198 if (initializer != null && node.getType() instanceof SimpleType)
199 {
200 SimpleType type = (SimpleType) node.getType();
201 TypeReference typeReference = type.getUserData(Keys.TYPE_REFERENCE);
202 String signature = Descriptor.of(typeReference.getErasedDescription());
203 Identifier identifier = initializer.getNameToken();
204 LocalVariableEntry localVariableEntry = new LocalVariableEntry(behaviorEntry, localsPosition++, initializer.getName(), new Type(signature));
205 identifierEntryCache.put(identifier.getName(), localVariableEntry);
206 addDeclarationToUnmatched(identifier.getName(), index);
207 index.addDeclaration(identifier, localVariableEntry);
208 }
209 }
210 return recurse(node, index);
211 }
144} 212}
diff --git a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
index 25edaef..d51131f 100644
--- a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
@@ -181,6 +181,8 @@ public class TranslationIndex {
181 return behaviorExists((BehaviorEntry) entry); 181 return behaviorExists((BehaviorEntry) entry);
182 } else if (entry instanceof ArgumentEntry) { 182 } else if (entry instanceof ArgumentEntry) {
183 return behaviorExists(((ArgumentEntry) entry).getBehaviorEntry()); 183 return behaviorExists(((ArgumentEntry) entry).getBehaviorEntry());
184 } else if (entry instanceof LocalVariableEntry) {
185 return behaviorExists(((LocalVariableEntry) entry).getBehaviorEntry());
184 } 186 }
185 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass()); 187 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass());
186 } 188 }