From 406b9a89318473571d27de60b8aa1b51f84af245 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 19 May 2018 17:06:26 +0200 Subject: Package updates --- .../cuchaz/enigma/mapping/entry/ClassDefEntry.java | 29 ++++ .../cuchaz/enigma/mapping/entry/ClassEntry.java | 171 +++++++++++++++++++++ .../java/cuchaz/enigma/mapping/entry/Entry.java | 22 +++ .../cuchaz/enigma/mapping/entry/EntryFactory.java | 49 ++++++ .../cuchaz/enigma/mapping/entry/FieldDefEntry.java | 35 +++++ .../cuchaz/enigma/mapping/entry/FieldEntry.java | 77 ++++++++++ .../mapping/entry/LocalVariableDefEntry.java | 76 +++++++++ .../enigma/mapping/entry/LocalVariableEntry.java | 82 ++++++++++ .../enigma/mapping/entry/MethodDefEntry.java | 36 +++++ .../cuchaz/enigma/mapping/entry/MethodEntry.java | 80 ++++++++++ .../enigma/mapping/entry/ProcyonEntryFactory.java | 71 +++++++++ .../enigma/mapping/entry/ReferencedEntryPool.java | 53 +++++++ 12 files changed, 781 insertions(+) create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/ClassEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/Entry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/EntryFactory.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/FieldEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/LocalVariableDefEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/LocalVariableEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/MethodEntry.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java create mode 100644 src/main/java/cuchaz/enigma/mapping/entry/ReferencedEntryPool.java (limited to 'src/main/java/cuchaz/enigma/mapping/entry') diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java new file mode 100644 index 0000000..75e7f1b --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/ClassDefEntry.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.bytecode.AccessFlags; + +public class ClassDefEntry extends ClassEntry { + private final AccessFlags access; + + public ClassDefEntry(String className, AccessFlags access) { + super(className); + Preconditions.checkNotNull(access, "Class access cannot be null"); + this.access = access; + } + + public AccessFlags getAccess() { + return access; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ClassEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/ClassEntry.java new file mode 100644 index 0000000..fc604d8 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/ClassEntry.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; + +import java.util.List; + +public class ClassEntry implements Entry { + + private final String name; + + public ClassEntry(String className) { + Preconditions.checkNotNull(className, "Class name cannot be null"); + + if (className.indexOf('.') >= 0) { + throw new IllegalArgumentException("Class name must be in JVM format. ie, path/to/package/class$inner : " + className); + } + + this.name = className; + + if (isInnerClass() && getInnermostClassName().indexOf('/') >= 0) { + throw new IllegalArgumentException("Inner class must not have a package: " + className); + } + } + + public ClassEntry(ClassEntry other) { + this.name = other.name; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getClassName() { + return this.name; + } + + @Override + public ClassEntry getOwnerClassEntry() { + return this; + } + + @Override + public ClassEntry updateOwnership(ClassEntry classEntry) { + return classEntry; + } + + @Override + public int hashCode() { + return this.name.hashCode(); + } + + @Override + public boolean equals(Object other) { + return other instanceof ClassEntry && equals((ClassEntry) other); + } + + public boolean equals(ClassEntry other) { + return other != null && this.name.equals(other.name); + } + + @Override + public String toString() { + return this.name; + } + + public boolean isInnerClass() { + return this.name.lastIndexOf('$') >= 0; + } + + public List getClassChainNames() { + return Lists.newArrayList(this.name.split("\\$")); + } + + public List getClassChain() { + List entries = Lists.newArrayList(); + StringBuilder buf = new StringBuilder(); + for (String name : getClassChainNames()) { + if (buf.length() > 0) { + buf.append("$"); + } + buf.append(name); + entries.add(new ClassEntry(buf.toString())); + } + return entries; + } + + public String getOutermostClassName() { + if (isInnerClass()) { + return this.name.substring(0, this.name.indexOf('$')); + } + return this.name; + } + + public ClassEntry getOutermostClassEntry() { + return new ClassEntry(getOutermostClassName()); + } + + public String getOuterClassName() { + if (!isInnerClass()) { + throw new Error("This is not an inner class!"); + } + return this.name.substring(0, this.name.lastIndexOf('$')); + } + + public ClassEntry getOuterClassEntry() { + return new ClassEntry(getOuterClassName()); + } + + public String getInnermostClassName() { + if (!isInnerClass()) { + throw new Error("This is not an inner class!"); + } + return this.name.substring(this.name.lastIndexOf('$') + 1); + } + + public boolean isInDefaultPackage() { + return this.name.indexOf('/') < 0; + } + + public String getPackageName() { + return getPackageName(this.name); + } + + public String getSimpleName() { + int pos = this.name.lastIndexOf('/'); + if (pos > 0) { + return this.name.substring(pos + 1); + } + return this.name; + } + + public static String getPackageName(String name) { + int pos = name.lastIndexOf('/'); + if (pos > 0) { + return name.substring(0, pos); + } + return null; + } + + public ClassEntry buildClassEntry(List classChain) { + assert (classChain.contains(this)); + StringBuilder buf = new StringBuilder(); + for (ClassEntry chainEntry : classChain) { + if (buf.length() == 0) { + buf.append(chainEntry.getName()); + } else { + buf.append("$"); + buf.append(chainEntry.isInnerClass() ? chainEntry.getInnermostClassName() : chainEntry.getSimpleName()); + } + + if (chainEntry == this) { + break; + } + } + return new ClassEntry(buf.toString()); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/Entry.java b/src/main/java/cuchaz/enigma/mapping/entry/Entry.java new file mode 100644 index 0000000..b612140 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/Entry.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +public interface Entry { + String getName(); + + String getClassName(); + + ClassEntry getOwnerClassEntry(); + + Entry updateOwnership(ClassEntry classEntry); +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/EntryFactory.java b/src/main/java/cuchaz/enigma/mapping/entry/EntryFactory.java new file mode 100644 index 0000000..5bd159f --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/EntryFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import cuchaz.enigma.analysis.JarIndex; +import cuchaz.enigma.mapping.ClassMapping; +import cuchaz.enigma.mapping.FieldMapping; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.MethodMapping; + +public class EntryFactory { + public static ClassEntry getObfClassEntry(JarIndex jarIndex, ClassMapping classMapping) { + ClassEntry obfClassEntry = new ClassEntry(classMapping.getObfFullName()); + return obfClassEntry.buildClassEntry(jarIndex.getObfClassChain(obfClassEntry)); + } + + private static ClassEntry getObfClassEntry(ClassMapping classMapping) { + return new ClassEntry(classMapping.getObfFullName()); + } + + public static ClassEntry getDeobfClassEntry(ClassMapping classMapping) { + return new ClassEntry(classMapping.getDeobfName()); + } + + public static FieldEntry getObfFieldEntry(ClassMapping classMapping, FieldMapping fieldMapping) { + return new FieldEntry(getObfClassEntry(classMapping), fieldMapping.getObfName(), fieldMapping.getObfDesc()); + } + + public static MethodEntry getMethodEntry(ClassEntry classEntry, String name, MethodDescriptor desc) { + return new MethodEntry(classEntry, name, desc); + } + + public static MethodEntry getObfMethodEntry(ClassEntry classEntry, MethodMapping methodMapping) { + return getMethodEntry(classEntry, methodMapping.getObfName(), methodMapping.getObfDesc()); + } + + public static MethodEntry getObfMethodEntry(ClassMapping classMapping, MethodMapping methodMapping) { + return getObfMethodEntry(getObfClassEntry(classMapping), methodMapping); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java new file mode 100644 index 0000000..78ea5f7 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/FieldDefEntry.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.bytecode.AccessFlags; +import cuchaz.enigma.mapping.TypeDescriptor; + +public class FieldDefEntry extends FieldEntry { + private final AccessFlags access; + + public FieldDefEntry(ClassEntry ownerEntry, String name, TypeDescriptor desc, AccessFlags access) { + super(ownerEntry, name, desc); + Preconditions.checkNotNull(access, "Field access cannot be null"); + this.access = access; + } + + public AccessFlags getAccess() { + return access; + } + + @Override + public FieldDefEntry updateOwnership(ClassEntry owner) { + return new FieldDefEntry(owner, this.name, this.desc, access); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/FieldEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/FieldEntry.java new file mode 100644 index 0000000..b6e1554 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/FieldEntry.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.mapping.TypeDescriptor; +import cuchaz.enigma.utils.Utils; + +public class FieldEntry implements Entry { + + protected final ClassEntry ownerEntry; + protected final String name; + protected final TypeDescriptor desc; + + // NOTE: this argument order is important for the MethodReader/MethodWriter + public FieldEntry(ClassEntry ownerEntry, String name, TypeDescriptor desc) { + Preconditions.checkNotNull(ownerEntry, "Owner cannot be null"); + Preconditions.checkNotNull(name, "Field name cannot be null"); + Preconditions.checkNotNull(desc, "Field descriptor cannot be null"); + + this.ownerEntry = ownerEntry; + this.name = name; + this.desc = desc; + } + + @Override + public ClassEntry getOwnerClassEntry() { + return this.ownerEntry; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getClassName() { + return this.ownerEntry.getName(); + } + + public TypeDescriptor getDesc() { + return this.desc; + } + + @Override + public FieldEntry updateOwnership(ClassEntry owner) { + return new FieldEntry(owner, this.name, this.desc); + } + + @Override + public int hashCode() { + return Utils.combineHashesOrdered(this.ownerEntry, this.name, this.desc); + } + + @Override + public boolean equals(Object other) { + return other instanceof FieldEntry && equals((FieldEntry) other); + } + + public boolean equals(FieldEntry other) { + return this.ownerEntry.equals(other.ownerEntry) && this.name.equals(other.name) && this.desc.equals(other.desc); + } + + @Override + public String toString() { + return this.ownerEntry.getName() + "." + this.name + ":" + this.desc; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableDefEntry.java new file mode 100644 index 0000000..0c4f3c1 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableDefEntry.java @@ -0,0 +1,76 @@ +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.mapping.TypeDescriptor; +import cuchaz.enigma.utils.Utils; + +/** + * TypeDescriptor... + * Created by Thog + * 19/10/2016 + */ +public class LocalVariableDefEntry extends LocalVariableEntry { + + protected final MethodDefEntry ownerEntry; + protected final TypeDescriptor desc; + + public LocalVariableDefEntry(MethodDefEntry ownerEntry, int index, String name, TypeDescriptor desc) { + super(ownerEntry, index, name); + Preconditions.checkNotNull(desc, "Variable desc cannot be null"); + + this.ownerEntry = ownerEntry; + this.desc = desc; + } + + public LocalVariableDefEntry(MethodDefEntry ownerEntry, int index, String name) { + super(ownerEntry, index, name); + + this.ownerEntry = ownerEntry; + + int namedIndex = getNamedIndex(); + if (namedIndex < 0) { + this.desc = TypeDescriptor.of(ownerEntry.getOwnerClassEntry().getName()); + } else { + this.desc = ownerEntry.getDesc().getArgumentDescs().get(namedIndex); + } + } + + @Override + public MethodDefEntry getOwnerEntry() { + return this.ownerEntry; + } + + public TypeDescriptor getDesc() { + return desc; + } + + public int getNamedIndex() { + // If we're not static, "this" is bound to index 0 + int indexOffset = ownerEntry.getAccess().isStatic() ? 0 : 1; + return index - indexOffset; + } + + @Override + public LocalVariableDefEntry updateOwnership(ClassEntry classEntry) { + return new LocalVariableDefEntry(ownerEntry.updateOwnership(classEntry), index, name, desc); + } + + @Override + public int hashCode() { + return Utils.combineHashesOrdered(this.ownerEntry, this.desc.hashCode(), this.name.hashCode(), Integer.hashCode(this.index)); + } + + @Override + public boolean equals(Object other) { + return other instanceof LocalVariableDefEntry && equals((LocalVariableDefEntry) other); + } + + public boolean equals(LocalVariableDefEntry other) { + return this.ownerEntry.equals(other.ownerEntry) && this.desc.equals(other.desc) && this.name.equals(other.name) && this.index == other.index; + } + + @Override + public String toString() { + return this.ownerEntry + "(" + this.index + ":" + this.name + ":" + this.desc + ")"; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableEntry.java new file mode 100644 index 0000000..a794d0a --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/LocalVariableEntry.java @@ -0,0 +1,82 @@ +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.utils.Utils; + +/** + * TypeDescriptor... + * Created by Thog + * 19/10/2016 + */ +public class LocalVariableEntry implements Entry { + + protected final MethodEntry ownerEntry; + protected final String name; + protected final int index; + + public LocalVariableEntry(MethodEntry ownerEntry, int index, String name) { + Preconditions.checkNotNull(ownerEntry, "Variable owner cannot be null"); + Preconditions.checkNotNull(name, "Variable name cannot be null"); + Preconditions.checkArgument(index >= 0, "Index must be positive"); + + this.ownerEntry = ownerEntry; + this.name = name; + this.index = index; + } + + public MethodEntry getOwnerEntry() { + return this.ownerEntry; + } + + public int getIndex() { + return index; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public ClassEntry getOwnerClassEntry() { + return this.ownerEntry.getOwnerClassEntry(); + } + + @Override + public String getClassName() { + return this.ownerEntry.getClassName(); + } + + @Override + public LocalVariableEntry updateOwnership(ClassEntry classEntry) { + return new LocalVariableEntry(ownerEntry.updateOwnership(classEntry), index, name); + } + + public String getMethodName() { + return this.ownerEntry.getName(); + } + + public MethodDescriptor getMethodDesc() { + return this.ownerEntry.getDesc(); + } + + @Override + public int hashCode() { + return Utils.combineHashesOrdered(this.ownerEntry, this.name.hashCode(), Integer.hashCode(this.index)); + } + + @Override + public boolean equals(Object other) { + return other instanceof LocalVariableEntry && equals((LocalVariableEntry) other); + } + + public boolean equals(LocalVariableEntry other) { + return this.ownerEntry.equals(other.ownerEntry) && this.name.equals(other.name) && this.index == other.index; + } + + @Override + public String toString() { + return this.ownerEntry + "(" + this.index + ":" + this.name + ")"; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java new file mode 100644 index 0000000..1d2c094 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/MethodDefEntry.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.bytecode.AccessFlags; +import cuchaz.enigma.mapping.MethodDescriptor; + +public class MethodDefEntry extends MethodEntry { + + private final AccessFlags access; + + public MethodDefEntry(ClassEntry classEntry, String name, MethodDescriptor descriptor, AccessFlags access) { + super(classEntry, name, descriptor); + Preconditions.checkNotNull(access, "Method access cannot be null"); + this.access = access; + } + + public AccessFlags getAccess() { + return access; + } + + @Override + public MethodDefEntry updateOwnership(ClassEntry classEntry) { + return new MethodDefEntry(new ClassEntry(classEntry.getName()), name, descriptor, access); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/MethodEntry.java b/src/main/java/cuchaz/enigma/mapping/entry/MethodEntry.java new file mode 100644 index 0000000..1abc5b1 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/MethodEntry.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.google.common.base.Preconditions; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.utils.Utils; + +public class MethodEntry implements Entry { + + protected final ClassEntry classEntry; + protected final String name; + protected final MethodDescriptor descriptor; + + public MethodEntry(ClassEntry classEntry, String name, MethodDescriptor descriptor) { + Preconditions.checkNotNull(classEntry, "Class cannot be null"); + Preconditions.checkNotNull(name, "Method name cannot be null"); + Preconditions.checkNotNull(descriptor, "Method descriptor cannot be null"); + + this.classEntry = classEntry; + this.name = name; + this.descriptor = descriptor; + } + + @Override + public ClassEntry getOwnerClassEntry() { + return this.classEntry; + } + + @Override + public String getName() { + return this.name; + } + + public MethodDescriptor getDesc() { + return this.descriptor; + } + + public boolean isConstructor() { + return name.equals("") || name.equals(""); + } + + @Override + public String getClassName() { + return this.classEntry.getName(); + } + + @Override + public MethodEntry updateOwnership(ClassEntry classEntry) { + return new MethodEntry(new ClassEntry(classEntry.getName()), name, descriptor); + } + + @Override + public int hashCode() { + return Utils.combineHashesOrdered(this.classEntry, this.name, this.descriptor); + } + + @Override + public boolean equals(Object other) { + return other instanceof MethodEntry && equals((MethodEntry) other); + } + + public boolean equals(MethodEntry other) { + return this.classEntry.equals(other.getOwnerClassEntry()) && this.name.equals(other.getName()) && this.descriptor.equals(other.getDesc()); + } + + @Override + public String toString() { + return this.classEntry.getName() + "." + this.name + this.descriptor; + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java b/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java new file mode 100644 index 0000000..e42a334 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/ProcyonEntryFactory.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import com.strobel.assembler.metadata.*; +import cuchaz.enigma.bytecode.AccessFlags; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.TypeDescriptor; + +import java.util.List; + +public class ProcyonEntryFactory { + private final ReferencedEntryPool entryPool; + + public ProcyonEntryFactory(ReferencedEntryPool entryPool) { + this.entryPool = entryPool; + } + + private String getErasedSignature(MemberReference def) { + if (!(def instanceof MethodReference)) + return def.getErasedSignature(); + MethodReference methodReference = (MethodReference) def; + StringBuilder builder = new StringBuilder("("); + for (ParameterDefinition param : methodReference.getParameters()) { + TypeReference paramType = param.getParameterType(); + if (paramType.getErasedSignature().equals("Ljava/lang/Object;") && paramType.hasExtendsBound() && paramType.getExtendsBound() instanceof CompoundTypeReference) { + List interfaces = ((CompoundTypeReference) paramType.getExtendsBound()).getInterfaces(); + interfaces.forEach((inter) -> builder.append(inter.getErasedSignature())); + } else + builder.append(paramType.getErasedSignature()); + } + builder.append(")"); + + TypeReference returnType = methodReference.getReturnType(); + if (returnType.getErasedSignature().equals("Ljava/lang/Object;") && returnType.hasExtendsBound() && returnType.getExtendsBound() instanceof CompoundTypeReference) { + List interfaces = ((CompoundTypeReference) returnType.getExtendsBound()).getInterfaces(); + interfaces.forEach((inter) -> builder.append(inter.getErasedSignature())); + } else + builder.append(returnType.getErasedSignature()); + return builder.toString(); + } + + public FieldEntry getFieldEntry(MemberReference def) { + ClassEntry classEntry = entryPool.getClass(def.getDeclaringType().getInternalName()); + return entryPool.getField(classEntry, def.getName(), def.getErasedSignature()); + } + + 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())); + } + + public MethodEntry getMethodEntry(MemberReference def) { + ClassEntry classEntry = entryPool.getClass(def.getDeclaringType().getInternalName()); + return entryPool.getMethod(classEntry, def.getName(), getErasedSignature(def)); + } + + 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())); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/entry/ReferencedEntryPool.java b/src/main/java/cuchaz/enigma/mapping/entry/ReferencedEntryPool.java new file mode 100644 index 0000000..338d209 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/entry/ReferencedEntryPool.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.mapping.entry; + +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.TypeDescriptor; + +import java.util.HashMap; +import java.util.Map; + +public class ReferencedEntryPool { + private final Map classEntries = new HashMap<>(); + private final Map> methodEntries = new HashMap<>(); + private final Map> fieldEntries = new HashMap<>(); + + public ClassEntry getClass(String name) { + return this.classEntries.computeIfAbsent(name, s -> new ClassEntry(name)); + } + + public MethodEntry getMethod(ClassEntry ownerEntry, String name, String desc) { + return getMethod(ownerEntry, name, new MethodDescriptor(desc)); + } + + public MethodEntry getMethod(ClassEntry ownerEntry, String name, MethodDescriptor desc) { + String key = name + desc.toString(); + return getClassMethods(ownerEntry.getName()).computeIfAbsent(key, s -> new MethodEntry(ownerEntry, name, desc)); + } + + public FieldEntry getField(ClassEntry ownerEntry, String name, String desc) { + return getField(ownerEntry, name, new TypeDescriptor(desc)); + } + + public FieldEntry getField(ClassEntry ownerEntry, String name, TypeDescriptor desc) { + return getClassFields(ownerEntry.getName()).computeIfAbsent(name, s -> new FieldEntry(ownerEntry, name, desc)); + } + + private Map getClassMethods(String name) { + return methodEntries.computeIfAbsent(name, s -> new HashMap<>()); + } + + private Map getClassFields(String name) { + return fieldEntries.computeIfAbsent(name, s -> new HashMap<>()); + } +} -- cgit v1.2.3