aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/ftbsc/lll/mapper/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/ftbsc/lll/mapper/data')
-rw-r--r--src/main/java/ftbsc/lll/mapper/data/ClassData.java144
-rw-r--r--src/main/java/ftbsc/lll/mapper/data/FieldData.java55
-rw-r--r--src/main/java/ftbsc/lll/mapper/data/MethodData.java35
-rw-r--r--src/main/java/ftbsc/lll/mapper/data/MethodSignature.java51
4 files changed, 285 insertions, 0 deletions
diff --git a/src/main/java/ftbsc/lll/mapper/data/ClassData.java b/src/main/java/ftbsc/lll/mapper/data/ClassData.java
new file mode 100644
index 0000000..04592fd
--- /dev/null
+++ b/src/main/java/ftbsc/lll/mapper/data/ClassData.java
@@ -0,0 +1,144 @@
+package ftbsc.lll.mapper.data;
+
+import ftbsc.lll.exceptions.MappingNotFoundException;
+import ftbsc.lll.mapper.utils.Mapper;
+import ftbsc.lll.mapper.utils.MappingUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Container class used to store information about classes.
+ */
+public class ClassData {
+
+ /**
+ * The internal (like the fully-qualified name, but with '/' instead
+ * of '.') of the class.
+ */
+ public final String name;
+
+ /**
+ * The mapped internal (like the fully-qualified name, but with '/'
+ * instead of '.') of the class.
+ */
+ public final String nameMapped;
+
+ /**
+ * A {@link Map} tying each method's signature to its data class.
+ */
+ private final Map<MethodSignature, MethodData> methods;
+
+ /**
+ * A {@link Map} tying each field's name to its data class.
+ */
+ private final Map<String, FieldData> fields;
+
+ /**
+ * The constructor. It takes in the names (plain and mapped) of a class.
+ * @param name the plain name
+ * @param nameMapped the mapped name
+ */
+ public ClassData(String name, String nameMapped) {
+ this.name = name;
+ this.nameMapped = nameMapped;
+ this.methods = new HashMap<>();
+ this.fields = new HashMap<>();
+ }
+
+ /**
+ * Adds a method to the target class.
+ * @param name the method name
+ * @param nameMapped the mapped method name
+ * @param descriptor the descriptor of the method
+ */
+ public void addMethod(String name, String nameMapped, String descriptor) {
+ MethodData data = new MethodData(this, name, nameMapped, descriptor);
+ this.methods.put(data.signature, data);
+ }
+
+ /**
+ * Adds a field to the target class.
+ * @param plain the name of the field
+ * @param mapped the mapped name of the field
+ */
+ public void addField(String plain, String mapped) {
+ this.fields.put(plain, new FieldData(this, plain, mapped));
+ }
+
+ /**
+ * Adds a field to the target class.
+ * @param plain the name of the field
+ * @param mapped the mapped name of the field
+ * @param descriptor the plain type descriptor of the field
+ */
+ public void addField(String plain, String mapped, String descriptor) {
+ this.fields.put(plain, new FieldData(this, plain, mapped, descriptor));
+ }
+
+ /**
+ * Generates the reverse mappings for this class.
+ * Should always be called only after the given mapper has finished
+ * processing all classes.
+ * @param mapper the mapper that generated this data
+ * @return a ClassData representing the inverted mappings
+ */
+ public ClassData generateReverseMappings(Mapper mapper) {
+ ClassData reverse = new ClassData(this.nameMapped, this.name);
+ this.methods.forEach((signature, data) -> reverse.addMethod(nameMapped, signature.name,
+ MappingUtils.mapMethodDescriptor(signature.descriptor, mapper, false)));
+ this.fields.forEach((name, data) -> reverse.addField(data.nameMapped, name, data.descriptor));
+ return reverse;
+ }
+
+ /**
+ * Gets the {@link MethodData} from its name and descriptor, which may be partial
+ * (i.e. not include the return type).
+ * @param methodName the method name
+ * @param methodDescriptor the method descriptor, which may be partial
+ * @return the requested {@link MethodData}
+ * @throws MappingNotFoundException if the mapping wasn't found
+ */
+ public MethodData mapMethod(String methodName, String methodDescriptor) {
+ List<MethodSignature> signatures = this.methods.keySet().stream().filter(
+ s -> s.name.equals(methodName) && s.descriptor.startsWith(methodDescriptor)
+ ).collect(Collectors.toList());
+ if(signatures.size() > 1)
+ throw new RuntimeException(); //should never happen unless something goes horribly wrong
+ else if(signatures.isEmpty())
+ throw new MappingNotFoundException("method",
+ String.format("%s::%s%s", this.name, methodName, methodDescriptor));
+ return this.methods.get(signatures.get(0));
+ }
+
+ /**
+ * Gets the {@link FieldData} its name.
+ * @param fieldName the field name
+ * @return the requested {@link FieldData}
+ * @throws MappingNotFoundException if the mapping wasn't found
+ */
+ public FieldData mapField(String fieldName) {
+ FieldData data = this.fields.get(fieldName);
+ if(data == null)
+ throw new MappingNotFoundException("field", String.format("%s.%s", this.name, fieldName));
+ else return data;
+ }
+
+ /**
+ * Gets the underlying {@link Map} for {@link MethodData}.
+ * @return a {@link Map} tying each {@link MethodSignature} to its {@link MethodData}
+ */
+ public Map<MethodSignature, MethodData> getMethods() {
+ return this.methods;
+ }
+
+ /**
+ * Gets the underlying {@link Map} for {@link FieldData}.
+ * @return a {@link Map} tying each field name to its {@link FieldData}
+ */
+ public Map<String, FieldData> getFields() {
+ return this.fields;
+ }
+}
diff --git a/src/main/java/ftbsc/lll/mapper/data/FieldData.java b/src/main/java/ftbsc/lll/mapper/data/FieldData.java
new file mode 100644
index 0000000..3e6cf6c
--- /dev/null
+++ b/src/main/java/ftbsc/lll/mapper/data/FieldData.java
@@ -0,0 +1,55 @@
+package ftbsc.lll.mapper.data;
+
+/**
+ * Container class for method data.
+ */
+public class FieldData {
+ /**
+ * The internal name of the parent class.
+ */
+ public final ClassData parentClass;
+
+ /**
+ * The name of the method.
+ */
+ public final String name;
+
+ /**
+ * The name mapped.
+ */
+ public final String nameMapped;
+
+ /**
+ * The field's type descriptor.
+ * Some formats may not specify it; if this was created in one such format,
+ * this is going to be null.
+ */
+ public final String descriptor;
+
+ /**
+ * Constructs a new {@link FieldData} with unspecified descriptor.
+ * @param parentClass the {@link ClassData} representation of the parent class
+ * @param name the field name
+ * @param nameMapped the mapped field name
+ */
+ public FieldData(ClassData parentClass, String name, String nameMapped) {
+ this.parentClass = parentClass;
+ this.name = name;
+ this.nameMapped = nameMapped;
+ this.descriptor = null;
+ }
+
+ /**
+ * Constructs a new {@link FieldData} with descriptor.
+ * @param parentClass the {@link ClassData} representation of the parent class
+ * @param name the field name
+ * @param nameMapped the mapped field name
+ * @param descriptor the field's type descriptor
+ */
+ public FieldData(ClassData parentClass, String name, String nameMapped, String descriptor) {
+ this.parentClass = parentClass;
+ this.name = name;
+ this.nameMapped = nameMapped;
+ this.descriptor = descriptor;
+ }
+}
diff --git a/src/main/java/ftbsc/lll/mapper/data/MethodData.java b/src/main/java/ftbsc/lll/mapper/data/MethodData.java
new file mode 100644
index 0000000..670ecd2
--- /dev/null
+++ b/src/main/java/ftbsc/lll/mapper/data/MethodData.java
@@ -0,0 +1,35 @@
+package ftbsc.lll.mapper.data;
+
+/**
+ * Container class for method data.
+ */
+public class MethodData {
+
+ /**
+ * The internal name of the parent class.
+ */
+ public final ClassData parentClass;
+
+ /**
+ * The signature of the method.
+ */
+ public final MethodSignature signature;
+
+ /**
+ * The mapped name of the method.
+ */
+ public final String nameMapped;
+
+ /**
+ * Constructs a new {@link MethodData}.
+ * @param parentClass the {@link ClassData} representation of the parent class
+ * @param name the method name
+ * @param nameMapped the mapped method name
+ * @param descriptor the method's descriptor
+ */
+ public MethodData(ClassData parentClass, String name, String nameMapped, String descriptor) {
+ this.parentClass = parentClass;
+ this.signature = new MethodSignature(name, descriptor);
+ this.nameMapped = nameMapped;
+ }
+}
diff --git a/src/main/java/ftbsc/lll/mapper/data/MethodSignature.java b/src/main/java/ftbsc/lll/mapper/data/MethodSignature.java
new file mode 100644
index 0000000..d7515a8
--- /dev/null
+++ b/src/main/java/ftbsc/lll/mapper/data/MethodSignature.java
@@ -0,0 +1,51 @@
+package ftbsc.lll.mapper.data;
+
+import java.util.Objects;
+
+/**
+ * Container class for method signature data.
+ */
+public class MethodSignature {
+ /**
+ * The name of the method.
+ */
+ public final String name;
+
+ /**
+ * The descriptor of the method.
+ */
+ public final String descriptor;
+
+ /**
+ * Constructs a new {@link MethodSignature}. The parameters should be
+ * either plain or obfuscated in the same way;
+ * @param name the method name
+ * @param descriptor the method descriptor
+ */
+ public MethodSignature(String name, String descriptor) {
+ this.name = name;
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * Checks if two {@link MethodSignature}s represent the same method.
+ * @param o the other signature
+ * @return whether they represent the same method
+ */
+ @Override
+ public boolean equals(Object o) {
+ if(this == o) return true;
+ if(o == null || getClass() != o.getClass()) return false;
+ MethodSignature signature = (MethodSignature) o;
+ return Objects.equals(name, signature.name) && Objects.equals(descriptor, signature.descriptor);
+ }
+
+ /**
+ * Calculates a hash based on name and descriptor.
+ * @return the hash code
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, descriptor);
+ }
+}