diff options
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 { | |||
| 19 | dependencies { | 19 | dependencies { |
| 20 | implementation 'com.google.guava:guava:30.1.1-jre' | 20 | implementation 'com.google.guava:guava:30.1.1-jre' |
| 21 | implementation 'com.google.code.gson:gson:2.8.7' | 21 | implementation 'com.google.code.gson:gson:2.8.7' |
| 22 | |||
| 23 | implementation 'net.fabricmc:mapping-io:0.5.0' | 22 | implementation 'net.fabricmc:mapping-io:0.5.0' |
| 23 | |||
| 24 | compileOnly 'org.jetbrains:annotations:24.0.1' | ||
| 24 | 25 | ||
| 25 | testImplementation 'junit:junit:4.13.2' | 26 | testImplementation 'junit:junit:4.13.2' |
| 26 | testImplementation 'org.hamcrest:hamcrest:2.2' | 27 | 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 { | |||
| 58 | protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { | 58 | protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 59 | // Legacy | 59 | // Legacy |
| 60 | if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { | 60 | if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { |
| 61 | return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters); | 61 | return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); | 64 | net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); |
| @@ -66,7 +66,7 @@ public abstract class Command { | |||
| 66 | 66 | ||
| 67 | VisitableMappingTree tree = new MemoryMappingTree(); | 67 | VisitableMappingTree tree = new MemoryMappingTree(); |
| 68 | MappingReader.read(path, format, tree); | 68 | MappingReader.read(path, format, tree); |
| 69 | return MappingIoConverter.fromMappingIo(tree, progress); | 69 | return MappingIoConverter.fromMappingIo(tree, progress, null); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | protected static File getWritableFile(String path) { | 72 | 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 { | |||
| 23 | 23 | ||
| 24 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { | 24 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { |
| 25 | if (type.equals("enigma")) { | 25 | if (type.equals("enigma")) { |
| 26 | return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters); | 26 | return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters, null); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | if (type.equals("tiny")) { | 29 | if (type.equals("tiny")) { |
| 30 | return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters); | 30 | return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters, null); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | MappingFormat format = null; | 33 | MappingFormat format = null; |
| @@ -41,7 +41,7 @@ public final class MappingCommandsUtil { | |||
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | if (format != null) { | 43 | if (format != null) { |
| 44 | return format.read(path, ProgressListener.none(), saveParameters); | 44 | return format.read(path, ProgressListener.none(), saveParameters, null); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | throw new IllegalArgumentException("no reader for " + type); | 47 | 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 { | |||
| 108 | mappingFormat = MappingFormat.ENIGMA_FILE; | 108 | mappingFormat = MappingFormat.ENIGMA_FILE; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters())); | 111 | mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters(), project.getJarIndex())); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile)); | 114 | 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 { | |||
| 154 | return ProgressDialog.runOffThread(gui.getFrame(), progress -> { | 154 | return ProgressDialog.runOffThread(gui.getFrame(), progress -> { |
| 155 | try { | 155 | try { |
| 156 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); | 156 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); |
| 157 | project.setMappings(format.read(path, progress, saveParameters)); | 157 | project.setMappings(format.read(path, progress, saveParameters, project.getJarIndex())); |
| 158 | 158 | ||
| 159 | loadedMappingFormat = format; | 159 | loadedMappingFormat = format; |
| 160 | loadedMappingPath = path; | 160 | 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; | |||
| 15 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | 15 | import net.fabricmc.mappingio.tree.VisitableMappingTree; |
| 16 | 16 | ||
| 17 | import cuchaz.enigma.ProgressListener; | 17 | import cuchaz.enigma.ProgressListener; |
| 18 | import cuchaz.enigma.analysis.index.JarIndex; | ||
| 18 | import cuchaz.enigma.translation.mapping.EntryMapping; | 19 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 19 | import cuchaz.enigma.translation.mapping.MappingDelta; | 20 | import cuchaz.enigma.translation.mapping.MappingDelta; |
| 20 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; | 21 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; |
| @@ -82,7 +83,12 @@ public enum MappingFormat { | |||
| 82 | } | 83 | } |
| 83 | } | 84 | } |
| 84 | 85 | ||
| 86 | @Deprecated | ||
| 85 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { | 87 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 88 | return read(path, progressListener, saveParameters, null); | ||
| 89 | } | ||
| 90 | |||
| 91 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException { | ||
| 86 | if (!useMappingIo()) { | 92 | if (!useMappingIo()) { |
| 87 | if (reader == null) { | 93 | if (reader == null) { |
| 88 | throw new IllegalStateException(name() + " does not support reading"); | 94 | throw new IllegalStateException(name() + " does not support reading"); |
| @@ -103,7 +109,7 @@ public enum MappingFormat { | |||
| 103 | 109 | ||
| 104 | VisitableMappingTree mappingTree = new MemoryMappingTree(); | 110 | VisitableMappingTree mappingTree = new MemoryMappingTree(); |
| 105 | MappingReader.read(path, mappingIoCounterpart, mappingTree); | 111 | MappingReader.read(path, mappingIoCounterpart, mappingTree); |
| 106 | return MappingIoConverter.fromMappingIo(mappingTree, progressListener); | 112 | return MappingIoConverter.fromMappingIo(mappingTree, progressListener, index); |
| 107 | } | 113 | } |
| 108 | 114 | ||
| 109 | @Nullable | 115 | @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; | |||
| 7 | import java.util.List; | 7 | import java.util.List; |
| 8 | import java.util.stream.StreamSupport; | 8 | import java.util.stream.StreamSupport; |
| 9 | 9 | ||
| 10 | import javax.annotation.Nullable; | ||
| 11 | |||
| 12 | import org.jetbrains.annotations.ApiStatus; | ||
| 10 | import net.fabricmc.mappingio.MappedElementKind; | 13 | import net.fabricmc.mappingio.MappedElementKind; |
| 11 | import net.fabricmc.mappingio.tree.MemoryMappingTree; | 14 | import net.fabricmc.mappingio.tree.MemoryMappingTree; |
| 12 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | 15 | import net.fabricmc.mappingio.tree.VisitableMappingTree; |
| @@ -17,6 +20,7 @@ import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; | |||
| 17 | import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; | 20 | import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; |
| 18 | 21 | ||
| 19 | import cuchaz.enigma.ProgressListener; | 22 | import cuchaz.enigma.ProgressListener; |
| 23 | import cuchaz.enigma.analysis.index.JarIndex; | ||
| 20 | import cuchaz.enigma.translation.mapping.EntryMap; | 24 | import cuchaz.enigma.translation.mapping.EntryMap; |
| 21 | import cuchaz.enigma.translation.mapping.EntryMapping; | 25 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 22 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 26 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| @@ -31,6 +35,7 @@ import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | |||
| 31 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 35 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 32 | import cuchaz.enigma.utils.I18n; | 36 | import cuchaz.enigma.utils.I18n; |
| 33 | 37 | ||
| 38 | @ApiStatus.Internal | ||
| 34 | public class MappingIoConverter { | 39 | public class MappingIoConverter { |
| 35 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress) { | 40 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress) { |
| 36 | return toMappingIo(mappings, progress, "intermediary", "named"); | 41 | return toMappingIo(mappings, progress, "intermediary", "named"); |
| @@ -174,20 +179,20 @@ public class MappingIoConverter { | |||
| 174 | mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); | 179 | mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); |
| 175 | } | 180 | } |
| 176 | 181 | ||
| 177 | public static EntryTree<EntryMapping> fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress) { | 182 | public static EntryTree<EntryMapping> fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress, @Nullable JarIndex index) { |
| 178 | EntryTree<EntryMapping> dstMappingTree = new HashEntryTree<>(); | 183 | EntryTree<EntryMapping> dstMappingTree = new HashEntryTree<>(); |
| 179 | progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); | 184 | progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); |
| 180 | int steps = 0; | 185 | int steps = 0; |
| 181 | 186 | ||
| 182 | for (ClassMapping classMapping : mappingTree.getClasses()) { | 187 | for (ClassMapping classMapping : mappingTree.getClasses()) { |
| 183 | progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); | 188 | progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); |
| 184 | readClass(classMapping, dstMappingTree); | 189 | readClass(classMapping, dstMappingTree, index); |
| 185 | } | 190 | } |
| 186 | 191 | ||
| 187 | return dstMappingTree; | 192 | return dstMappingTree; |
| 188 | } | 193 | } |
| 189 | 194 | ||
| 190 | private static void readClass(ClassMapping classMapping, EntryTree<EntryMapping> mappingTree) { | 195 | private static void readClass(ClassMapping classMapping, EntryTree<EntryMapping> mappingTree, JarIndex index) { |
| 191 | ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); | 196 | ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); |
| 192 | String dstName = classMapping.getDstName(0); | 197 | String dstName = classMapping.getDstName(0); |
| 193 | 198 | ||
| @@ -198,7 +203,7 @@ public class MappingIoConverter { | |||
| 198 | mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); | 203 | mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); |
| 199 | 204 | ||
| 200 | for (FieldMapping fieldMapping : classMapping.getFields()) { | 205 | for (FieldMapping fieldMapping : classMapping.getFields()) { |
| 201 | readField(fieldMapping, currentClass, mappingTree); | 206 | readField(fieldMapping, currentClass, mappingTree, index); |
| 202 | } | 207 | } |
| 203 | 208 | ||
| 204 | for (MethodMapping methodMapping : classMapping.getMethods()) { | 209 | for (MethodMapping methodMapping : classMapping.getMethods()) { |
| @@ -206,9 +211,40 @@ public class MappingIoConverter { | |||
| 206 | } | 211 | } |
| 207 | } | 212 | } |
| 208 | 213 | ||
| 209 | private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree<EntryMapping> mappingTree) { | 214 | private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree<EntryMapping> mappingTree, JarIndex index) { |
| 210 | mappingTree.insert(new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())), | 215 | String srcDesc = fieldMapping.getSrcDesc(); |
| 211 | new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); | 216 | FieldEntry[] fieldEntries; |
| 217 | |||
| 218 | if (srcDesc != null) { | ||
| 219 | fieldEntries = new FieldEntry[] { new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())) }; | ||
| 220 | } else { | ||
| 221 | if (index == null) return; // Enigma requires source descriptors, and without an index we can't look them up | ||
| 222 | |||
| 223 | fieldEntries = index.getChildrenByClass().get(parent).stream() | ||
| 224 | .filter(entry -> entry instanceof FieldEntry) | ||
| 225 | .filter(entry -> entry.getName().equals(fieldMapping.getSrcName())) | ||
| 226 | .toArray(FieldEntry[]::new); | ||
| 227 | |||
| 228 | if (fieldEntries.length == 0) { // slow path for synthetics | ||
| 229 | fieldEntries = index.getEntryIndex().getFields().stream() | ||
| 230 | .filter(entry -> entry.getParent().getFullName().equals(parent.getFullName())) | ||
| 231 | .filter(entry -> { | ||
| 232 | if (entry.getName().equals(fieldMapping.getSrcName())) { | ||
| 233 | return true; | ||
| 234 | } else { | ||
| 235 | System.out.println("Entry name: " + entry.getName() + ", mapping name: " + fieldMapping.getSrcName()); | ||
| 236 | return false; | ||
| 237 | } | ||
| 238 | }) | ||
| 239 | .toArray(FieldEntry[]::new); | ||
| 240 | } | ||
| 241 | |||
| 242 | if (fieldEntries.length == 0) return; // No target found, invalid mapping | ||
| 243 | } | ||
| 244 | |||
| 245 | for (FieldEntry fieldEntry : fieldEntries) { | ||
| 246 | mappingTree.insert(fieldEntry, new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); | ||
| 247 | } | ||
| 212 | } | 248 | } |
| 213 | 249 | ||
| 214 | private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree<EntryMapping> mappingTree) { | 250 | private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree<EntryMapping> 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 { | |||
| 63 | mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); | 63 | mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); |
| 64 | Assert.assertTrue("Written file not created", tempFile.exists()); | 64 | Assert.assertTrue("Written file not created", tempFile.exists()); |
| 65 | 65 | ||
| 66 | EntryTree<EntryMapping> loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters); | 66 | EntryTree<EntryMapping> loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters, null); |
| 67 | 67 | ||
| 68 | Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); | 68 | Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); |
| 69 | Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); | 69 | Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); |