From 423f5cf98c6d419942301cca0c7c8169db8d4b30 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 13:51:03 +0100 Subject: Fix importing mappings without field source descriptors --- build.gradle | 3 +- .../main/java/cuchaz/enigma/command/Command.java | 4 +- .../cuchaz/enigma/command/MappingCommandsUtil.java | 6 +-- .../enigma/network/DedicatedEnigmaServer.java | 2 +- .../main/java/cuchaz/enigma/gui/GuiController.java | 2 +- .../translation/mapping/serde/MappingFormat.java | 8 +++- .../mapping/serde/MappingIoConverter.java | 50 +++++++++++++++++++--- .../translation/mapping/TestReadWriteCycle.java | 2 +- 8 files changed, 60 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index 3b90781a..8cbe0cd6 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,9 @@ subprojects { dependencies { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' - implementation 'net.fabricmc:mapping-io:0.5.0' + + compileOnly 'org.jetbrains:annotations:24.0.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java index ef7cfaa5..de06fa6e 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java @@ -58,7 +58,7 @@ public abstract class Command { protected static EntryTree readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { // Legacy if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { - return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters); + return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null); } net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); @@ -66,7 +66,7 @@ public abstract class Command { VisitableMappingTree tree = new MemoryMappingTree(); MappingReader.read(path, format, tree); - return MappingIoConverter.fromMappingIo(tree, progress); + return MappingIoConverter.fromMappingIo(tree, progress, null); } protected static File getWritableFile(String path) { diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index c452d8ca..2c6c9fdb 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java @@ -23,11 +23,11 @@ public final class MappingCommandsUtil { public static EntryTree read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { if (type.equals("enigma")) { - return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters); + return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters, null); } if (type.equals("tiny")) { - return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters); + return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters, null); } MappingFormat format = null; @@ -41,7 +41,7 @@ public final class MappingCommandsUtil { } if (format != null) { - return format.read(path, ProgressListener.none(), saveParameters); + return format.read(path, ProgressListener.none(), saveParameters, null); } throw new IllegalArgumentException("no reader for " + type); diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java index eb22a506..fbee40d0 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java @@ -108,7 +108,7 @@ public class DedicatedEnigmaServer extends EnigmaServer { mappingFormat = MappingFormat.ENIGMA_FILE; } - mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters())); + mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters(), project.getJarIndex())); } PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile)); diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java index 88dc070d..6eab0f86 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -154,7 +154,7 @@ public class GuiController implements ClientPacketHandler { return ProgressDialog.runOffThread(gui.getFrame(), progress -> { try { MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); - project.setMappings(format.read(path, progress, saveParameters)); + project.setMappings(format.read(path, progress, saveParameters, project.getJarIndex())); loadedMappingFormat = format; loadedMappingPath = path; 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 bbbf3697..530aff40 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 @@ -15,6 +15,7 @@ import net.fabricmc.mappingio.tree.VisitOrder; import net.fabricmc.mappingio.tree.VisitableMappingTree; import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.analysis.index.JarIndex; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.MappingDelta; import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; @@ -82,7 +83,12 @@ public enum MappingFormat { } } + @Deprecated public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { + return read(path, progressListener, saveParameters, null); + } + + public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException { if (!useMappingIo()) { if (reader == null) { throw new IllegalStateException(name() + " does not support reading"); @@ -103,7 +109,7 @@ public enum MappingFormat { VisitableMappingTree mappingTree = new MemoryMappingTree(); MappingReader.read(path, mappingIoCounterpart, mappingTree); - return MappingIoConverter.fromMappingIo(mappingTree, progressListener); + return MappingIoConverter.fromMappingIo(mappingTree, progressListener, index); } @Nullable 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 index 43725851..3843d8e4 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -7,6 +7,9 @@ import java.util.LinkedList; import java.util.List; import java.util.stream.StreamSupport; +import javax.annotation.Nullable; + +import org.jetbrains.annotations.ApiStatus; import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.mappingio.tree.VisitableMappingTree; @@ -17,6 +20,7 @@ import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.analysis.index.JarIndex; import cuchaz.enigma.translation.mapping.EntryMap; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; @@ -31,6 +35,7 @@ import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; import cuchaz.enigma.utils.I18n; +@ApiStatus.Internal public class MappingIoConverter { public static VisitableMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { return toMappingIo(mappings, progress, "intermediary", "named"); @@ -174,20 +179,20 @@ public class MappingIoConverter { mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); } - public static EntryTree fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress) { + public static EntryTree fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress, @Nullable JarIndex index) { EntryTree dstMappingTree = new HashEntryTree<>(); progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); int steps = 0; for (ClassMapping classMapping : mappingTree.getClasses()) { progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); - readClass(classMapping, dstMappingTree); + readClass(classMapping, dstMappingTree, index); } return dstMappingTree; } - private static void readClass(ClassMapping classMapping, EntryTree mappingTree) { + private static void readClass(ClassMapping classMapping, EntryTree mappingTree, JarIndex index) { ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); String dstName = classMapping.getDstName(0); @@ -198,7 +203,7 @@ public class MappingIoConverter { mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); for (FieldMapping fieldMapping : classMapping.getFields()) { - readField(fieldMapping, currentClass, mappingTree); + readField(fieldMapping, currentClass, mappingTree, index); } for (MethodMapping methodMapping : classMapping.getMethods()) { @@ -206,9 +211,40 @@ public class MappingIoConverter { } } - private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree) { - mappingTree.insert(new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())), - new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); + private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree, JarIndex index) { + String srcDesc = fieldMapping.getSrcDesc(); + FieldEntry[] fieldEntries; + + if (srcDesc != null) { + fieldEntries = new FieldEntry[] { new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())) }; + } else { + if (index == null) return; // Enigma requires source descriptors, and without an index we can't look them up + + fieldEntries = index.getChildrenByClass().get(parent).stream() + .filter(entry -> entry instanceof FieldEntry) + .filter(entry -> entry.getName().equals(fieldMapping.getSrcName())) + .toArray(FieldEntry[]::new); + + if (fieldEntries.length == 0) { // slow path for synthetics + fieldEntries = index.getEntryIndex().getFields().stream() + .filter(entry -> entry.getParent().getFullName().equals(parent.getFullName())) + .filter(entry -> { + if (entry.getName().equals(fieldMapping.getSrcName())) { + return true; + } else { + System.out.println("Entry name: " + entry.getName() + ", mapping name: " + fieldMapping.getSrcName()); + return false; + } + }) + .toArray(FieldEntry[]::new); + } + + if (fieldEntries.length == 0) return; // No target found, invalid mapping + } + + for (FieldEntry fieldEntry : fieldEntries) { + mappingTree.insert(fieldEntry, new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); + } } private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree mappingTree) { diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java index 34d5a6ea..25f11fbc 100644 --- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java +++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java @@ -63,7 +63,7 @@ public class TestReadWriteCycle { mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); Assert.assertTrue("Written file not created", tempFile.exists()); - EntryTree loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters); + EntryTree loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters, null); Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); -- cgit v1.2.3