From d72aad82c795726efcf6145f5a4172e4c8d3a5b2 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 19 May 2018 20:38:14 +0200 Subject: Signature refactoring --- .../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 +- 7 files changed, 132 insertions(+), 33 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/mapping/Signature.java (limited to 'src/main/java/cuchaz/enigma/mapping') diff --git a/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java b/src/main/java/cuchaz/enigma/mapping/DirectionalTranslator.java index dec5acf..fe141c6 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 0000000..071e4af --- /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 1bc2f37..a9ff1cb 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 75e7f1b..ac1fe2a 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 78ea5f7..d18115b 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 1d2c094..ec3af69 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 e42a334..5892a03 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