summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/TranslatingTypeLoader.java2
-rw-r--r--src/cuchaz/enigma/mapping/BehaviorSignature.java96
-rw-r--r--src/cuchaz/enigma/mapping/Mappings.java23
-rw-r--r--src/cuchaz/enigma/mapping/Type.java179
4 files changed, 276 insertions, 24 deletions
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java
index 9287999b..cfa03a1a 100644
--- a/src/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/cuchaz/enigma/TranslatingTypeLoader.java
@@ -167,7 +167,7 @@ public class TranslatingTypeLoader implements ITypeLoader {
167 assertClassName(c, deobfClassEntry); 167 assertClassName(c, deobfClassEntry);
168 168
169 // DEBUG 169 // DEBUG
170 Util.writeClass( c ); 170 //Util.writeClass( c );
171 171
172 // we have a transformed class! 172 // we have a transformed class!
173 return c.toBytecode(); 173 return c.toBytecode();
diff --git a/src/cuchaz/enigma/mapping/BehaviorSignature.java b/src/cuchaz/enigma/mapping/BehaviorSignature.java
new file mode 100644
index 00000000..a6371f85
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/BehaviorSignature.java
@@ -0,0 +1,96 @@
1package cuchaz.enigma.mapping;
2
3import java.util.List;
4
5import com.beust.jcommander.internal.Lists;
6
7public class BehaviorSignature {
8
9 public static interface ClassReplacer {
10 ClassEntry replace(ClassEntry entry);
11 }
12
13 private List<Type> m_argumentTypes;
14 private Type m_returnType;
15
16 public BehaviorSignature(String signature) {
17 m_argumentTypes = Lists.newArrayList();
18 int i=0;
19 while (i<signature.length()) {
20 char c = signature.charAt(i);
21 if (c == '(') {
22 assert(m_argumentTypes.isEmpty());
23 assert(m_returnType == null);
24 i++;
25 } else if (c == ')') {
26 i++;
27 break;
28 } else {
29 String type = Type.parseFirst(signature.substring(i));
30 m_argumentTypes.add(new Type(type));
31 i += type.length();
32 }
33 }
34 m_returnType = new Type(Type.parseFirst(signature.substring(i)));
35 }
36
37 public BehaviorSignature(BehaviorSignature other, ClassReplacer replacer) {
38 m_argumentTypes = Lists.newArrayList(other.m_argumentTypes);
39 for (int i=0; i<m_argumentTypes.size(); i++) {
40 Type type = m_argumentTypes.get(i);
41 if (type.isClass()) {
42 ClassEntry newClassEntry = replacer.replace(type.getClassEntry());
43 if (newClassEntry != null) {
44 m_argumentTypes.set(i, new Type(newClassEntry));
45 }
46 }
47 }
48 m_returnType = other.m_returnType;
49 if (other.m_returnType.isClass()) {
50 ClassEntry newClassEntry = replacer.replace(m_returnType.getClassEntry());
51 if (newClassEntry != null) {
52 m_returnType = new Type(newClassEntry);
53 }
54 }
55 }
56
57 public List<Type> getArgumentTypes() {
58 return m_argumentTypes;
59 }
60
61 public Type getReturnType() {
62 return m_returnType;
63 }
64
65 @Override
66 public String toString() {
67 StringBuilder buf = new StringBuilder();
68 buf.append("(");
69 for (int i=0; i<m_argumentTypes.size(); i++) {
70 if (i > 0) {
71 buf.append(",");
72 }
73 buf.append(m_argumentTypes.get(i).toString());
74 }
75 buf.append(")");
76 buf.append(m_returnType.toString());
77 return buf.toString();
78 }
79
80 public Iterable<Type> types() {
81 List<Type> types = Lists.newArrayList();
82 types.addAll(m_argumentTypes);
83 types.add(m_returnType);
84 return types;
85 }
86
87 public Iterable<ClassEntry> classes() {
88 List<ClassEntry> out = Lists.newArrayList();
89 for (Type type : types()) {
90 if (type.isClass()) {
91 out.add(type.getClassEntry());
92 }
93 }
94 return out;
95 }
96}
diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java
index cc560a87..92134edf 100644
--- a/src/cuchaz/enigma/mapping/Mappings.java
+++ b/src/cuchaz/enigma/mapping/Mappings.java
@@ -10,20 +10,15 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
12 12
13import java.io.IOException;
14import java.io.InputStream;
15import java.io.ObjectInputStream;
16import java.io.Serializable; 13import java.io.Serializable;
17import java.util.ArrayList; 14import java.util.ArrayList;
18import java.util.Collection; 15import java.util.Collection;
19import java.util.Map; 16import java.util.Map;
20import java.util.Set; 17import java.util.Set;
21import java.util.zip.GZIPInputStream;
22 18
23import com.google.common.collect.Maps; 19import com.google.common.collect.Maps;
24import com.google.common.collect.Sets; 20import com.google.common.collect.Sets;
25 21
26import cuchaz.enigma.Util;
27import cuchaz.enigma.analysis.TranslationIndex; 22import cuchaz.enigma.analysis.TranslationIndex;
28import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; 23import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater;
29 24
@@ -50,16 +45,6 @@ public class Mappings implements Serializable {
50 } 45 }
51 } 46 }
52 47
53 public static Mappings newFromResource(String resource) throws IOException {
54 InputStream in = null;
55 try {
56 in = Mappings.class.getResourceAsStream(resource);
57 return newFromStream(in);
58 } finally {
59 Util.closeQuietly(in);
60 }
61 }
62
63 public Collection<ClassMapping> classes() { 48 public Collection<ClassMapping> classes() {
64 assert (m_classesByObf.size() >= m_classesByDeobf.size()); 49 assert (m_classesByObf.size() >= m_classesByDeobf.size());
65 return m_classesByObf.values(); 50 return m_classesByObf.values();
@@ -134,14 +119,6 @@ public class Mappings implements Serializable {
134 } 119 }
135 } 120 }
136 121
137 public static Mappings newFromStream(InputStream in) throws IOException {
138 try {
139 return (Mappings)new ObjectInputStream(new GZIPInputStream(in)).readObject();
140 } catch (ClassNotFoundException ex) {
141 throw new Error(ex);
142 }
143 }
144
145 @Override 122 @Override
146 public String toString() { 123 public String toString() {
147 StringBuilder buf = new StringBuilder(); 124 StringBuilder buf = new StringBuilder();
diff --git a/src/cuchaz/enigma/mapping/Type.java b/src/cuchaz/enigma/mapping/Type.java
new file mode 100644
index 00000000..2273e21b
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/Type.java
@@ -0,0 +1,179 @@
1package cuchaz.enigma.mapping;
2
3import java.util.Map;
4
5import com.google.common.collect.Maps;
6
7public class Type {
8
9 public enum Primitive {
10 Byte('B'),
11 Character('C'),
12 Short('S'),
13 Integer('I'),
14 Long('J'),
15 Float('F'),
16 Double('D'),
17 Boolean('Z');
18
19 private static final Map<Character,Primitive> m_lookup;
20
21 static {
22 m_lookup = Maps.newTreeMap();
23 for (Primitive val : values()) {
24 m_lookup.put(val.getCode(), val);
25 }
26 }
27
28 public static Primitive get(char code) {
29 return m_lookup.get(code);
30 }
31
32 private char m_code;
33
34 private Primitive(char code) {
35 m_code = code;
36 }
37
38 public char getCode() {
39 return m_code;
40 }
41 }
42
43 public static String parseFirst(String in) {
44
45 // read one type from the input
46
47 char c = in.charAt(0);
48
49 // first check for void
50 if (c == 'V') {
51 return "V";
52 }
53
54 // then check for primitives
55 Primitive primitive = Primitive.get(c);
56 if (primitive != null) {
57 return in.substring(0, 1);
58 }
59
60 // then check for classes
61 if (c == 'L') {
62 return readClass(in);
63 }
64
65 // then check for arrays
66 int dim = countArrayDimension(in);
67 if (dim > 0) {
68 String arrayType = Type.parseFirst(in.substring(dim));
69 return in.substring(0, dim + arrayType.length());
70 }
71
72 throw new IllegalArgumentException("don't know how to parse: " + in);
73 }
74
75 private String m_name;
76
77 public Type(String name) {
78 m_name = name;
79 }
80
81 public Type(ClassEntry classEntry) {
82 m_name = "L" + classEntry.getClassName() + ";";
83 }
84
85 @Override
86 public String toString() {
87 return m_name;
88 }
89
90 public boolean isVoid() {
91 return m_name.length() == 1 && m_name.charAt(0) == 'V';
92 }
93
94 public boolean isPrimitive() {
95 return m_name.length() == 1 && Primitive.get(m_name.charAt(0)) != null;
96 }
97
98 public Primitive getPrimitive() {
99 if (!isPrimitive()) {
100 throw new IllegalStateException("not a primitive");
101 }
102 return Primitive.get(m_name.charAt(0));
103 }
104
105 public boolean isClass() {
106 return m_name.charAt(0) == 'L' && m_name.charAt(m_name.length() - 1) == ';';
107 }
108
109 public ClassEntry getClassEntry() {
110 if (!isClass()) {
111 throw new IllegalStateException("not a class");
112 }
113 String name = m_name.substring(1, m_name.length() - 1);
114
115 int pos = name.indexOf('<');
116 if (pos >= 0) {
117 // remove the parameters from the class name
118 name = name.substring(0, pos);
119 }
120
121 return new ClassEntry(name);
122 }
123
124 public boolean isArray() {
125 return m_name.charAt(0) == '[';
126 }
127
128 public int getArrayDimension() {
129 if (!isArray()) {
130 throw new IllegalStateException("not an array");
131 }
132 return countArrayDimension(m_name);
133 }
134
135 public Type getArrayType() {
136 if (!isArray()) {
137 throw new IllegalStateException("not an array");
138 }
139 return new Type(m_name.substring(getArrayDimension(), m_name.length()));
140 }
141
142 @Override
143 public boolean equals(Object other) {
144 if (other instanceof Type) {
145 return equals((Type)other);
146 }
147 return false;
148 }
149
150 public boolean equals(Type other) {
151 return m_name.equals(other.m_name);
152 }
153
154 private static int countArrayDimension(String in) {
155 int i=0;
156 for(; i < in.length() && in.charAt(i) == '['; i++);
157 return i;
158 }
159
160 private static String readClass(String in) {
161 // read all the characters in the buffer until we hit a ';'
162 // remember to treat parameters correctly
163 StringBuilder buf = new StringBuilder();
164 int depth = 0;
165 for (int i=0; i<in.length(); i++) {
166 char c = in.charAt(i);
167 buf.append(c);
168
169 if (c == '<') {
170 depth++;
171 } else if (c == '>') {
172 depth--;
173 } else if (depth == 0 && c == ';') {
174 return buf.toString();
175 }
176 }
177 return null;
178 }
179}