summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz
diff options
context:
space:
mode:
authorGravatar gegy10002018-05-19 18:02:29 +0200
committerGravatar gegy10002018-05-19 18:02:29 +0200
commit8e7453727ff059c8f1db7f89f6793d22cbd5e6fc (patch)
treed15e55f61705fd9cd0a1d54816c09d0b6cc0ec36 /src/main/java/cuchaz
parentPackage updates (diff)
downloadenigma-8e7453727ff059c8f1db7f89f6793d22cbd5e6fc.tar.gz
enigma-8e7453727ff059c8f1db7f89f6793d22cbd5e6fc.tar.xz
enigma-8e7453727ff059c8f1db7f89f6793d22cbd5e6fc.zip
Annotation + inner class translation
Diffstat (limited to 'src/main/java/cuchaz')
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/AccessFlags.java3
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java45
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java31
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationFieldVisitor.java33
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java16
-rw-r--r--src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Mappings.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MethodDescriptor.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Translator.java13
-rw-r--r--src/main/java/cuchaz/enigma/mapping/TypeDescriptor.java9
10 files changed, 133 insertions, 23 deletions
diff --git a/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java b/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java
index 0999abf0..152f4629 100644
--- a/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java
+++ b/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java
@@ -5,6 +5,9 @@ import org.objectweb.asm.Opcodes;
5import java.lang.reflect.Modifier; 5import java.lang.reflect.Modifier;
6 6
7public class AccessFlags { 7public class AccessFlags {
8 public static final AccessFlags PUBLIC = new AccessFlags(Modifier.PUBLIC);
9 public static final AccessFlags PUBLIC_STATIC_FINAL = new AccessFlags(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
10
8 private static final int SYNTHETIC_FLAG = 0x00001000; 11 private static final int SYNTHETIC_FLAG = 0x00001000;
9 private static final int BRIDGED_FLAG = 0x00000040; 12 private static final int BRIDGED_FLAG = 0x00000040;
10 13
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java
new file mode 100644
index 00000000..177691b4
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java
@@ -0,0 +1,45 @@
1package cuchaz.enigma.bytecode.translators;
2
3import cuchaz.enigma.bytecode.AccessFlags;
4import cuchaz.enigma.mapping.Translator;
5import cuchaz.enigma.mapping.TypeDescriptor;
6import cuchaz.enigma.mapping.entry.ClassEntry;
7import cuchaz.enigma.mapping.entry.FieldDefEntry;
8import org.objectweb.asm.AnnotationVisitor;
9import org.objectweb.asm.Type;
10
11public class TranslationAnnotationVisitor extends AnnotationVisitor {
12 private final Translator translator;
13 private final ClassEntry annotationEntry;
14
15 public TranslationAnnotationVisitor(Translator translator, ClassEntry annotationEntry, int api, AnnotationVisitor av) {
16 super(api, av);
17 this.translator = translator;
18 this.annotationEntry = annotationEntry;
19 }
20
21 @Override
22 public void visit(String name, Object value) {
23 if (value instanceof Type) {
24 Type type = (Type) value;
25 super.visit(name, translator.getTranslatedType(type));
26 } else {
27 super.visit(name, value);
28 }
29 }
30
31 @Override
32 public AnnotationVisitor visitAnnotation(String name, String desc) {
33 TypeDescriptor type = new TypeDescriptor(desc);
34 FieldDefEntry annotationField = translator.getTranslatedFieldDef(new FieldDefEntry(annotationEntry, name, type, AccessFlags.PUBLIC));
35 return super.visitAnnotation(annotationField.getName(), annotationField.getDesc().toString());
36 }
37
38 @Override
39 public void visitEnum(String name, String desc, String value) {
40 TypeDescriptor type = new TypeDescriptor(desc);
41 FieldDefEntry annotationField = translator.getTranslatedFieldDef(new FieldDefEntry(annotationEntry, name, type, AccessFlags.PUBLIC));
42 FieldDefEntry enumField = translator.getTranslatedFieldDef(new FieldDefEntry(type.getTypeEntry(), value, type, AccessFlags.PUBLIC_STATIC_FINAL));
43 super.visitEnum(annotationField.getName(), annotationField.getDesc().toString(), enumField.getName());
44 }
45}
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
index 3f61c291..5fdfaf11 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java
@@ -54,7 +54,8 @@ public class TranslationClassVisitor extends ClassVisitor {
54 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { 54 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
55 FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access)); 55 FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access));
56 FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry); 56 FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry);
57 return super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, value); 57 FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, value);
58 return new TranslationFieldVisitor(translator, translatedEntry, api, fv);
58 } 59 }
59 60
60 @Override 61 @Override
@@ -64,32 +65,38 @@ public class TranslationClassVisitor extends ClassVisitor {
64 if (jarIndex.getBridgedMethod(entry) != null) { 65 if (jarIndex.getBridgedMethod(entry) != null) {
65 translatedEntry.getAccess().setBridged(); 66 translatedEntry.getAccess().setBridged();
66 } 67 }
67 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), name, desc, signature, exceptions); 68 String[] translatedExceptions = new String[exceptions.length];
69 for (int i = 0; i < exceptions.length; i++) {
70 translatedExceptions[i] = translator.getTranslatedClass(entryPool.getClass(exceptions[i])).getName();
71 }
72 MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, translatedExceptions);
68 return new TranslationMethodVisitor(translator, translatedEntry, api, mv); 73 return new TranslationMethodVisitor(translator, translatedEntry, api, mv);
69 } 74 }
70 75
71 @Override 76 @Override
72 public void visitOuterClass(String owner, String name, String desc) { 77 public void visitOuterClass(String owner, String name, String desc) {
78 ClassEntry ownerEntry = translator.getTranslatedClass(entryPool.getClass(owner));
79 String translatedDesc = desc != null ? translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString() : desc;
73 if (name != null) { 80 if (name != null) {
74 ClassEntry ownerEntry = translator.getTranslatedClass(entryPool.getClass(owner));
75 ClassEntry entry = translator.getTranslatedClass(entryPool.getClass(name)); 81 ClassEntry entry = translator.getTranslatedClass(entryPool.getClass(name));
76 String translatedDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString();
77 super.visitOuterClass(ownerEntry.getName(), entry.getName(), translatedDesc); 82 super.visitOuterClass(ownerEntry.getName(), entry.getName(), translatedDesc);
78 } else { 83 } else {
79 super.visitOuterClass(owner, name, desc); 84 super.visitOuterClass(ownerEntry.getName(), name, translatedDesc);
80 } 85 }
81 } 86 }
82 87
83 @Override 88 @Override
84 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 89 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
85 // TODO: Implement 90 TypeDescriptor translatedDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
86 return super.visitAnnotation(desc, visible); 91 AnnotationVisitor av = super.visitAnnotation(translatedDesc.toString(), visible);
92 return new TranslationAnnotationVisitor(translator, translatedDesc.getTypeEntry(), api, av);
87 } 93 }
88 94
89 @Override 95 @Override
90 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { 96 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
91 // TODO: Implement 97 TypeDescriptor translatedDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
92 return super.visitTypeAnnotation(typeRef, typePath, desc, visible); 98 AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath, translatedDesc.toString(), visible);
99 return new TranslationAnnotationVisitor(translator, translatedDesc.getTypeEntry(), api, av);
93 } 100 }
94 101
95 @Override 102 @Override
@@ -101,7 +108,11 @@ public class TranslationClassVisitor extends ClassVisitor {
101 ClassEntry innerEntry = translator.getTranslatedClass(entryPool.getClass(innerName)); 108 ClassEntry innerEntry = translator.getTranslatedClass(entryPool.getClass(innerName));
102 super.visitInnerClass(translatedEntry.getName(), outerEntry.getName(), innerEntry.getName(), translatedEntry.getAccess().getFlags()); 109 super.visitInnerClass(translatedEntry.getName(), outerEntry.getName(), innerEntry.getName(), translatedEntry.getAccess().getFlags());
103 } else { 110 } else {
104 super.visitInnerClass(name, outerName, innerName, access); 111 int separatorIndex = name.lastIndexOf("$");
112 String parentName = name.substring(0, separatorIndex);
113 String childName = name.substring(separatorIndex + 1);
114 ClassEntry outerEntry = translator.getTranslatedClass(entryPool.getClass(parentName));
115 super.visitInnerClass(outerEntry.getName() + "$" + childName, outerName, innerName, access);
105 } 116 }
106 } 117 }
107} 118}
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationFieldVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationFieldVisitor.java
new file mode 100644
index 00000000..e4695fb6
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationFieldVisitor.java
@@ -0,0 +1,33 @@
1package cuchaz.enigma.bytecode.translators;
2
3import cuchaz.enigma.mapping.Translator;
4import cuchaz.enigma.mapping.TypeDescriptor;
5import cuchaz.enigma.mapping.entry.FieldDefEntry;
6import org.objectweb.asm.AnnotationVisitor;
7import org.objectweb.asm.FieldVisitor;
8import org.objectweb.asm.TypePath;
9
10public class TranslationFieldVisitor extends FieldVisitor {
11 private final FieldDefEntry fieldEntry;
12 private final Translator translator;
13
14 public TranslationFieldVisitor(Translator translator, FieldDefEntry fieldEntry, int api, FieldVisitor fv) {
15 super(api, fv);
16 this.translator = translator;
17 this.fieldEntry = fieldEntry;
18 }
19
20 @Override
21 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
22 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
23 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
24 return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av);
25 }
26
27 @Override
28 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
29 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
30 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
31 return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av);
32 }
33}
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
index b2192e47..c7299628 100644
--- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java
@@ -39,15 +39,17 @@ public class TranslationMethodVisitor extends MethodVisitor {
39 } 39 }
40 40
41 @Override 41 @Override
42 public void visitAttribute(Attribute attr) { 42 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
43 // TODO: Implement 43 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
44 super.visitAttribute(attr); 44 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
45 return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av);
45 } 46 }
46 47
47 @Override 48 @Override
48 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 49 public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
49 // TODO: Implement 50 TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc));
50 return super.visitAnnotation(desc, visible); 51 AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible);
52 return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av);
51 } 53 }
52 54
53 @Override 55 @Override
@@ -69,7 +71,7 @@ public class TranslationMethodVisitor extends MethodVisitor {
69 // List types would require this whole block again, so just go with aListx 71 // List types would require this whole block again, so just go with aListx
70 nameBuilder.append(nameIndex); 72 nameBuilder.append(nameIndex);
71 } else if (argDesc.isType()) { 73 } else if (argDesc.isType()) {
72 String typeName = argDesc.getOwnerEntry().getSimpleName().replace("$", ""); 74 String typeName = argDesc.getTypeEntry().getSimpleName().replace("$", "");
73 typeName = typeName.substring(0, 1).toUpperCase(Locale.ROOT) + typeName.substring(1); 75 typeName = typeName.substring(0, 1).toUpperCase(Locale.ROOT) + typeName.substring(1);
74 nameBuilder.append(typeName); 76 nameBuilder.append(typeName);
75 } 77 }
diff --git a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
index c9e2ab49..196bbd69 100644
--- a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
+++ b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java
@@ -185,7 +185,7 @@ public class DirectionalTranslator implements Translator {
185 } 185 }
186 // TODO: Translating arguments calls method translation.. Can we refactor the code in such a way that we don't need this? 186 // TODO: Translating arguments calls method translation.. Can we refactor the code in such a way that we don't need this?
187 MethodEntry translatedOwner = getTranslatedMethod(entry.getOwnerEntry()); 187 MethodEntry translatedOwner = getTranslatedMethod(entry.getOwnerEntry());
188 return new LocalVariableEntry(translatedOwner, entry.getIndex(), translatedArgumentName); 188 return new LocalVariableEntry(translatedOwner != null ? translatedOwner : entry.getOwnerEntry(), entry.getIndex(), translatedArgumentName);
189 } 189 }
190 190
191 @Override 191 @Override
diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java
index 9b907a9c..79d9f104 100644
--- a/src/main/java/cuchaz/enigma/mapping/Mappings.java
+++ b/src/main/java/cuchaz/enigma/mapping/Mappings.java
@@ -156,7 +156,7 @@ public class Mappings {
156 for (MethodMapping methodMapping : classMapping.methods()) { 156 for (MethodMapping methodMapping : classMapping.methods()) {
157 for (TypeDescriptor desc : methodMapping.getObfDesc().types()) { 157 for (TypeDescriptor desc : methodMapping.getObfDesc().types()) {
158 if (desc.containsType()) { 158 if (desc.containsType()) {
159 classNames.add(desc.getOwnerEntry().getClassName()); 159 classNames.add(desc.getTypeEntry().getClassName());
160 } 160 }
161 } 161 }
162 } 162 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MethodDescriptor.java b/src/main/java/cuchaz/enigma/mapping/MethodDescriptor.java
index b56d1d48..0fc03517 100644
--- a/src/main/java/cuchaz/enigma/mapping/MethodDescriptor.java
+++ b/src/main/java/cuchaz/enigma/mapping/MethodDescriptor.java
@@ -97,7 +97,7 @@ public class MethodDescriptor {
97 97
98 public boolean hasClass(ClassEntry classEntry) { 98 public boolean hasClass(ClassEntry classEntry) {
99 for (TypeDescriptor desc : types()) { 99 for (TypeDescriptor desc : types()) {
100 if (desc.containsType() && desc.getOwnerEntry().equals(classEntry)) { 100 if (desc.containsType() && desc.getTypeEntry().equals(classEntry)) {
101 return true; 101 return true;
102 } 102 }
103 } 103 }
diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java
index ab55a02d..6373da7b 100644
--- a/src/main/java/cuchaz/enigma/mapping/Translator.java
+++ b/src/main/java/cuchaz/enigma/mapping/Translator.java
@@ -12,6 +12,7 @@
12package cuchaz.enigma.mapping; 12package cuchaz.enigma.mapping;
13 13
14import cuchaz.enigma.mapping.entry.*; 14import cuchaz.enigma.mapping.entry.*;
15import org.objectweb.asm.Type;
15 16
16public interface Translator { 17public interface Translator {
17 ClassEntry getTranslatedClass(ClassEntry entry); 18 ClassEntry getTranslatedClass(ClassEntry entry);
@@ -34,6 +35,18 @@ public interface Translator {
34 35
35 MethodDescriptor getTranslatedMethodDesc(MethodDescriptor descriptor); 36 MethodDescriptor getTranslatedMethodDesc(MethodDescriptor descriptor);
36 37
38 default Type getTranslatedType(Type type) {
39 String descString = type.getDescriptor();
40 // If this is a method
41 if (descString.contains("(")) {
42 MethodDescriptor descriptor = new MethodDescriptor(descString);
43 return Type.getMethodType(getTranslatedMethodDesc(descriptor).toString());
44 } else {
45 TypeDescriptor descriptor = new TypeDescriptor(descString);
46 return Type.getType(getTranslatedTypeDesc(descriptor).toString());
47 }
48 }
49
37 @SuppressWarnings("unchecked") 50 @SuppressWarnings("unchecked")
38 default <T extends Entry> T getTranslatedEntry(T entry) { 51 default <T extends Entry> T getTranslatedEntry(T entry) {
39 if (entry instanceof ClassDefEntry) { 52 if (entry instanceof ClassDefEntry) {
diff --git a/src/main/java/cuchaz/enigma/mapping/TypeDescriptor.java b/src/main/java/cuchaz/enigma/mapping/TypeDescriptor.java
index 58fa6513..b7b1255a 100644
--- a/src/main/java/cuchaz/enigma/mapping/TypeDescriptor.java
+++ b/src/main/java/cuchaz/enigma/mapping/TypeDescriptor.java
@@ -11,6 +11,7 @@
11 11
12package cuchaz.enigma.mapping; 12package cuchaz.enigma.mapping;
13 13
14import com.google.common.base.Preconditions;
14import com.google.common.collect.Maps; 15import com.google.common.collect.Maps;
15import cuchaz.enigma.mapping.entry.ClassEntry; 16import cuchaz.enigma.mapping.entry.ClassEntry;
16 17
@@ -22,6 +23,8 @@ public class TypeDescriptor {
22 protected final String desc; 23 protected final String desc;
23 24
24 public TypeDescriptor(String desc) { 25 public TypeDescriptor(String desc) {
26 Preconditions.checkNotNull(desc, "Desc cannot be null");
27
25 // don't deal with generics 28 // don't deal with generics
26 // this is just for raw jvm types 29 // this is just for raw jvm types
27 if (desc.charAt(0) == 'T' || desc.indexOf('<') >= 0 || desc.indexOf('>') >= 0) { 30 if (desc.charAt(0) == 'T' || desc.indexOf('<') >= 0 || desc.indexOf('>') >= 0) {
@@ -127,7 +130,7 @@ public class TypeDescriptor {
127 return this.desc.charAt(0) == 'L' && this.desc.charAt(this.desc.length() - 1) == ';'; 130 return this.desc.charAt(0) == 'L' && this.desc.charAt(this.desc.length() - 1) == ';';
128 } 131 }
129 132
130 public ClassEntry getOwnerEntry() { 133 public ClassEntry getTypeEntry() {
131 if (isType()) { 134 if (isType()) {
132 String name = this.desc.substring(1, this.desc.length() - 1); 135 String name = this.desc.substring(1, this.desc.length() - 1);
133 136
@@ -140,7 +143,7 @@ public class TypeDescriptor {
140 return new ClassEntry(name); 143 return new ClassEntry(name);
141 144
142 } else if (isArray() && getArrayType().isType()) { 145 } else if (isArray() && getArrayType().isType()) {
143 return getArrayType().getOwnerEntry(); 146 return getArrayType().getTypeEntry();
144 } else { 147 } else {
145 throw new IllegalStateException("desc doesn't have a class"); 148 throw new IllegalStateException("desc doesn't have a class");
146 } 149 }
@@ -185,7 +188,7 @@ public class TypeDescriptor {
185 public TypeDescriptor remap(Function<String, String> remapper) { 188 public TypeDescriptor remap(Function<String, String> remapper) {
186 String desc = this.desc; 189 String desc = this.desc;
187 if (isType() || (isArray() && containsType())) { 190 if (isType() || (isArray() && containsType())) {
188 String replacedName = remapper.apply(this.getOwnerEntry().getName()); 191 String replacedName = remapper.apply(this.getTypeEntry().getName());
189 if (replacedName != null) { 192 if (replacedName != null) {
190 if (this.isType()) { 193 if (this.isType()) {
191 desc = "L" + replacedName + ";"; 194 desc = "L" + replacedName + ";";