summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/mapping/Translator.java
diff options
context:
space:
mode:
authorGravatar jeff2015-02-08 21:29:25 -0500
committerGravatar jeff2015-02-08 21:29:25 -0500
commited9b5cdfc648e86fd463bfa8d86b94c41671e14c (patch)
tree2619bbc7e04dfa3b82f8dfd3b1d31f529766cd4b /src/cuchaz/enigma/mapping/Translator.java
downloadenigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.tar.gz
enigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.tar.xz
enigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.zip
switch all classes to new signature/type system
Diffstat (limited to 'src/cuchaz/enigma/mapping/Translator.java')
-rw-r--r--src/cuchaz/enigma/mapping/Translator.java239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java
new file mode 100644
index 0000000..5eba18c
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/Translator.java
@@ -0,0 +1,239 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.mapping;
12
13import java.util.Map;
14
15import com.google.common.collect.Maps;
16
17import cuchaz.enigma.analysis.TranslationIndex;
18
19public class Translator {
20
21 private TranslationDirection m_direction;
22 private Map<String,ClassMapping> m_classes;
23 private TranslationIndex m_index;
24
25 public Translator() {
26 m_direction = null;
27 m_classes = Maps.newHashMap();
28 }
29
30 public Translator(TranslationDirection direction, Map<String,ClassMapping> classes, TranslationIndex index) {
31 m_direction = direction;
32 m_classes = classes;
33 m_index = index;
34 }
35
36 @SuppressWarnings("unchecked")
37 public <T extends Entry> T translateEntry(T entry) {
38 if (entry instanceof ClassEntry) {
39 return (T)translateEntry((ClassEntry)entry);
40 } else if (entry instanceof FieldEntry) {
41 return (T)translateEntry((FieldEntry)entry);
42 } else if (entry instanceof MethodEntry) {
43 return (T)translateEntry((MethodEntry)entry);
44 } else if (entry instanceof ConstructorEntry) {
45 return (T)translateEntry((ConstructorEntry)entry);
46 } else if (entry instanceof ArgumentEntry) {
47 return (T)translateEntry((ArgumentEntry)entry);
48 } else {
49 throw new Error("Unknown entry type: " + entry.getClass().getName());
50 }
51 }
52
53 public String translateClass(String className) {
54 return translate(new ClassEntry(className));
55 }
56
57 public String translate(ClassEntry in) {
58 ClassMapping classMapping = m_classes.get(in.getOuterClassName());
59 if (classMapping != null) {
60 if (in.isInnerClass()) {
61 // translate the inner class
62 String translatedInnerClassName = m_direction.choose(
63 classMapping.getDeobfInnerClassName(in.getInnerClassName()),
64 classMapping.getObfInnerClassName(in.getInnerClassName())
65 );
66 if (translatedInnerClassName != null) {
67 // try to translate the outer name
68 String translatedOuterClassName = m_direction.choose(classMapping.getDeobfName(), classMapping.getObfName());
69 if (translatedOuterClassName != null) {
70 return translatedOuterClassName + "$" + translatedInnerClassName;
71 } else {
72 return in.getOuterClassName() + "$" + translatedInnerClassName;
73 }
74 }
75 } else {
76 // just return outer
77 return m_direction.choose(classMapping.getDeobfName(), classMapping.getObfName());
78 }
79 }
80 return null;
81 }
82
83 public ClassEntry translateEntry(ClassEntry in) {
84
85 // can we translate the inner class?
86 String name = translate(in);
87 if (name != null) {
88 return new ClassEntry(name);
89 }
90
91 if (in.isInnerClass()) {
92
93 // guess not. just translate the outer class name then
94 String outerClassName = translate(in.getOuterClassEntry());
95 if (outerClassName != null) {
96 return new ClassEntry(outerClassName + "$" + in.getInnerClassName());
97 }
98 }
99
100 return in;
101 }
102
103 public String translate(FieldEntry in) {
104
105 // resolve the class entry
106 ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in);
107 if (resolvedClassEntry != null) {
108
109 // look for the class
110 ClassMapping classMapping = findClassMapping(resolvedClassEntry);
111 if (classMapping != null) {
112
113 // look for the field
114 String translatedName = m_direction.choose(
115 classMapping.getDeobfFieldName(in.getName()),
116 classMapping.getObfFieldName(in.getName())
117 );
118 if (translatedName != null) {
119 return translatedName;
120 }
121 }
122 }
123 return null;
124 }
125
126 public FieldEntry translateEntry(FieldEntry in) {
127 String name = translate(in);
128 if (name == null) {
129 name = in.getName();
130 }
131 return new FieldEntry(translateEntry(in.getClassEntry()), name);
132 }
133
134 public String translate(MethodEntry in) {
135
136 // resolve the class entry
137 ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in);
138 if (resolvedClassEntry != null) {
139
140 // look for class
141 ClassMapping classMapping = findClassMapping(resolvedClassEntry);
142 if (classMapping != null) {
143
144 // look for the method
145 MethodMapping methodMapping = m_direction.choose(
146 classMapping.getMethodByObf(in.getName(), in.getSignature()),
147 classMapping.getMethodByDeobf(in.getName(), translateSignature(in.getSignature()))
148 );
149 if (methodMapping != null) {
150 return m_direction.choose(methodMapping.getDeobfName(), methodMapping.getObfName());
151 }
152 }
153 }
154 return null;
155 }
156
157 public MethodEntry translateEntry(MethodEntry in) {
158 String name = translate(in);
159 if (name == null) {
160 name = in.getName();
161 }
162 return new MethodEntry(translateEntry(in.getClassEntry()), name, translateSignature(in.getSignature()));
163 }
164
165 public ConstructorEntry translateEntry(ConstructorEntry in) {
166 if (in.isStatic()) {
167 return new ConstructorEntry(translateEntry(in.getClassEntry()));
168 } else {
169 return new ConstructorEntry(translateEntry(in.getClassEntry()), translateSignature(in.getSignature()));
170 }
171 }
172
173 public BehaviorEntry translateEntry(BehaviorEntry in) {
174 if (in instanceof MethodEntry) {
175 return translateEntry((MethodEntry)in);
176 } else if (in instanceof ConstructorEntry) {
177 return translateEntry((ConstructorEntry)in);
178 }
179 throw new Error("Wrong entry type!");
180 }
181
182 public String translate(ArgumentEntry in) {
183
184 // look for the class
185 ClassMapping classMapping = findClassMapping(in.getClassEntry());
186 if (classMapping != null) {
187
188 // look for the method
189 MethodMapping methodMapping = m_direction.choose(
190 classMapping.getMethodByObf(in.getMethodName(), in.getMethodSignature()),
191 classMapping.getMethodByDeobf(in.getMethodName(), translateSignature(in.getMethodSignature()))
192 );
193 if (methodMapping != null) {
194 return m_direction.choose(
195 methodMapping.getDeobfArgumentName(in.getIndex()),
196 methodMapping.getObfArgumentName(in.getIndex())
197 );
198 }
199 }
200 return null;
201 }
202
203 public ArgumentEntry translateEntry(ArgumentEntry in) {
204 String name = translate(in);
205 if (name == null) {
206 name = in.getName();
207 }
208 return new ArgumentEntry(translateEntry(in.getBehaviorEntry()), in.getIndex(), name);
209 }
210
211 public Type translateType(Type type) {
212 return new Type(type, new ClassNameReplacer() {
213 @Override
214 public String replace(String className) {
215 return translateClass(className);
216 }
217 });
218 }
219
220 public Signature translateSignature(Signature signature) {
221 return new Signature(signature, new ClassNameReplacer() {
222 @Override
223 public String replace(String className) {
224 return translateClass(className);
225 }
226 });
227 }
228
229 private ClassMapping findClassMapping(ClassEntry classEntry) {
230 ClassMapping classMapping = m_classes.get(classEntry.getOuterClassName());
231 if (classMapping != null && classEntry.isInnerClass()) {
232 classMapping = m_direction.choose(
233 classMapping.getInnerClassByObf(classEntry.getInnerClassName()),
234 classMapping.getInnerClassByDeobfThenObf(classEntry.getInnerClassName())
235 );
236 }
237 return classMapping;
238 }
239}