From d72aad82c795726efcf6145f5a4172e4c8d3a5b2 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 19 May 2018 20:38:14 +0200 Subject: Signature refactoring --- .../java/cuchaz/enigma/analysis/EntryRenamer.java | 18 ++++- .../cuchaz/enigma/analysis/IndexClassVisitor.java | 6 +- .../enigma/analysis/IndexReferenceVisitor.java | 10 ++- src/main/java/cuchaz/enigma/analysis/JarIndex.java | 14 ++-- .../cuchaz/enigma/analysis/TranslationIndex.java | 4 +- .../translators/TranslationAnnotationVisitor.java | 9 ++- .../translators/TranslationClassVisitor.java | 44 ++++++------ .../translators/TranslationMethodVisitor.java | 3 +- .../translators/TranslationSignatureVisitor.java | 29 ++++---- .../enigma/mapping/DirectionalTranslator.java | 42 +++++------ src/main/java/cuchaz/enigma/mapping/Signature.java | 82 ++++++++++++++++++++++ .../java/cuchaz/enigma/mapping/Translator.java | 2 +- .../cuchaz/enigma/mapping/entry/ClassDefEntry.java | 10 ++- .../cuchaz/enigma/mapping/entry/FieldDefEntry.java | 12 +++- .../enigma/mapping/entry/MethodDefEntry.java | 12 +++- .../enigma/mapping/entry/ProcyonEntryFactory.java | 5 +- 16 files changed, 206 insertions(+), 96 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/mapping/Signature.java diff --git a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java index 656fa320..e37c1d0c 100644 --- a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java +++ b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java @@ -122,10 +122,22 @@ public class EntryRenamer { return (T) new ClassEntry(renameClassesInThing(renames, classEntry.getClassName())); } else if (thing instanceof FieldDefEntry) { FieldDefEntry fieldEntry = (FieldDefEntry) thing; - return (T) new FieldDefEntry(renameClassesInThing(renames, fieldEntry.getOwnerClassEntry()), fieldEntry.getName(), renameClassesInThing(renames, fieldEntry.getDesc()), fieldEntry.getAccess()); + return (T) new FieldDefEntry( + renameClassesInThing(renames, fieldEntry.getOwnerClassEntry()), + fieldEntry.getName(), + renameClassesInThing(renames, fieldEntry.getDesc()), + renameClassesInThing(renames, fieldEntry.getSignature()), + fieldEntry.getAccess() + ); } else if (thing instanceof MethodDefEntry) { MethodDefEntry methodEntry = (MethodDefEntry) thing; - return (T) new MethodDefEntry(renameClassesInThing(renames, methodEntry.getOwnerClassEntry()), methodEntry.getName(), renameClassesInThing(renames, methodEntry.getDesc()), methodEntry.getAccess()); + return (T) new MethodDefEntry( + renameClassesInThing(renames, methodEntry.getOwnerClassEntry()), + methodEntry.getName(), + renameClassesInThing(renames, methodEntry.getDesc()), + renameClassesInThing(renames, methodEntry.getSignature()), + methodEntry.getAccess() + ); } else if (thing instanceof LocalVariableEntry) { LocalVariableEntry argumentEntry = (LocalVariableEntry) thing; return (T) new LocalVariableEntry(renameClassesInThing(renames, argumentEntry.getOwnerEntry()), argumentEntry.getIndex(), argumentEntry.getName()); @@ -138,6 +150,8 @@ public class EntryRenamer { return (T) ((MethodDescriptor) thing).remap(className -> renameClassesInThing(renames, className)); } else if (thing instanceof TypeDescriptor) { return (T) ((TypeDescriptor) thing).remap(className -> renameClassesInThing(renames, className)); + } else if (thing instanceof Signature) { + return (T) ((Signature) thing).remap(className -> renameClassesInThing(renames, className)); } return thing; diff --git a/src/main/java/cuchaz/enigma/analysis/IndexClassVisitor.java b/src/main/java/cuchaz/enigma/analysis/IndexClassVisitor.java index 7828fa94..69fe54fc 100644 --- a/src/main/java/cuchaz/enigma/analysis/IndexClassVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/IndexClassVisitor.java @@ -16,14 +16,14 @@ public class IndexClassVisitor extends ClassVisitor { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - this.classEntry = this.index.indexClass(access, name, superName, interfaces); + this.classEntry = this.index.indexClass(access, name, signature, superName, interfaces); super.visit(version, access, name, signature, superName, interfaces); } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { if (this.classEntry != null) { - this.index.indexField(this.classEntry, access, name, desc); + this.index.indexField(this.classEntry, access, name, desc, signature); } return super.visitField(access, name, desc, signature, value); } @@ -31,7 +31,7 @@ public class IndexClassVisitor extends ClassVisitor { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (this.classEntry != null) { - this.index.indexMethod(this.classEntry, access, name, desc); + this.index.indexMethod(this.classEntry, access, name, desc, signature); } return super.visitMethod(access, name, desc, signature, exceptions); } diff --git a/src/main/java/cuchaz/enigma/analysis/IndexReferenceVisitor.java b/src/main/java/cuchaz/enigma/analysis/IndexReferenceVisitor.java index bd64bfc1..c05281bd 100644 --- a/src/main/java/cuchaz/enigma/analysis/IndexReferenceVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/IndexReferenceVisitor.java @@ -1,22 +1,20 @@ package cuchaz.enigma.analysis; import cuchaz.enigma.bytecode.AccessFlags; -import cuchaz.enigma.mapping.*; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Signature; import cuchaz.enigma.mapping.entry.ClassEntry; import cuchaz.enigma.mapping.entry.MethodDefEntry; -import cuchaz.enigma.mapping.entry.ReferencedEntryPool; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; public class IndexReferenceVisitor extends ClassVisitor { private final JarIndex index; - private final ReferencedEntryPool entryPool; private ClassEntry classEntry; - public IndexReferenceVisitor(JarIndex index, ReferencedEntryPool entryPool, int api) { + public IndexReferenceVisitor(JarIndex index, int api) { super(api); this.index = index; - this.entryPool = entryPool; } @Override @@ -26,7 +24,7 @@ public class IndexReferenceVisitor extends ClassVisitor { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodDefEntry entry = new MethodDefEntry(classEntry, name, new MethodDescriptor(desc), new AccessFlags(access)); + MethodDefEntry entry = new MethodDefEntry(classEntry, name, new MethodDescriptor(desc), Signature.createSignature(signature), new AccessFlags(access)); return new Method(this.index, entry, this.api); } diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java index 54dd5068..3479c5d5 100644 --- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java @@ -61,7 +61,7 @@ public class JarIndex { jar.visit(node -> node.accept(new IndexClassVisitor(this, Opcodes.ASM5))); // step 3: index field, method, constructor references - jar.visit(node -> node.accept(new IndexReferenceVisitor(this, entryPool, Opcodes.ASM5))); + jar.visit(node -> node.accept(new IndexReferenceVisitor(this, Opcodes.ASM5))); // step 4: index bridged methods for (MethodDefEntry methodEntry : methods.values()) { @@ -95,24 +95,24 @@ public class JarIndex { } } - protected ClassDefEntry indexClass(int access, String name, String superName, String[] interfaces) { + protected ClassDefEntry indexClass(int access, String name, String signature, String superName, String[] interfaces) { for (String interfaceName : interfaces) { if (name.equals(interfaceName)) { throw new IllegalArgumentException("Class cannot be its own interface! " + name); } } - return this.translationIndex.indexClass(access, name, superName, interfaces); + return this.translationIndex.indexClass(access, name, signature, superName, interfaces); } - protected void indexField(ClassDefEntry owner, int access, String name, String desc) { - FieldDefEntry fieldEntry = new FieldDefEntry(owner, name, new TypeDescriptor(desc), new AccessFlags(access)); + protected void indexField(ClassDefEntry owner, int access, String name, String desc, String signature) { + FieldDefEntry fieldEntry = new FieldDefEntry(owner, name, new TypeDescriptor(desc), Signature.createTypedSignature(signature), new AccessFlags(access)); this.translationIndex.indexField(fieldEntry); this.access.put(fieldEntry, Access.get(access)); this.fields.put(fieldEntry.getOwnerClassEntry(), fieldEntry); } - protected void indexMethod(ClassDefEntry owner, int access, String name, String desc) { - MethodDefEntry methodEntry = new MethodDefEntry(owner, name, new MethodDescriptor(desc), new AccessFlags(access)); + protected void indexMethod(ClassDefEntry owner, int access, String name, String desc, String signature) { + MethodDefEntry methodEntry = new MethodDefEntry(owner, name, new MethodDescriptor(desc), Signature.createSignature(signature), new AccessFlags(access)); this.translationIndex.indexMethod(methodEntry); this.access.put(methodEntry, Access.get(access)); this.methods.put(methodEntry.getOwnerClassEntry(), methodEntry); diff --git a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java index 0c8ed9cd..644a3f2b 100644 --- a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java @@ -76,8 +76,8 @@ public class TranslationIndex { } } - protected ClassDefEntry indexClass(int access, String name, String superName, String[] interfaces) { - ClassDefEntry classEntry = new ClassDefEntry(name, new AccessFlags(access)); + protected ClassDefEntry indexClass(int access, String name, String signature, String superName, String[] interfaces) { + ClassDefEntry classEntry = new ClassDefEntry(name, Signature.createSignature(signature), new AccessFlags(access)); if (isJre(classEntry)) { return null; } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java index 7cc37719..df5f8f7e 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java @@ -1,10 +1,9 @@ package cuchaz.enigma.bytecode.translators; -import cuchaz.enigma.bytecode.AccessFlags; import cuchaz.enigma.mapping.Translator; import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.ClassEntry; -import cuchaz.enigma.mapping.entry.FieldDefEntry; +import cuchaz.enigma.mapping.entry.FieldEntry; import org.objectweb.asm.AnnotationVisitor; public class TranslationAnnotationVisitor extends AnnotationVisitor { @@ -30,15 +29,15 @@ public class TranslationAnnotationVisitor extends AnnotationVisitor { @Override public AnnotationVisitor visitAnnotation(String name, String desc) { TypeDescriptor type = new TypeDescriptor(desc); - FieldDefEntry annotationField = translator.getTranslatedFieldDef(new FieldDefEntry(annotationEntry, name, type, AccessFlags.PUBLIC)); + FieldEntry annotationField = translator.getTranslatedField(new FieldEntry(annotationEntry, name, type)); return super.visitAnnotation(annotationField.getName(), annotationField.getDesc().toString()); } @Override public void visitEnum(String name, String desc, String value) { TypeDescriptor type = new TypeDescriptor(desc); - FieldDefEntry annotationField = translator.getTranslatedFieldDef(new FieldDefEntry(annotationEntry, name, type, AccessFlags.PUBLIC)); - FieldDefEntry enumField = translator.getTranslatedFieldDef(new FieldDefEntry(type.getTypeEntry(), value, type, AccessFlags.PUBLIC_STATIC_FINAL)); + FieldEntry annotationField = translator.getTranslatedField(new FieldEntry(annotationEntry, name, type)); + FieldEntry enumField = translator.getTranslatedField(new FieldEntry(type.getTypeEntry(), value, type)); super.visitEnum(annotationField.getName(), annotationField.getDesc().toString(), enumField.getName()); } } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java index 89772dbb..0137155c 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java @@ -14,6 +14,7 @@ package cuchaz.enigma.bytecode.translators; import cuchaz.enigma.analysis.JarIndex; import cuchaz.enigma.bytecode.AccessFlags; import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Signature; import cuchaz.enigma.mapping.Translator; import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.*; @@ -25,6 +26,7 @@ public class TranslationClassVisitor extends ClassVisitor { private final ReferencedEntryPool entryPool; private ClassDefEntry obfClassEntry; + private Signature obfSignature; public TranslationClassVisitor(Translator translator, JarIndex jarIndex, ReferencedEntryPool entryPool, int api, ClassVisitor cv) { super(api, cv); @@ -35,29 +37,28 @@ public class TranslationClassVisitor extends ClassVisitor { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - obfClassEntry = new ClassDefEntry(name, new AccessFlags(access)); - ClassDefEntry entry = translator.getTranslatedClassDef(obfClassEntry); + obfSignature = Signature.createSignature(signature); + obfClassEntry = new ClassDefEntry(name, obfSignature, new AccessFlags(access)); + ClassDefEntry translatedEntry = translator.getTranslatedClassDef(obfClassEntry); ClassEntry superEntry = translator.getTranslatedClass(entryPool.getClass(superName)); String[] translatedInterfaces = new String[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { translatedInterfaces[i] = translator.getTranslatedClass(entryPool.getClass(interfaces[i])).getName(); } - String translatedSignature = translator.getTranslatedSignature(signature, false, api); - super.visit(version, entry.getAccess().getFlags(), entry.getName(), translatedSignature, superEntry.getName(), translatedInterfaces); + super.visit(version, translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getSignature().toString(), superEntry.getName(), translatedInterfaces); } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access)); + FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), Signature.createTypedSignature(signature), new AccessFlags(access)); FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry); - String translatedSignature = translator.getTranslatedSignature(signature, true, api); - FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, value); + FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedEntry.getSignature().toString(), value); return new TranslationFieldVisitor(translator, translatedEntry, api, fv); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodDefEntry entry = new MethodDefEntry(obfClassEntry, name, new MethodDescriptor(desc), new AccessFlags(access)); + MethodDefEntry entry = new MethodDefEntry(obfClassEntry, name, new MethodDescriptor(desc), Signature.createSignature(signature), new AccessFlags(access)); MethodDefEntry translatedEntry = translator.getTranslatedMethodDef(entry); if (jarIndex.getBridgedMethod(entry) != null) { translatedEntry.getAccess().setBridged(); @@ -66,11 +67,22 @@ public class TranslationClassVisitor extends ClassVisitor { for (int i = 0; i < exceptions.length; i++) { translatedExceptions[i] = translator.getTranslatedClass(entryPool.getClass(exceptions[i])).getName(); } - String translatedSignature = translator.getTranslatedSignature(signature, false, api); - MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, translatedExceptions); + MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedEntry.getSignature().toString(), translatedExceptions); return new TranslationMethodVisitor(translator, translatedEntry, api, mv); } + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + ClassDefEntry translatedEntry = translator.getTranslatedClassDef(new ClassDefEntry(name, obfSignature, new AccessFlags(access))); + String translatedName = translatedEntry.getName(); + int separatorIndex = translatedName.lastIndexOf("$"); + String parentName = translatedName.substring(0, separatorIndex); + String childName = translatedName.substring(separatorIndex + 1); + + ClassEntry outerEntry = translator.getTranslatedClass(entryPool.getClass(parentName)); + super.visitInnerClass(translatedName, outerEntry.getName(), childName, translatedEntry.getAccess().getFlags()); + } + @Override public void visitOuterClass(String owner, String name, String desc) { if (desc != null) { @@ -94,16 +106,4 @@ public class TranslationClassVisitor extends ClassVisitor { AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath, translatedDesc.toString(), visible); return new TranslationAnnotationVisitor(translator, translatedDesc.getTypeEntry(), api, av); } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - ClassDefEntry translatedEntry = translator.getTranslatedClassDef(new ClassDefEntry(name, new AccessFlags(access))); - String translatedName = translatedEntry.getName(); - int separatorIndex = translatedName.lastIndexOf("$"); - String parentName = translatedName.substring(0, separatorIndex); - String childName = translatedName.substring(separatorIndex + 1); - - ClassEntry outerEntry = translator.getTranslatedClass(entryPool.getClass(parentName)); - super.visitInnerClass(translatedName, outerEntry.getName(), childName, translatedEntry.getAccess().getFlags()); - } } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java index cce91db3..eeabdfad 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java @@ -1,6 +1,7 @@ package cuchaz.enigma.bytecode.translators; import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Signature; import cuchaz.enigma.mapping.Translator; import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.*; @@ -102,7 +103,7 @@ public class TranslationMethodVisitor extends MethodVisitor { } translatedName = nameBuilder.toString(); } - String translatedSignature = translator.getTranslatedSignature(signature, true, api); + String translatedSignature = translator.getTranslatedSignature(Signature.createTypedSignature(signature)).toString(); super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index); } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java index e1dcea5c..2bb80a83 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java @@ -1,37 +1,36 @@ package cuchaz.enigma.bytecode.translators; -import cuchaz.enigma.mapping.Translator; -import cuchaz.enigma.mapping.entry.ClassEntry; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.signature.SignatureVisitor; import java.util.Stack; +import java.util.function.Function; public class TranslationSignatureVisitor extends SignatureVisitor { - private final Translator translator; + private final Function remapper; private final SignatureVisitor sv; - private final Stack classes = new Stack<>(); + private final Stack classes = new Stack<>(); - public TranslationSignatureVisitor(Translator translator, int api, SignatureVisitor sv) { - super(api); - this.translator = translator; + public TranslationSignatureVisitor(Function remapper, SignatureVisitor sv) { + super(Opcodes.ASM5); + this.remapper = remapper; this.sv = sv; } @Override public void visitClassType(String name) { - ClassEntry entry = new ClassEntry(name); - ClassEntry translatedEntry = this.translator.getTranslatedClass(entry); - this.classes.push(entry); - this.sv.visitClassType(translatedEntry.getName()); + String translatedEntry = this.remapper.apply(name); + this.classes.push(name); + this.sv.visitClassType(translatedEntry); } @Override public void visitInnerClassType(String name) { - ClassEntry outerEntry = this.classes.pop(); - ClassEntry entry = new ClassEntry(outerEntry + "$" + name); - this.classes.push(entry); - String translatedEntry = this.translator.getTranslatedClass(entry).getName(); + String outerName = this.classes.pop(); + String className = outerName + "$" + name; + this.classes.push(className); + String translatedEntry = this.remapper.apply(className); this.sv.visitInnerClassType(translatedEntry.substring(translatedEntry.lastIndexOf('$') + 1)); } diff --git a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java index dec5acf4..fe141c66 100644 --- a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java +++ b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java @@ -15,20 +15,13 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import cuchaz.enigma.analysis.TranslationIndex; import cuchaz.enigma.bytecode.AccessFlags; -import cuchaz.enigma.bytecode.translators.TranslationSignatureVisitor; import cuchaz.enigma.mapping.entry.*; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.objectweb.asm.signature.SignatureWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class DirectionalTranslator implements Translator { - private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*"); - private final TranslationDirection direction; private final Map classes; private final TranslationIndex index; @@ -62,7 +55,7 @@ public class DirectionalTranslator implements Translator { @Override public ClassDefEntry getTranslatedClassDef(ClassDefEntry entry) { String className = entry.isInnerClass() ? translateInnerClassName(entry) : translateClassName(entry); - return new ClassDefEntry(className, getClassModifier(entry).transform(entry.getAccess())); + return new ClassDefEntry(className, entry.getSignature(), getClassModifier(entry).transform(entry.getAccess())); } private String translateClassName(ClassEntry entry) { @@ -108,8 +101,9 @@ public class DirectionalTranslator implements Translator { } ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); TypeDescriptor translatedDesc = getTranslatedTypeDesc(entry.getDesc()); + Signature translatedSignature = getTranslatedSignature(entry.getSignature()); AccessFlags translatedAccess = getFieldModifier(entry).transform(entry.getAccess()); - return new FieldDefEntry(translatedOwner, translatedName, translatedDesc, translatedAccess); + return new FieldDefEntry(translatedOwner, translatedName, translatedDesc, translatedSignature, translatedAccess); } @Override @@ -148,8 +142,9 @@ public class DirectionalTranslator implements Translator { } ClassEntry translatedOwner = getTranslatedClass(entry.getOwnerClassEntry()); MethodDescriptor translatedDesc = getTranslatedMethodDesc(entry.getDesc()); + Signature translatedSignature = getTranslatedSignature(entry.getSignature()); AccessFlags access = getMethodModifier(entry).transform(entry.getAccess()); - return new MethodDefEntry(translatedOwner, translatedName, translatedDesc, access); + return new MethodDefEntry(translatedOwner, translatedName, translatedDesc, translatedSignature, access); } @Override @@ -265,7 +260,7 @@ public class DirectionalTranslator implements Translator { @Override public TypeDescriptor getTranslatedTypeDesc(TypeDescriptor desc) { - return desc.remap(name -> getTranslatedClass(new ClassEntry(name)).getName()); + return desc.remap(this::remapClass); } @Override @@ -279,23 +274,11 @@ public class DirectionalTranslator implements Translator { } @Override - public String getTranslatedSignature(String signature, boolean isType, int api) { + public Signature getTranslatedSignature(Signature signature) { if (signature == null) { return null; } - SignatureReader reader = new SignatureReader(signature); - SignatureWriter writer = new SignatureWriter(); - SignatureVisitor visitor = new TranslationSignatureVisitor(this, api, writer); - if (isType) { - reader.acceptType(visitor); - } else { - reader.accept(visitor); - } - String translatedSignature = writer.toString(); - if (OBJECT_PATTERN.matcher(signature).matches()) { - translatedSignature = signature.replaceAll(":Ljava/lang/Object;:", "::"); - } - return translatedSignature; + return signature.remap(this::remapClass); } private ClassMapping findClassMapping(ClassEntry entry) { @@ -360,4 +343,13 @@ public class DirectionalTranslator implements Translator { } return Mappings.EntryModifier.UNCHANGED; } + + private String remapClass(String name) { + String translatedName = getTranslatedClass(new ClassEntry(name)).getName(); + int separatorIndex = translatedName.lastIndexOf("$"); + if (separatorIndex != -1) { + translatedName = translatedName.substring(separatorIndex + 1); + } + return translatedName; + } } diff --git a/src/main/java/cuchaz/enigma/mapping/Signature.java b/src/main/java/cuchaz/enigma/mapping/Signature.java new file mode 100644 index 00000000..071e4afa --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/Signature.java @@ -0,0 +1,82 @@ +package cuchaz.enigma.mapping; + +import cuchaz.enigma.bytecode.translators.TranslationSignatureVisitor; +import org.objectweb.asm.signature.SignatureReader; +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; + +import java.util.function.Function; +import java.util.regex.Pattern; + +public class Signature { + private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*"); + + private final String signature; + private final boolean isType; + + private Signature(String signature, boolean isType) { + if (signature != null && OBJECT_PATTERN.matcher(signature).matches()) { + signature = signature.replaceAll(":Ljava/lang/Object;:", "::"); + } + + this.signature = signature; + this.isType = isType; + } + + public static Signature createTypedSignature(String signature) { + if (signature != null && !signature.isEmpty()) { + return new Signature(signature, true); + } + return new Signature(null, true); + } + + public static Signature createSignature(String signature) { + if (signature != null && !signature.isEmpty()) { + return new Signature(signature, false); + } + return new Signature(null, false); + } + + public String getSignature() { + return signature; + } + + public boolean isType() { + return isType; + } + + public Signature remap(Function remapper) { + if (signature == null) { + return this; + } + SignatureWriter writer = new SignatureWriter(); + SignatureVisitor visitor = new TranslationSignatureVisitor(remapper, writer); + if (isType) { + new SignatureReader(signature).acceptType(visitor); + } else { + new SignatureReader(signature).accept(visitor); + } + return new Signature(writer.toString(), isType); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Signature) { + Signature other = (Signature) obj; + return (other.signature == null && signature == null || other.signature != null + && signature != null && other.signature.equals(signature)) + && other.isType == this.isType; + } + return false; + } + + @Override + public int hashCode() { + return signature.hashCode() | (isType ? 1 : 0) << 16; + } + + @Override + public String toString() { + return signature; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java index 1bc2f373..a9ff1cbb 100644 --- a/src/main/java/cuchaz/enigma/mapping/Translator.java +++ b/src/main/java/cuchaz/enigma/mapping/Translator.java @@ -44,7 +44,7 @@ public interface Translator { MethodDescriptor getTranslatedMethodDesc(MethodDescriptor descriptor); - String getTranslatedSignature(String signature, boolean isType, int api); + Signature getTranslatedSignature(Signature signature); default Type getTranslatedType(Type type) { String descString = type.getDescriptor(); diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java index 75e7f1bd..ac1fe2ab 100644 --- a/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java +++ b/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java @@ -13,16 +13,24 @@ package cuchaz.enigma.mapping.entry; import com.google.common.base.Preconditions; import cuchaz.enigma.bytecode.AccessFlags; +import cuchaz.enigma.mapping.Signature; public class ClassDefEntry extends ClassEntry { private final AccessFlags access; + private final Signature signature; - public ClassDefEntry(String className, AccessFlags access) { + public ClassDefEntry(String className, Signature signature, AccessFlags access) { super(className); + Preconditions.checkNotNull(signature, "Class signature cannot be null"); Preconditions.checkNotNull(access, "Class access cannot be null"); + this.signature = signature; this.access = access; } + public Signature getSignature() { + return signature; + } + public AccessFlags getAccess() { return access; } diff --git a/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java index 78ea5f76..d18115bf 100644 --- a/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java +++ b/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java @@ -13,23 +13,31 @@ package cuchaz.enigma.mapping.entry; import com.google.common.base.Preconditions; import cuchaz.enigma.bytecode.AccessFlags; +import cuchaz.enigma.mapping.Signature; import cuchaz.enigma.mapping.TypeDescriptor; public class FieldDefEntry extends FieldEntry { private final AccessFlags access; + private final Signature signature; - public FieldDefEntry(ClassEntry ownerEntry, String name, TypeDescriptor desc, AccessFlags access) { + public FieldDefEntry(ClassEntry ownerEntry, String name, TypeDescriptor desc, Signature signature, AccessFlags access) { super(ownerEntry, name, desc); Preconditions.checkNotNull(access, "Field access cannot be null"); + Preconditions.checkNotNull(signature, "Field signature cannot be null"); this.access = access; + this.signature = signature; } public AccessFlags getAccess() { return access; } + public Signature getSignature() { + return signature; + } + @Override public FieldDefEntry updateOwnership(ClassEntry owner) { - return new FieldDefEntry(owner, this.name, this.desc, access); + return new FieldDefEntry(owner, this.name, this.desc, signature, access); } } diff --git a/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java index 1d2c094d..ec3af694 100644 --- a/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java +++ b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java @@ -14,23 +14,31 @@ package cuchaz.enigma.mapping.entry; import com.google.common.base.Preconditions; import cuchaz.enigma.bytecode.AccessFlags; import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Signature; public class MethodDefEntry extends MethodEntry { private final AccessFlags access; + private final Signature signature; - public MethodDefEntry(ClassEntry classEntry, String name, MethodDescriptor descriptor, AccessFlags access) { + public MethodDefEntry(ClassEntry classEntry, String name, MethodDescriptor descriptor, Signature signature, AccessFlags access) { super(classEntry, name, descriptor); Preconditions.checkNotNull(access, "Method access cannot be null"); + Preconditions.checkNotNull(signature, "Method signature cannot be null"); this.access = access; + this.signature = signature; } public AccessFlags getAccess() { return access; } + public Signature getSignature() { + return signature; + } + @Override public MethodDefEntry updateOwnership(ClassEntry classEntry) { - return new MethodDefEntry(new ClassEntry(classEntry.getName()), name, descriptor, access); + return new MethodDefEntry(new ClassEntry(classEntry.getName()), name, descriptor, signature, access); } } diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java b/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java index e42a334e..5892a03e 100644 --- a/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java +++ b/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java @@ -14,6 +14,7 @@ package cuchaz.enigma.mapping.entry; import com.strobel.assembler.metadata.*; import cuchaz.enigma.bytecode.AccessFlags; import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Signature; import cuchaz.enigma.mapping.TypeDescriptor; import java.util.List; @@ -56,7 +57,7 @@ public class ProcyonEntryFactory { public FieldDefEntry getFieldDefEntry(FieldDefinition def) { ClassEntry classEntry = entryPool.getClass(def.getDeclaringType().getInternalName()); - return new FieldDefEntry(classEntry, def.getName(), new TypeDescriptor(def.getErasedSignature()), new AccessFlags(def.getModifiers())); + return new FieldDefEntry(classEntry, def.getName(), new TypeDescriptor(def.getErasedSignature()), Signature.createTypedSignature(def.getSignature()), new AccessFlags(def.getModifiers())); } public MethodEntry getMethodEntry(MemberReference def) { @@ -66,6 +67,6 @@ public class ProcyonEntryFactory { public MethodDefEntry getMethodDefEntry(MethodDefinition def) { ClassEntry classEntry = entryPool.getClass(def.getDeclaringType().getInternalName()); - return new MethodDefEntry(classEntry, def.getName(), new MethodDescriptor(def.getErasedSignature()), new AccessFlags(def.getModifiers())); + return new MethodDefEntry(classEntry, def.getName(), new MethodDescriptor(def.getErasedSignature()), Signature.createSignature(def.getSignature()), new AccessFlags(def.getModifiers())); } } -- cgit v1.2.3