From 47de69a821c6e089b01187e93f4f916aceeeea85 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 22 Sep 2022 11:59:53 +0200 Subject: Add initial Mapping-IO export support --- .../translation/mapping/serde/MappingFormat.java | 25 ++-- .../mapping/serde/MappingIoConverter.java | 126 +++++++++++++++++++++ 2 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java (limited to 'enigma') diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 367af3b..4790fee 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -21,21 +21,23 @@ import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; import cuchaz.enigma.translation.mapping.tree.EntryTree; public enum MappingFormat { - ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), - ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), - ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), - TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), - TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), - SRG_FILE(SrgMappingsWriter.INSTANCE, null), - PROGUARD(null, ProguardMappingsReader.INSTANCE), - RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE); + ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, null), + ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA), + ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null), + TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2), + TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY), + SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG), + PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD), + RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); private final MappingsWriter writer; private final MappingsReader reader; + private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; - MappingFormat(MappingsWriter writer, MappingsReader reader) { + MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) { this.writer = writer; this.reader = reader; + this.mappingIoCounterpart = mappingIoCounterpart; } public void write(EntryTree mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { @@ -67,4 +69,9 @@ public enum MappingFormat { public MappingsReader getReader() { return reader; } + + @Nullable + public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { + return mappingIoCounterpart; + } } diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java new file mode 100644 index 0000000..3a86476 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -0,0 +1,126 @@ +package cuchaz.enigma.translation.mapping.serde; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +import cuchaz.enigma.translation.mapping.EntryMap; +import cuchaz.enigma.translation.mapping.EntryMapping; +import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; +import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.translation.representation.entry.Entry; +import cuchaz.enigma.translation.representation.entry.FieldEntry; +import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; +import cuchaz.enigma.translation.representation.entry.MethodEntry; + +public class MappingIoConverter { + public static MemoryMappingTree toMappingIo(EntryTree mappings) { + MemoryMappingTree mappingTree = new MemoryMappingTree(); + mappingTree.visitNamespaces("intermediary", List.of("named")); + + for (EntryTreeNode node : mappings) { + if (node.getEntry() instanceof ClassEntry) { + writeClass(node, mappings, mappingTree); + } + } + + mappingTree.visitEnd(); + return mappingTree; + } + + private static void writeClass(EntryTreeNode classNode, EntryMap oldMappingTree, MemoryMappingTree newMappingTree) { + ClassEntry classEntry = (ClassEntry) classNode.getEntry(); + EntryMapping mapping = oldMappingTree.get(classEntry); + Deque parts = new LinkedList<>(); + + newMappingTree.visitClass(classEntry.getFullName()); + newMappingTree.visitComment(MappedElementKind.CLASS, mapping.javadoc()); + + do { + mapping = oldMappingTree.get(classEntry); + + if (mapping != null && mapping.targetName() != null) { + parts.addFirst(mapping.targetName()); + } else { + parts.addFirst(classEntry.getName()); + } + + classEntry = classEntry.getOuterClass(); + } while (classEntry != null); + + String mappedName = String.join("$", parts); + newMappingTree.visitDstName(MappedElementKind.CLASS, 0, mappedName); + + for (EntryTreeNode child : classNode.getChildNodes()) { + Entry entry = child.getEntry(); + + if (entry instanceof FieldEntry) { + writeField(child, newMappingTree); + } else if (entry instanceof MethodEntry) { + writeMethod(child, newMappingTree); + } + } + } + + private static void writeField(EntryTreeNode fieldNode, MemoryMappingTree mappingTree) { + if (fieldNode.getValue() == null || fieldNode.getValue().equals(EntryMapping.DEFAULT)) { + return; // Shortcut + } + + FieldEntry fieldEntry = ((FieldEntry) fieldNode.getEntry()); + mappingTree.visitField(fieldEntry.getName(), fieldEntry.getDesc().toString()); + + EntryMapping fieldMapping = fieldNode.getValue(); + + if (fieldMapping == null) { + fieldMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.FIELD, 0, fieldMapping.targetName()); + mappingTree.visitComment(MappedElementKind.FIELD, fieldMapping.javadoc()); + } + + private static void writeMethod(EntryTreeNode methodNode, MemoryMappingTree mappingTree) { + MethodEntry methodEntry = ((MethodEntry) methodNode.getEntry()); + mappingTree.visitMethod(methodEntry.getName(), methodEntry.getDesc().toString()); + + EntryMapping methodMapping = methodNode.getValue(); + + if (methodMapping == null) { + methodMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.METHOD, 0, methodMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD, methodMapping.javadoc()); + + for (EntryTreeNode child : methodNode.getChildNodes()) { + Entry entry = child.getEntry(); + + if (entry instanceof LocalVariableEntry) { + writeMethodArg(child, mappingTree); + } + } + } + + private static void writeMethodArg(EntryTreeNode methodArgNode, MemoryMappingTree mappingTree) { + if (methodArgNode.getValue() == null || methodArgNode.getValue().equals(EntryMapping.DEFAULT)) { + return; // Shortcut + } + + LocalVariableEntry methodArgEntry = ((LocalVariableEntry) methodArgNode.getEntry()); + mappingTree.visitMethodArg(-1, methodArgEntry.getIndex(), methodArgEntry.getName()); + + EntryMapping methodArgMapping = methodArgNode.getValue(); + + if (methodArgMapping == null) { + methodArgMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, methodArgMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc()); + } +} -- cgit v1.2.3