summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/Command.java7
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java14
-rw-r--r--enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java3
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java13
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java3
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java50
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java106
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java31
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java12
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java16
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java30
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java361
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java44
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/proguard/ProguardMappingsReader.java137
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java64
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java77
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java119
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java117
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java144
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java332
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java187
-rw-r--r--enigma/src/main/resources/lang/en_us.json1
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestComments.java37
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java5
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java37
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestV2Main.java23
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java45
-rw-r--r--enigma/src/test/resources/comments/test.mapping18
-rw-r--r--enigma/src/test/resources/recaf.mappings10
-rw-r--r--enigma/src/test/resources/tinyV2InnerClasses/c.mapping2
-rw-r--r--enigma/src/test/resources/tinyV2InnerClasses/cuchaz/enigma/Dad.mapping5
31 files changed, 34 insertions, 2016 deletions
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 7f42f3aa..30afb2c2 100644
--- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java
+++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java
@@ -7,7 +7,6 @@ import java.nio.file.Path;
7import java.nio.file.Paths; 7import java.nio.file.Paths;
8import java.util.ArrayList; 8import java.util.ArrayList;
9import java.util.List; 9import java.util.List;
10import java.util.Locale;
11 10
12import net.fabricmc.mappingio.MappingReader; 11import net.fabricmc.mappingio.MappingReader;
13import net.fabricmc.mappingio.tree.MemoryMappingTree; 12import net.fabricmc.mappingio.tree.MemoryMappingTree;
@@ -17,7 +16,6 @@ import cuchaz.enigma.Enigma;
17import cuchaz.enigma.EnigmaProject; 16import cuchaz.enigma.EnigmaProject;
18import cuchaz.enigma.ProgressListener; 17import cuchaz.enigma.ProgressListener;
19import cuchaz.enigma.translation.mapping.EntryMapping; 18import cuchaz.enigma.translation.mapping.EntryMapping;
20import cuchaz.enigma.translation.mapping.serde.MappingFormat;
21import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; 19import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
22import cuchaz.enigma.translation.mapping.serde.MappingParseException; 20import cuchaz.enigma.translation.mapping.serde.MappingParseException;
23import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 21import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
@@ -57,11 +55,6 @@ public abstract class Command {
57 } 55 }
58 56
59 protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { 57 protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
60 // Legacy
61 if (path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".zip")) {
62 return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null);
63 }
64
65 net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); 58 net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path);
66 if (format == null) throw new IllegalArgumentException("Unknown mapping format!"); 59 if (format == null) throw new IllegalArgumentException("Unknown mapping format!");
67 60
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 7c6bf436..1bd72ac4 100644
--- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
+++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
@@ -15,8 +15,6 @@ import cuchaz.enigma.translation.mapping.serde.MappingFormat;
15import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; 15import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
16import cuchaz.enigma.translation.mapping.serde.MappingParseException; 16import cuchaz.enigma.translation.mapping.serde.MappingParseException;
17import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 17import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
18import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter;
19import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
20import cuchaz.enigma.translation.mapping.tree.EntryTree; 18import cuchaz.enigma.translation.mapping.tree.EntryTree;
21 19
22public final class MappingCommandsUtil { 20public final class MappingCommandsUtil {
@@ -25,7 +23,7 @@ public final class MappingCommandsUtil {
25 23
26 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 {
27 if (type.equals("enigma")) { 25 if (type.equals("enigma")) {
28 return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters, null); 26 return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_FILE).read(path, ProgressListener.none(), saveParameters, null);
29 } 27 }
30 28
31 if (type.equals("tiny")) { 29 if (type.equals("tiny")) {
@@ -62,11 +60,6 @@ public final class MappingCommandsUtil {
62 throw new IllegalArgumentException("specify column names as 'tinyv2:from_namespace:to_namespace'"); 60 throw new IllegalArgumentException("specify column names as 'tinyv2:from_namespace:to_namespace'");
63 } 61 }
64 62
65 if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) {
66 new TinyV2Writer(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
67 return;
68 }
69
70 try { 63 try {
71 VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); 64 VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]);
72 tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE)); 65 tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE));
@@ -84,11 +77,6 @@ public final class MappingCommandsUtil {
84 throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'"); 77 throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'");
85 } 78 }
86 79
87 if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) {
88 new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
89 return;
90 }
91
92 try { 80 try {
93 VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); 81 VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]);
94 tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE)); 82 tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE));
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 24fd9ff3..f7112cff 100644
--- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java
+++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java
@@ -6,7 +6,6 @@ import java.nio.file.Files;
6import java.nio.file.Path; 6import java.nio.file.Path;
7import java.nio.file.Paths; 7import java.nio.file.Paths;
8import java.util.List; 8import java.util.List;
9import java.util.Locale;
10import java.util.concurrent.BlockingQueue; 9import java.util.concurrent.BlockingQueue;
11import java.util.concurrent.Executors; 10import java.util.concurrent.Executors;
12import java.util.concurrent.LinkedBlockingDeque; 11import java.util.concurrent.LinkedBlockingDeque;
@@ -104,8 +103,6 @@ public class DedicatedEnigmaServer extends EnigmaServer {
104 103
105 if (Files.isDirectory(mappingsFile)) { 104 if (Files.isDirectory(mappingsFile)) {
106 mappingFormat = MappingFormat.ENIGMA_DIRECTORY; 105 mappingFormat = MappingFormat.ENIGMA_DIRECTORY;
107 } else if (mappingsFile.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".zip")) {
108 mappingFormat = MappingFormat.ENIGMA_ZIP;
109 } else { 106 } else {
110 mappingFormat = MappingFormat.ENIGMA_FILE; 107 mappingFormat = MappingFormat.ENIGMA_FILE;
111 } 108 }
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 1853a9fc..a2b3bd9d 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -31,7 +31,6 @@ import javax.swing.JFrame;
31import javax.swing.JOptionPane; 31import javax.swing.JOptionPane;
32import javax.swing.SwingUtilities; 32import javax.swing.SwingUtilities;
33 33
34import org.jetbrains.annotations.ApiStatus;
35import org.jetbrains.annotations.Nullable; 34import org.jetbrains.annotations.Nullable;
36 35
37import cuchaz.enigma.Enigma; 36import cuchaz.enigma.Enigma;
@@ -172,12 +171,6 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida
172 this.gui.onCloseJar(); 171 this.gui.onCloseJar();
173 } 172 }
174 173
175 @ApiStatus.Internal
176 public CompletableFuture<Void> openMappings(MappingFormat format, Path path, boolean useMappingIo) {
177 System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false");
178 return openMappings(format, path);
179 }
180
181 public CompletableFuture<Void> openMappings(MappingFormat format, Path path) { 174 public CompletableFuture<Void> openMappings(MappingFormat format, Path path) {
182 if (project == null) { 175 if (project == null) {
183 return CompletableFuture.completedFuture(null); 176 return CompletableFuture.completedFuture(null);
@@ -220,12 +213,6 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida
220 return saveMappings(path, loadedMappingFormat); 213 return saveMappings(path, loadedMappingFormat);
221 } 214 }
222 215
223 @ApiStatus.Internal
224 public CompletableFuture<Void> saveMappings(Path path, MappingFormat format, boolean useMappingIo) {
225 System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false");
226 return saveMappings(path, format);
227 }
228
229 /** 216 /**
230 * Saves the mappings, with a dialog popping up, showing the progress. 217 * Saves the mappings, with a dialog popping up, showing the progress.
231 * 218 *
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
index b9ad19e8..0ed500e3 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
@@ -18,7 +18,6 @@ import java.nio.file.Path;
18import java.nio.file.Paths; 18import java.nio.file.Paths;
19import java.util.EnumSet; 19import java.util.EnumSet;
20import java.util.List; 20import java.util.List;
21import java.util.Locale;
22import java.util.Set; 21import java.util.Set;
23 22
24import joptsimple.OptionException; 23import joptsimple.OptionException;
@@ -148,8 +147,6 @@ public class Main {
148 147
149 if (Files.isDirectory(mappingsPath)) { 148 if (Files.isDirectory(mappingsPath)) {
150 controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath); 149 controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath);
151 } else if (mappingsPath.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".zip")) {
152 controller.openMappings(MappingFormat.ENIGMA_ZIP, mappingsPath);
153 } else { 150 } else {
154 controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath); 151 controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath);
155 } 152 }
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
index 02fa9e36..e8917864 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
@@ -405,28 +405,13 @@ public class MenuBar {
405 } 405 }
406 406
407 private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) { 407 private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) {
408 // Mapping-IO readers 408 for (MappingFormat format : MappingFormat.getReadableFormats()) {
409 for (MappingFormat format : MappingFormat.values()) { 409 addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)),
410 if (format.getMappingIoCounterpart() != null) { 410 format, openMappingsMenu, gui);
411 addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)),
412 format, true, openMappingsMenu, gui);
413 }
414 }
415
416 openMappingsMenu.addSeparator();
417
418 // Enigma's own readers
419 String legacySuffix = " (" + I18n.translate("legacy") + ")";
420
421 for (MappingFormat format : MappingFormat.values()) {
422 if (format.getReader() != null) {
423 addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + legacySuffix,
424 format, false, openMappingsMenu, gui);
425 }
426 } 411 }
427 } 412 }
428 413
429 private static void addOpenMappingsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu openMappingsMenu, Gui gui) { 414 private static void addOpenMappingsMenuEntry(String text, MappingFormat format, JMenu openMappingsMenu, Gui gui) {
430 JMenuItem item = new JMenuItem(text); 415 JMenuItem item = new JMenuItem(text);
431 item.addActionListener(event -> { 416 item.addActionListener(event -> {
432 ExtensionFileFilter.setupFileChooser(gui.mappingsFileChooser, format); 417 ExtensionFileFilter.setupFileChooser(gui.mappingsFileChooser, format);
@@ -434,7 +419,7 @@ public class MenuBar {
434 419
435 if (gui.mappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 420 if (gui.mappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
436 File selectedFile = gui.mappingsFileChooser.getSelectedFile(); 421 File selectedFile = gui.mappingsFileChooser.getSelectedFile();
437 gui.getController().openMappings(format, selectedFile.toPath(), mappingIo); 422 gui.getController().openMappings(format, selectedFile.toPath());
438 UiConfig.setLastSelectedDir(gui.mappingsFileChooser.getCurrentDirectory().toString()); 423 UiConfig.setLastSelectedDir(gui.mappingsFileChooser.getCurrentDirectory().toString());
439 } 424 }
440 }); 425 });
@@ -442,28 +427,13 @@ public class MenuBar {
442 } 427 }
443 428
444 private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { 429 private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) {
445 // Mapping-IO writers 430 for (MappingFormat format : MappingFormat.getWritableFormats()) {
446 for (MappingFormat format : MappingFormat.values()) { 431 addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)),
447 if (format.hasMappingIoWriter()) { 432 format, saveMappingsAsMenu, saveMappingsItem, gui);
448 addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)),
449 format, true, saveMappingsAsMenu, saveMappingsItem, gui);
450 }
451 }
452
453 saveMappingsAsMenu.addSeparator();
454
455 // Enigma's own writers
456 String legacySuffix = " (" + I18n.translate("legacy") + ")";
457
458 for (MappingFormat format : MappingFormat.values()) {
459 if (format.getWriter() != null) {
460 addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + legacySuffix,
461 format, false, saveMappingsAsMenu, saveMappingsItem, gui);
462 }
463 } 433 }
464 } 434 }
465 435
466 private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { 436 private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format, JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) {
467 JMenuItem item = new JMenuItem(text); 437 JMenuItem item = new JMenuItem(text);
468 item.addActionListener(event -> { 438 item.addActionListener(event -> {
469 JFileChooser fileChooser = gui.mappingsFileChooser; 439 JFileChooser fileChooser = gui.mappingsFileChooser;
@@ -475,7 +445,7 @@ public class MenuBar {
475 445
476 if (fileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 446 if (fileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
477 Path savePath = ExtensionFileFilter.getSavePath(fileChooser); 447 Path savePath = ExtensionFileFilter.getSavePath(fileChooser);
478 gui.getController().saveMappings(savePath, format, mappingIo); 448 gui.getController().saveMappings(savePath, format);
479 saveMappingsItem.setEnabled(true); 449 saveMappingsItem.setEnabled(true);
480 UiConfig.setLastSelectedDir(fileChooser.getCurrentDirectory().toString()); 450 UiConfig.setLastSelectedDir(fileChooser.getCurrentDirectory().toString());
481 } 451 }
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 ec36d47d..b891f438 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
@@ -5,6 +5,7 @@ import java.io.UncheckedIOException;
5import java.nio.file.Path; 5import java.nio.file.Path;
6import java.util.Arrays; 6import java.util.Arrays;
7import java.util.List; 7import java.util.List;
8import java.util.Objects;
8 9
9import net.fabricmc.mappingio.MappingReader; 10import net.fabricmc.mappingio.MappingReader;
10import net.fabricmc.mappingio.MappingWriter; 11import net.fabricmc.mappingio.MappingWriter;
@@ -12,56 +13,39 @@ import net.fabricmc.mappingio.tree.MemoryMappingTree;
12import net.fabricmc.mappingio.tree.VisitOrder; 13import net.fabricmc.mappingio.tree.VisitOrder;
13import net.fabricmc.mappingio.tree.VisitableMappingTree; 14import net.fabricmc.mappingio.tree.VisitableMappingTree;
14import org.jetbrains.annotations.ApiStatus; 15import org.jetbrains.annotations.ApiStatus;
15import org.jetbrains.annotations.Nullable;
16 16
17import cuchaz.enigma.ProgressListener; 17import cuchaz.enigma.ProgressListener;
18import cuchaz.enigma.analysis.index.JarIndex; 18import cuchaz.enigma.analysis.index.JarIndex;
19import cuchaz.enigma.translation.mapping.EntryMapping; 19import cuchaz.enigma.translation.mapping.EntryMapping;
20import cuchaz.enigma.translation.mapping.MappingDelta; 20import cuchaz.enigma.translation.mapping.MappingDelta;
21import cuchaz.enigma.translation.mapping.MappingOperations; 21import cuchaz.enigma.translation.mapping.MappingOperations;
22import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
23import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter; 22import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter;
24import cuchaz.enigma.translation.mapping.serde.proguard.ProguardMappingsReader;
25import cuchaz.enigma.translation.mapping.serde.recaf.RecafMappingsReader;
26import cuchaz.enigma.translation.mapping.serde.recaf.RecafMappingsWriter;
27import cuchaz.enigma.translation.mapping.serde.srg.SrgMappingsWriter;
28import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsReader;
29import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter;
30import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader;
31import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
32import cuchaz.enigma.translation.mapping.tree.EntryTree; 23import cuchaz.enigma.translation.mapping.tree.EntryTree;
33import cuchaz.enigma.utils.I18n; 24import cuchaz.enigma.utils.I18n;
34 25
35public enum MappingFormat { 26public enum MappingFormat {
36 ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, FileType.MAPPING, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE), 27 ENIGMA_FILE(FileType.MAPPING, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE),
37 ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, FileType.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR), 28 ENIGMA_DIRECTORY(FileType.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR),
38 ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, FileType.ZIP, null), 29 TINY_V2(FileType.TINY, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE),
39 TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), FileType.TINY, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE), 30 TINY_FILE(FileType.TINY, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE),
40 TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, FileType.TINY, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE), 31 SRG_FILE(FileType.SRG, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE),
41 SRG_FILE(SrgMappingsWriter.INSTANCE, null, FileType.SRG, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE), 32 XSRG_FILE(FileType.XSRG, net.fabricmc.mappingio.format.MappingFormat.XSRG_FILE),
42 XSRG_FILE(null, null, FileType.XSRG, net.fabricmc.mappingio.format.MappingFormat.XSRG_FILE), 33 JAM_FILE(FileType.JAM, net.fabricmc.mappingio.format.MappingFormat.JAM_FILE),
43 JAM_FILE(null, null, FileType.JAM, net.fabricmc.mappingio.format.MappingFormat.JAM_FILE), 34 CSRG_FILE(FileType.CSRG, net.fabricmc.mappingio.format.MappingFormat.CSRG_FILE),
44 CSRG_FILE(null, null, FileType.CSRG, net.fabricmc.mappingio.format.MappingFormat.CSRG_FILE), 35 TSRG_FILE(FileType.TSRG, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE),
45 TSRG_FILE(null, null, FileType.TSRG, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE), 36 TSRG_2_FILE(FileType.TSRG, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE),
46 TSRG_2_FILE(null, null, FileType.TSRG, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE), 37 PROGUARD(FileType.TXT, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE),
47 PROGUARD(null, ProguardMappingsReader.INSTANCE, FileType.TXT, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE), 38 RECAF(FileType.TXT, net.fabricmc.mappingio.format.MappingFormat.RECAF_SIMPLE_FILE),
48 RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, FileType.TXT, net.fabricmc.mappingio.format.MappingFormat.RECAF_SIMPLE_FILE), 39 JOBF_FILE(FileType.JOBF, net.fabricmc.mappingio.format.MappingFormat.JOBF_FILE),
49 JOBF_FILE(null, null, FileType.JOBF, net.fabricmc.mappingio.format.MappingFormat.JOBF_FILE), 40 INTELLIJ_MIGRATION_MAP_FILE(FileType.XML, net.fabricmc.mappingio.format.MappingFormat.INTELLIJ_MIGRATION_MAP_FILE);
50 INTELLIJ_MIGRATION_MAP_FILE(null, null, FileType.XML, net.fabricmc.mappingio.format.MappingFormat.INTELLIJ_MIGRATION_MAP_FILE); 41
51
52 private final MappingsWriter writer;
53 private final MappingsReader reader;
54 private final FileType fileType; 42 private final FileType fileType;
55 private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; 43 private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart;
56 private final boolean hasMappingIoWriter;
57 private boolean usedMappingIoWriterLast; 44 private boolean usedMappingIoWriterLast;
58 45
59 MappingFormat(MappingsWriter writer, MappingsReader reader, FileType fileType, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) { 46 MappingFormat(FileType fileType, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) {
60 this.writer = writer;
61 this.reader = reader;
62 this.fileType = fileType; 47 this.fileType = fileType;
63 this.mappingIoCounterpart = mappingIoCounterpart; 48 this.mappingIoCounterpart = Objects.requireNonNull(mappingIoCounterpart);
64 this.hasMappingIoWriter = mappingIoCounterpart == null ? false : mappingIoCounterpart.hasWriter;
65 } 49 }
66 50
67 public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { 51 public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) {
@@ -69,10 +53,8 @@ public enum MappingFormat {
69 } 53 }
70 54
71 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { 55 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) {
72 if (!hasMappingIoWriter || (!useMappingIo() && writer != null)) { 56 if (!isWritable()) {
73 writer.write(mappings, usedMappingIoWriterLast ? MappingDelta.added(mappings) : delta, path, progressListener, saveParameters); 57 throw new UnsupportedOperationException("Mapping format " + this + " does not support writing");
74 usedMappingIoWriterLast = false;
75 return;
76 } 58 }
77 59
78 try { 60 try {
@@ -103,10 +85,6 @@ public enum MappingFormat {
103 } 85 }
104 86
105 public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException { 87 public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException {
106 if (mappingIoCounterpart == null || (!useMappingIo() && reader != null)) {
107 return reader.read(path, progressListener, saveParameters);
108 }
109
110 String loadingMessage; 88 String loadingMessage;
111 89
112 if (mappingIoCounterpart.hasSingleFile()) { 90 if (mappingIoCounterpart.hasSingleFile()) {
@@ -124,56 +102,17 @@ public enum MappingFormat {
124 return this == PROGUARD ? MappingOperations.invert(mappings) : mappings; 102 return this == PROGUARD ? MappingOperations.invert(mappings) : mappings;
125 } 103 }
126 104
127 /**
128 * @return Enigma's native writer for the format, or {@code null} if none exists.
129 *
130 * @deprecated Use {@link #isWritable()} and {@link #write(EntryTree, Path, ProgressListener, MappingSaveParameters)} instead,
131 * which take the new Mapping-IO equivalents (and eventual replacements) into account.
132 */
133 @Nullable
134 @Deprecated
135 public MappingsWriter getWriter() {
136 return writer;
137 }
138
139 /**
140 * @return Enigma's native reader for the format, or {@code null} if none exists.
141 *
142 * @deprecated Use {@link #isReadable()} and {@link #read(Path, ProgressListener, MappingSaveParameters, JarIndex)} instead,
143 * which take the new Mapping-IO equivalents (and eventual replacements) into account.
144 */
145 @Nullable
146 @Deprecated
147 public MappingsReader getReader() {
148 return reader;
149 }
150
151 @ApiStatus.Internal 105 @ApiStatus.Internal
152 public FileType getFileType() { 106 public FileType getFileType() {
153 return fileType; 107 return fileType;
154 } 108 }
155 109
156 @Nullable
157 @ApiStatus.Internal
158 public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() {
159 return mappingIoCounterpart;
160 }
161
162 @ApiStatus.Internal
163 public boolean hasMappingIoWriter() {
164 return hasMappingIoWriter;
165 }
166
167 public boolean isReadable() { 110 public boolean isReadable() {
168 return reader != null || mappingIoCounterpart != null; 111 return true;
169 } 112 }
170 113
171 public boolean isWritable() { 114 public boolean isWritable() {
172 return writer != null || hasMappingIoWriter; 115 return mappingIoCounterpart.hasWriter;
173 }
174
175 private boolean useMappingIo() {
176 return System.getProperty("enigma.use_mappingio", "true").equals("true");
177 } 116 }
178 117
179 public static List<MappingFormat> getReadableFormats() { 118 public static List<MappingFormat> getReadableFormats() {
@@ -199,7 +138,6 @@ public enum MappingFormat {
199 @ApiStatus.Internal 138 @ApiStatus.Internal
200 public record FileType(List<String> extensions) { 139 public record FileType(List<String> extensions) {
201 public static final FileType DIRECTORY = new FileType(); 140 public static final FileType DIRECTORY = new FileType();
202 public static final FileType ZIP = new FileType(".zip");
203 public static final FileType MAPPING = new FileType(".mapping", ".mappings"); 141 public static final FileType MAPPING = new FileType(".mapping", ".mappings");
204 public static final FileType TINY = new FileType(".tiny"); 142 public static final FileType TINY = new FileType(".tiny");
205 public static final FileType SRG = new FileType(".srg"); 143 public static final FileType SRG = new FileType(".srg");
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java
index 5f466bba..d89205c5 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java
@@ -21,37 +21,6 @@ public final class MappingHelper {
21 return builder.toString(); 21 return builder.toString();
22 } 22 }
23 23
24 public static String unescape(String str) {
25 int pos = str.indexOf('\\');
26
27 if (pos < 0) {
28 return str;
29 }
30
31 StringBuilder ret = new StringBuilder(str.length() - 1);
32 int start = 0;
33
34 do {
35 ret.append(str, start, pos);
36 pos++;
37 int type;
38
39 if (pos >= str.length()) {
40 throw new RuntimeException("incomplete escape sequence at the end");
41 } else if ((type = ESCAPED.indexOf(str.charAt(pos))) < 0) {
42 throw new RuntimeException("invalid escape character: \\" + str.charAt(pos));
43 } else {
44 ret.append(TO_ESCAPE.charAt(type));
45 }
46
47 start = pos + 1;
48 } while ((pos = str.indexOf('\\', start)) >= 0);
49
50 ret.append(str, start, str.length());
51
52 return ret.toString();
53 }
54
55 private MappingHelper() { 24 private MappingHelper() {
56 } 25 }
57} 26}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java
deleted file mode 100644
index 4fdfdcba..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java
+++ /dev/null
@@ -1,12 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde;
2
3import java.io.IOException;
4import java.nio.file.Path;
5
6import cuchaz.enigma.ProgressListener;
7import cuchaz.enigma.translation.mapping.EntryMapping;
8import cuchaz.enigma.translation.mapping.tree.EntryTree;
9
10public interface MappingsReader {
11 EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException;
12}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java
deleted file mode 100644
index 5c273ad3..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java
+++ /dev/null
@@ -1,16 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde;
2
3import java.nio.file.Path;
4
5import cuchaz.enigma.ProgressListener;
6import cuchaz.enigma.translation.mapping.EntryMapping;
7import cuchaz.enigma.translation.mapping.MappingDelta;
8import cuchaz.enigma.translation.mapping.tree.EntryTree;
9
10public interface MappingsWriter {
11 void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters);
12
13 default void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
14 write(mappings, MappingDelta.added(mappings), path, progress, saveParameters);
15 }
16}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java
deleted file mode 100644
index 6465008b..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java
+++ /dev/null
@@ -1,30 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import cuchaz.enigma.translation.mapping.AccessModifier;
7import cuchaz.enigma.translation.mapping.EntryMapping;
8
9public final class RawEntryMapping {
10 private final String targetName;
11 private final AccessModifier access;
12 private final List<String> javadocs = new ArrayList<>();
13
14 public RawEntryMapping(String targetName) {
15 this(targetName, AccessModifier.UNCHANGED);
16 }
17
18 public RawEntryMapping(String targetName, AccessModifier access) {
19 this.access = access;
20 this.targetName = targetName != null && !targetName.equals("-") ? targetName : null;
21 }
22
23 public void addJavadocLine(String line) {
24 javadocs.add(line);
25 }
26
27 public EntryMapping bake() {
28 return new EntryMapping(targetName, access, javadocs.isEmpty() ? null : String.join("\n", javadocs));
29 }
30}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java
deleted file mode 100644
index 08d0e575..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java
+++ /dev/null
@@ -1,361 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.enigma;
2
3import java.io.IOException;
4import java.nio.charset.StandardCharsets;
5import java.nio.file.FileSystem;
6import java.nio.file.FileSystems;
7import java.nio.file.Files;
8import java.nio.file.NotDirectoryException;
9import java.nio.file.Path;
10import java.util.ArrayDeque;
11import java.util.Arrays;
12import java.util.Deque;
13import java.util.List;
14import java.util.Locale;
15
16import org.jetbrains.annotations.Nullable;
17
18import cuchaz.enigma.ProgressListener;
19import cuchaz.enigma.translation.mapping.AccessModifier;
20import cuchaz.enigma.translation.mapping.EntryMapping;
21import cuchaz.enigma.translation.mapping.MappingPair;
22import cuchaz.enigma.translation.mapping.serde.MappingHelper;
23import cuchaz.enigma.translation.mapping.serde.MappingParseException;
24import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
25import cuchaz.enigma.translation.mapping.serde.MappingsReader;
26import cuchaz.enigma.translation.mapping.serde.RawEntryMapping;
27import cuchaz.enigma.translation.mapping.tree.EntryTree;
28import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
29import cuchaz.enigma.translation.representation.MethodDescriptor;
30import cuchaz.enigma.translation.representation.TypeDescriptor;
31import cuchaz.enigma.translation.representation.entry.ClassEntry;
32import cuchaz.enigma.translation.representation.entry.Entry;
33import cuchaz.enigma.translation.representation.entry.FieldEntry;
34import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
35import cuchaz.enigma.translation.representation.entry.MethodEntry;
36import cuchaz.enigma.utils.I18n;
37
38public enum EnigmaMappingsReader implements MappingsReader {
39 FILE {
40 @Override
41 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
42 progress.init(1, I18n.translate("progress.mappings.loading_file"));
43
44 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
45 readFile(path, mappings);
46
47 progress.step(1, I18n.translate("progress.done"));
48
49 return mappings;
50 }
51 },
52 DIRECTORY {
53 @Override
54 public EntryTree<EntryMapping> read(Path root, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
55 if (!Files.isDirectory(root)) {
56 throw new NotDirectoryException(root.toString());
57 }
58
59 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
60 List<Path> files = Files.walk(root).filter(f -> !Files.isDirectory(f)).filter(f -> f.toString().endsWith(".mapping")).toList();
61
62 progress.init(files.size(), I18n.translate("progress.mappings.loading_directory"));
63 int step = 0;
64
65 for (Path file : files) {
66 progress.step(step++, root.relativize(file).toString());
67
68 if (Files.isHidden(file)) {
69 continue;
70 }
71
72 readFile(file, mappings);
73 }
74
75 return mappings;
76 }
77 },
78 ZIP {
79 @Override
80 public EntryTree<EntryMapping> read(Path zip, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException {
81 try (FileSystem fs = FileSystems.newFileSystem(zip, (ClassLoader) null)) {
82 return DIRECTORY.read(fs.getPath("/"), progress, saveParameters);
83 }
84 }
85 };
86
87 /**
88 * Reads multiple Enigma mapping files.
89 *
90 * @param progress the progress listener
91 * @param paths the Enigma files to read; cannot be empty
92 * @return the parsed mappings
93 * @throws MappingParseException if a mapping file cannot be parsed
94 * @throws IOException if an IO error occurs
95 * @throws IllegalArgumentException if there are no paths to read
96 */
97 public static EntryTree<EntryMapping> readFiles(ProgressListener progress, Path... paths) throws MappingParseException, IOException {
98 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
99
100 if (paths.length == 0) {
101 throw new IllegalArgumentException("No paths to read mappings from");
102 }
103
104 progress.init(paths.length, I18n.translate("progress.mappings.loading_directory"));
105 int step = 0;
106
107 for (Path file : paths) {
108 progress.step(step++, paths.toString());
109 readFile(file, mappings);
110 }
111
112 return mappings;
113 }
114
115 private static void readFile(Path path, EntryTree<EntryMapping> mappings) throws IOException, MappingParseException {
116 List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
117 Deque<MappingPair<?, RawEntryMapping>> mappingStack = new ArrayDeque<>();
118
119 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
120 String line = lines.get(lineNumber);
121 int indentation = countIndentation(line, path, lineNumber);
122
123 line = formatLine(line);
124
125 if (line == null) {
126 continue;
127 }
128
129 cleanMappingStack(indentation, mappingStack, mappings);
130
131 try {
132 MappingPair<?, RawEntryMapping> pair = parseLine(mappingStack.peek(), line);
133
134 if (pair != null) {
135 mappingStack.push(pair);
136 }
137 } catch (Throwable t) {
138 throw new MappingParseException(path, lineNumber + 1, t);
139 }
140 }
141
142 // Clean up rest
143 cleanMappingStack(0, mappingStack, mappings);
144 }
145
146 private static void cleanMappingStack(int indentation, Deque<MappingPair<?, RawEntryMapping>> mappingStack, EntryTree<EntryMapping> mappings) {
147 while (indentation < mappingStack.size()) {
148 MappingPair<?, RawEntryMapping> pair = mappingStack.pop();
149
150 if (pair.getMapping() != null) {
151 mappings.insert(pair.getEntry(), pair.getMapping().bake());
152 }
153 }
154 }
155
156 @Nullable
157 private static String formatLine(String line) {
158 line = stripComment(line);
159 line = line.trim();
160
161 if (line.isEmpty()) {
162 return null;
163 }
164
165 return line;
166 }
167
168 private static String stripComment(String line) {
169 //Dont support comments on javadoc lines
170 if (line.trim().startsWith(EnigmaFormat.COMMENT)) {
171 return line;
172 }
173
174 int commentPos = line.indexOf('#');
175
176 if (commentPos >= 0) {
177 return line.substring(0, commentPos);
178 }
179
180 return line;
181 }
182
183 private static int countIndentation(String line, Path path, int lineNumber) throws MappingParseException {
184 int indent = 0;
185
186 for (int i = 0; i < line.length(); i++) {
187 if (line.charAt(i) == ' ') {
188 throw new MappingParseException(path, lineNumber + 1, "Spaces must not be used to indent lines!");
189 }
190
191 if (line.charAt(i) != '\t') {
192 break;
193 }
194
195 indent++;
196 }
197
198 return indent;
199 }
200
201 private static MappingPair<?, RawEntryMapping> parseLine(@Nullable MappingPair<?, RawEntryMapping> parent, String line) {
202 String[] tokens = line.trim().split("\\s");
203 String keyToken = tokens[0].toUpperCase(Locale.ROOT);
204 Entry<?> parentEntry = parent == null ? null : parent.getEntry();
205
206 switch (keyToken) {
207 case EnigmaFormat.CLASS:
208 return parseClass(parentEntry, tokens);
209 case EnigmaFormat.FIELD:
210 return parseField(parentEntry, tokens);
211 case EnigmaFormat.METHOD:
212 return parseMethod(parentEntry, tokens);
213 case EnigmaFormat.PARAMETER:
214 return parseArgument(parentEntry, tokens);
215 case EnigmaFormat.COMMENT:
216 readJavadoc(parent, tokens);
217 return null;
218 default:
219 throw new RuntimeException("Unknown token '" + keyToken + "'");
220 }
221 }
222
223 private static void readJavadoc(MappingPair<?, RawEntryMapping> parent, String[] tokens) {
224 if (parent == null) {
225 throw new IllegalStateException("Javadoc has no parent!");
226 }
227
228 // Empty string to concat
229 String jdLine = tokens.length > 1 ? String.join(" ", Arrays.copyOfRange(tokens, 1, tokens.length)) : "";
230
231 if (parent.getMapping() == null) {
232 parent.setMapping(new RawEntryMapping(parent.getEntry().getName(), AccessModifier.UNCHANGED));
233 }
234
235 parent.getMapping().addJavadocLine(MappingHelper.unescape(jdLine));
236 }
237
238 private static MappingPair<ClassEntry, RawEntryMapping> parseClass(@Nullable Entry<?> parent, String[] tokens) {
239 String obfuscatedName = ClassEntry.getInnerName(tokens[1]);
240 ClassEntry obfuscatedEntry;
241
242 if (parent instanceof ClassEntry) {
243 obfuscatedEntry = new ClassEntry((ClassEntry) parent, obfuscatedName);
244 } else {
245 obfuscatedEntry = new ClassEntry(obfuscatedName);
246 }
247
248 String mapping = null;
249 AccessModifier modifier = AccessModifier.UNCHANGED;
250
251 if (tokens.length == 3) {
252 AccessModifier parsedModifier = parseModifier(tokens[2]);
253
254 if (parsedModifier != null) {
255 modifier = parsedModifier;
256 mapping = obfuscatedName;
257 } else {
258 mapping = tokens[2];
259 }
260 } else if (tokens.length == 4) {
261 mapping = tokens[2];
262 modifier = parseModifier(tokens[3]);
263 }
264
265 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier));
266 }
267
268 private static MappingPair<FieldEntry, RawEntryMapping> parseField(@Nullable Entry<?> parent, String[] tokens) {
269 if (!(parent instanceof ClassEntry)) {
270 throw new RuntimeException("Field must be a child of a class!");
271 }
272
273 ClassEntry ownerEntry = (ClassEntry) parent;
274
275 String obfuscatedName = tokens[1];
276 String mapping = null;
277 AccessModifier modifier = AccessModifier.UNCHANGED;
278 TypeDescriptor descriptor;
279
280 if (tokens.length == 3) {
281 descriptor = new TypeDescriptor(tokens[2]);
282 } else if (tokens.length == 4) {
283 AccessModifier parsedModifier = parseModifier(tokens[3]);
284
285 if (parsedModifier != null) {
286 descriptor = new TypeDescriptor(tokens[2]);
287 modifier = parsedModifier;
288 } else {
289 mapping = tokens[2];
290 descriptor = new TypeDescriptor(tokens[3]);
291 }
292 } else if (tokens.length == 5) {
293 mapping = tokens[2];
294 modifier = parseModifier(tokens[3]);
295 descriptor = new TypeDescriptor(tokens[4]);
296 } else {
297 throw new RuntimeException("Invalid field declaration");
298 }
299
300 FieldEntry obfuscatedEntry = new FieldEntry(ownerEntry, obfuscatedName, descriptor);
301 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier));
302 }
303
304 private static MappingPair<MethodEntry, RawEntryMapping> parseMethod(@Nullable Entry<?> parent, String[] tokens) {
305 if (!(parent instanceof ClassEntry)) {
306 throw new RuntimeException("Method must be a child of a class!");
307 }
308
309 ClassEntry ownerEntry = (ClassEntry) parent;
310
311 String obfuscatedName = tokens[1];
312 String mapping = null;
313 AccessModifier modifier = AccessModifier.UNCHANGED;
314 MethodDescriptor descriptor;
315
316 if (tokens.length == 3) {
317 descriptor = new MethodDescriptor(tokens[2]);
318 } else if (tokens.length == 4) {
319 AccessModifier parsedModifier = parseModifier(tokens[3]);
320
321 if (parsedModifier != null) {
322 modifier = parsedModifier;
323 mapping = obfuscatedName;
324 descriptor = new MethodDescriptor(tokens[2]);
325 } else {
326 mapping = tokens[2];
327 descriptor = new MethodDescriptor(tokens[3]);
328 }
329 } else if (tokens.length == 5) {
330 mapping = tokens[2];
331 modifier = parseModifier(tokens[4]);
332 descriptor = new MethodDescriptor(tokens[3]);
333 } else {
334 throw new RuntimeException("Invalid method declaration");
335 }
336
337 MethodEntry obfuscatedEntry = new MethodEntry(ownerEntry, obfuscatedName, descriptor);
338 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier));
339 }
340
341 private static MappingPair<LocalVariableEntry, RawEntryMapping> parseArgument(@Nullable Entry<?> parent, String[] tokens) {
342 if (!(parent instanceof MethodEntry)) {
343 throw new RuntimeException("Method arg must be a child of a method!");
344 }
345
346 MethodEntry ownerEntry = (MethodEntry) parent;
347 LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerEntry, Integer.parseInt(tokens[1]), "", true, null);
348 String mapping = tokens[2];
349
350 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping));
351 }
352
353 @Nullable
354 private static AccessModifier parseModifier(String token) {
355 if (token.startsWith("ACC:")) {
356 return AccessModifier.valueOf(token.substring(4));
357 }
358
359 return null;
360 }
361}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java
index 266668dd..b90bb7f2 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java
@@ -13,17 +13,12 @@ package cuchaz.enigma.translation.mapping.serde.enigma;
13 13
14import java.io.IOException; 14import java.io.IOException;
15import java.io.PrintWriter; 15import java.io.PrintWriter;
16import java.net.URI;
17import java.net.URISyntaxException;
18import java.nio.file.DirectoryStream; 16import java.nio.file.DirectoryStream;
19import java.nio.file.FileSystem;
20import java.nio.file.FileSystems;
21import java.nio.file.Files; 17import java.nio.file.Files;
22import java.nio.file.Path; 18import java.nio.file.Path;
23import java.nio.file.Paths; 19import java.nio.file.Paths;
24import java.util.ArrayList; 20import java.util.ArrayList;
25import java.util.Collection; 21import java.util.Collection;
26import java.util.Collections;
27import java.util.HashSet; 22import java.util.HashSet;
28import java.util.Objects; 23import java.util.Objects;
29import java.util.Set; 24import java.util.Set;
@@ -50,7 +45,6 @@ import cuchaz.enigma.translation.mapping.serde.MappingFileNameFormat;
50import cuchaz.enigma.translation.mapping.serde.MappingHelper; 45import cuchaz.enigma.translation.mapping.serde.MappingHelper;
51import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; 46import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
52import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 47import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
53import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
54import cuchaz.enigma.translation.mapping.tree.EntryTree; 48import cuchaz.enigma.translation.mapping.tree.EntryTree;
55import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; 49import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
56import cuchaz.enigma.translation.mapping.tree.HashEntryTree; 50import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
@@ -61,33 +55,9 @@ import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
61import cuchaz.enigma.translation.representation.entry.MethodEntry; 55import cuchaz.enigma.translation.representation.entry.MethodEntry;
62import cuchaz.enigma.utils.I18n; 56import cuchaz.enigma.utils.I18n;
63 57
64public enum EnigmaMappingsWriter implements MappingsWriter { 58public enum EnigmaMappingsWriter {
65 FILE {
66 @Override
67 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
68 Collection<ClassEntry> classes = mappings.getRootNodes().filter(entry -> entry.getEntry() instanceof ClassEntry).map(entry -> (ClassEntry) entry.getEntry()).toList();
69
70 progress.init(classes.size(), I18n.translate("progress.mappings.writing"));
71
72 int steps = 0;
73
74 try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) {
75 for (ClassEntry classEntry : classes) {
76 progress.step(steps++, classEntry.getFullName());
77 writeRoot(writer, mappings, classEntry);
78 }
79 } catch (IOException e) {
80 e.printStackTrace();
81 }
82 }
83 },
84 DIRECTORY { 59 DIRECTORY {
85 @Override 60 @Override
86 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
87 write(mappings, delta, path, progress, saveParameters, false);
88 }
89
90 @Override
91 @ApiStatus.Internal 61 @ApiStatus.Internal
92 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters, boolean useMio) { 62 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters, boolean useMio) {
93 Collection<ClassEntry> changedClasses = delta.getChangedRoots().filter(entry -> entry instanceof ClassEntry).map(entry -> (ClassEntry) entry).toList(); 63 Collection<ClassEntry> changedClasses = delta.getChangedRoots().filter(entry -> entry instanceof ClassEntry).map(entry -> (ClassEntry) entry).toList();
@@ -199,18 +169,6 @@ public enum EnigmaMappingsWriter implements MappingsWriter {
199 private Path resolve(Path root, ClassEntry classEntry) { 169 private Path resolve(Path root, ClassEntry classEntry) {
200 return root.resolve(classEntry.getFullName() + ".mapping"); 170 return root.resolve(classEntry.getFullName() + ".mapping");
201 } 171 }
202 },
203 ZIP {
204 @Override
205 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path zip, ProgressListener progress, MappingSaveParameters saveParameters) {
206 try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:file", null, zip.toUri().getPath(), ""), Collections.singletonMap("create", "true"))) {
207 DIRECTORY.write(mappings, delta, fs.getPath("/"), progress, saveParameters);
208 } catch (IOException e) {
209 e.printStackTrace();
210 } catch (URISyntaxException e) {
211 throw new RuntimeException("Unexpected error creating URI for " + zip, e);
212 }
213 }
214 }; 172 };
215 173
216 protected void writeRoot(PrintWriter writer, EntryTree<EntryMapping> mappings, ClassEntry classEntry) { 174 protected void writeRoot(PrintWriter writer, EntryTree<EntryMapping> mappings, ClassEntry classEntry) {
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/proguard/ProguardMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/proguard/ProguardMappingsReader.java
deleted file mode 100644
index b839c079..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/proguard/ProguardMappingsReader.java
+++ /dev/null
@@ -1,137 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.proguard;
2
3import java.io.IOException;
4import java.nio.charset.StandardCharsets;
5import java.nio.file.Files;
6import java.nio.file.Path;
7import java.util.regex.Matcher;
8import java.util.regex.Pattern;
9
10import cuchaz.enigma.ProgressListener;
11import cuchaz.enigma.translation.mapping.EntryMapping;
12import cuchaz.enigma.translation.mapping.MappingOperations;
13import cuchaz.enigma.translation.mapping.serde.MappingParseException;
14import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
15import cuchaz.enigma.translation.mapping.serde.MappingsReader;
16import cuchaz.enigma.translation.mapping.tree.EntryTree;
17import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
18import cuchaz.enigma.translation.representation.MethodDescriptor;
19import cuchaz.enigma.translation.representation.TypeDescriptor;
20import cuchaz.enigma.translation.representation.entry.ClassEntry;
21import cuchaz.enigma.translation.representation.entry.FieldEntry;
22import cuchaz.enigma.translation.representation.entry.MethodEntry;
23
24public class ProguardMappingsReader implements MappingsReader {
25 public static final ProguardMappingsReader INSTANCE = new ProguardMappingsReader();
26 private static final String NAME = "[a-zA-Z0-9_\\-.$<>]+";
27 private static final String TYPE = NAME + "(?:\\[])*";
28 private static final String TYPE_LIST = "|(?:(?:" + TYPE + ",)*" + TYPE + ")";
29 private static final Pattern CLASS = Pattern.compile("(" + NAME + ") -> (" + NAME + "):");
30 private static final Pattern FIELD = Pattern.compile(" {4}(" + TYPE + ") (" + NAME + ") -> (" + NAME + ")");
31 private static final Pattern METHOD = Pattern.compile(" {4}(?:[0-9]+:[0-9]+:)?(" + TYPE + ") (" + NAME + ")\\((" + TYPE_LIST + ")\\) -> (" + NAME + ")");
32
33 public ProguardMappingsReader() {
34 }
35
36 @Override
37 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException {
38 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
39
40 int lineNumber = 0;
41 ClassEntry currentClass = null;
42
43 for (String line : Files.readAllLines(path, StandardCharsets.UTF_8)) {
44 lineNumber++;
45
46 if (line.startsWith("#") || line.isEmpty()) {
47 continue;
48 }
49
50 Matcher classMatcher = CLASS.matcher(line);
51 Matcher fieldMatcher = FIELD.matcher(line);
52 Matcher methodMatcher = METHOD.matcher(line);
53
54 if (classMatcher.matches()) {
55 String name = classMatcher.group(1);
56 String targetName = classMatcher.group(2);
57
58 mappings.insert(currentClass = new ClassEntry(name.replace('.', '/')), new EntryMapping(ClassEntry.getInnerName(targetName.replace('.', '/'))));
59 } else if (fieldMatcher.matches()) {
60 String type = fieldMatcher.group(1);
61 String name = fieldMatcher.group(2);
62 String targetName = fieldMatcher.group(3);
63
64 if (currentClass == null) {
65 throw new MappingParseException(path, lineNumber, "field mapping not inside class: " + line);
66 }
67
68 mappings.insert(new FieldEntry(currentClass, name, new TypeDescriptor(getDescriptor(type))), new EntryMapping(targetName));
69 } else if (methodMatcher.matches()) {
70 String returnType = methodMatcher.group(1);
71 String name = methodMatcher.group(2);
72 String[] parameterTypes = methodMatcher.group(3).isEmpty() ? new String[0] : methodMatcher.group(3).split(",");
73 String targetName = methodMatcher.group(4);
74
75 if (currentClass == null) {
76 throw new MappingParseException(path, lineNumber, "method mapping not inside class: " + line);
77 }
78
79 mappings.insert(new MethodEntry(currentClass, name, new MethodDescriptor(getDescriptor(returnType, parameterTypes))), new EntryMapping(targetName));
80 } else {
81 throw new MappingParseException(path, lineNumber, "invalid mapping line: " + line);
82 }
83 }
84
85 return MappingOperations.invert(mappings);
86 }
87
88 private String getDescriptor(String type) {
89 StringBuilder descriptor = new StringBuilder();
90
91 while (type.endsWith("[]")) {
92 descriptor.append("[");
93 type = type.substring(0, type.length() - 2);
94 }
95
96 switch (type) {
97 case "byte":
98 return descriptor + "B";
99 case "char":
100 return descriptor + "C";
101 case "short":
102 return descriptor + "S";
103 case "int":
104 return descriptor + "I";
105 case "long":
106 return descriptor + "J";
107 case "float":
108 return descriptor + "F";
109 case "double":
110 return descriptor + "D";
111 case "boolean":
112 return descriptor + "Z";
113 case "void":
114 return descriptor + "V";
115 }
116
117 descriptor.append("L");
118 descriptor.append(type.replace('.', '/'));
119 descriptor.append(";");
120
121 return descriptor.toString();
122 }
123
124 private String getDescriptor(String returnType, String[] parameterTypes) {
125 StringBuilder descriptor = new StringBuilder();
126 descriptor.append('(');
127
128 for (String parameterType : parameterTypes) {
129 descriptor.append(getDescriptor(parameterType));
130 }
131
132 descriptor.append(')');
133 descriptor.append(getDescriptor(returnType));
134
135 return descriptor.toString();
136 }
137}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java
deleted file mode 100644
index ce54feae..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java
+++ /dev/null
@@ -1,64 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import java.io.IOException;
4import java.nio.file.Files;
5import java.nio.file.Path;
6import java.util.List;
7import java.util.regex.Matcher;
8import java.util.regex.Pattern;
9
10import cuchaz.enigma.ProgressListener;
11import cuchaz.enigma.translation.mapping.EntryMapping;
12import cuchaz.enigma.translation.mapping.serde.MappingParseException;
13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
14import cuchaz.enigma.translation.mapping.serde.MappingsReader;
15import cuchaz.enigma.translation.mapping.tree.EntryTree;
16import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
17import cuchaz.enigma.translation.representation.MethodDescriptor;
18import cuchaz.enigma.translation.representation.TypeDescriptor;
19import cuchaz.enigma.translation.representation.entry.ClassEntry;
20import cuchaz.enigma.translation.representation.entry.FieldEntry;
21import cuchaz.enigma.translation.representation.entry.MethodEntry;
22
23public class RecafMappingsReader implements MappingsReader {
24 public static final RecafMappingsReader INSTANCE = new RecafMappingsReader();
25 private static final Pattern METHOD_PATTERN = Pattern.compile("(.*?)\\.(.*?)(\\(.*?) (.*)");
26 private static final Pattern FIELD_PATTERN = Pattern.compile("(.*?)\\.(.*?) (.*?) (.*)");
27 private static final Pattern CLASS_PATTERN = Pattern.compile("(.*?) (.*)");
28
29 @Override
30 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException {
31 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
32 List<String> lines = Files.readAllLines(path);
33
34 for (String line : lines) {
35 Matcher methodMatcher = METHOD_PATTERN.matcher(line);
36
37 if (methodMatcher.find()) {
38 ClassEntry owner = new ClassEntry(methodMatcher.group(1));
39 String name = methodMatcher.group(2);
40 MethodDescriptor desc = new MethodDescriptor(methodMatcher.group(3));
41 mappings.insert(new MethodEntry(owner, name, desc), new EntryMapping(methodMatcher.group(4)));
42 continue;
43 }
44
45 Matcher fieldMatcher = FIELD_PATTERN.matcher(line);
46
47 if (fieldMatcher.find()) {
48 ClassEntry owner = new ClassEntry(fieldMatcher.group(1));
49 String name = fieldMatcher.group(2);
50 TypeDescriptor desc = new TypeDescriptor(fieldMatcher.group(3));
51 mappings.insert(new FieldEntry(owner, name, desc), new EntryMapping(fieldMatcher.group(4)));
52 continue;
53 }
54
55 Matcher classMatcher = CLASS_PATTERN.matcher(line);
56
57 if (classMatcher.find()) {
58 mappings.insert(new ClassEntry(classMatcher.group(1)), new EntryMapping(classMatcher.group(2)));
59 }
60 }
61
62 return mappings;
63 }
64}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java
deleted file mode 100644
index 26a29bf1..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java
+++ /dev/null
@@ -1,77 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import java.io.BufferedWriter;
4import java.io.IOException;
5import java.io.Writer;
6import java.nio.file.Files;
7import java.nio.file.Path;
8import java.util.ArrayList;
9
10import cuchaz.enigma.ProgressListener;
11import cuchaz.enigma.translation.mapping.EntryMapping;
12import cuchaz.enigma.translation.mapping.MappingDelta;
13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
14import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
15import cuchaz.enigma.translation.mapping.tree.EntryTree;
16import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
17import cuchaz.enigma.translation.representation.entry.ClassEntry;
18import cuchaz.enigma.translation.representation.entry.Entry;
19import cuchaz.enigma.translation.representation.entry.FieldEntry;
20import cuchaz.enigma.translation.representation.entry.MethodEntry;
21
22public class RecafMappingsWriter implements MappingsWriter {
23 public static final RecafMappingsWriter INSTANCE = new RecafMappingsWriter();
24
25 @Override
26 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
27 try {
28 Files.deleteIfExists(path);
29 Files.createFile(path);
30 } catch (IOException e) {
31 e.printStackTrace();
32 }
33
34 try (BufferedWriter writer = Files.newBufferedWriter(path)) {
35 new ArrayList<>(mappings).stream().map(EntryTreeNode::getEntry).forEach(entry -> writeEntry(writer, mappings, entry));
36 } catch (IOException e) {
37 e.printStackTrace();
38 }
39 }
40
41 private void writeEntry(Writer writer, EntryTree<EntryMapping> mappings, Entry<?> entry) {
42 EntryTreeNode<EntryMapping> node = mappings.findNode(entry);
43
44 if (node == null) {
45 return;
46 }
47
48 EntryMapping mapping = mappings.get(entry);
49
50 try {
51 if (mapping != null && mapping.targetName() != null) {
52 if (entry instanceof ClassEntry classEntry) {
53 writer.write(classEntry.getFullName());
54 writer.write(" ");
55 writer.write(mapping.targetName());
56 } else if (entry instanceof FieldEntry fieldEntry) {
57 writer.write(fieldEntry.getFullName());
58 writer.write(" ");
59 writer.write(fieldEntry.getDesc().toString());
60 writer.write(" ");
61 writer.write(mapping.targetName());
62 } else if (entry instanceof MethodEntry methodEntry) {
63 writer.write(methodEntry.getFullName());
64 writer.write(methodEntry.getDesc().toString());
65 writer.write(" ");
66 writer.write(mapping.targetName());
67 }
68
69 writer.write("\n");
70 }
71 } catch (IOException e) {
72 e.printStackTrace();
73 }
74
75 node.getChildren().forEach(child -> writeEntry(writer, mappings, child));
76 }
77}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java
deleted file mode 100644
index 42372373..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java
+++ /dev/null
@@ -1,119 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.srg;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5import java.nio.file.Files;
6import java.nio.file.Path;
7import java.util.ArrayList;
8import java.util.Collection;
9import java.util.Comparator;
10import java.util.List;
11
12import cuchaz.enigma.ProgressListener;
13import cuchaz.enigma.translation.MappingTranslator;
14import cuchaz.enigma.translation.Translator;
15import cuchaz.enigma.translation.mapping.EntryMapping;
16import cuchaz.enigma.translation.mapping.MappingDelta;
17import cuchaz.enigma.translation.mapping.VoidEntryResolver;
18import cuchaz.enigma.translation.mapping.serde.LfPrintWriter;
19import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
20import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
21import cuchaz.enigma.translation.mapping.tree.EntryTree;
22import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
23import cuchaz.enigma.translation.representation.entry.ClassEntry;
24import cuchaz.enigma.translation.representation.entry.Entry;
25import cuchaz.enigma.translation.representation.entry.FieldEntry;
26import cuchaz.enigma.translation.representation.entry.MethodEntry;
27import cuchaz.enigma.utils.I18n;
28
29public enum SrgMappingsWriter implements MappingsWriter {
30 INSTANCE;
31
32 @Override
33 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
34 try {
35 Files.deleteIfExists(path);
36 Files.createFile(path);
37 } catch (IOException e) {
38 e.printStackTrace();
39 }
40
41 List<String> classLines = new ArrayList<>();
42 List<String> fieldLines = new ArrayList<>();
43 List<String> methodLines = new ArrayList<>();
44
45 List<? extends Entry<?>> rootEntries = new ArrayList<>(mappings).stream().map(EntryTreeNode::getEntry).toList();
46 progress.init(rootEntries.size(), I18n.translate("progress.mappings.converting"));
47
48 int steps = 0;
49
50 for (Entry<?> entry : sorted(rootEntries)) {
51 progress.step(steps++, entry.getName());
52 writeEntry(classLines, fieldLines, methodLines, mappings, entry);
53 }
54
55 progress.init(3, I18n.translate("progress.mappings.writing"));
56
57 try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) {
58 progress.step(0, I18n.translate("type.classes"));
59 classLines.forEach(writer::println);
60 progress.step(1, I18n.translate("type.fields"));
61 fieldLines.forEach(writer::println);
62 progress.step(2, I18n.translate("type.methods"));
63 methodLines.forEach(writer::println);
64 } catch (IOException e) {
65 e.printStackTrace();
66 }
67 }
68
69 private void writeEntry(List<String> classes, List<String> fields, List<String> methods, EntryTree<EntryMapping> mappings, Entry<?> entry) {
70 EntryTreeNode<EntryMapping> node = mappings.findNode(entry);
71
72 if (node == null) {
73 return;
74 }
75
76 Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
77
78 if (entry instanceof ClassEntry) {
79 classes.add(generateClassLine((ClassEntry) entry, translator));
80 } else if (entry instanceof FieldEntry) {
81 fields.add(generateFieldLine((FieldEntry) entry, translator));
82 } else if (entry instanceof MethodEntry) {
83 methods.add(generateMethodLine((MethodEntry) entry, translator));
84 }
85
86 for (Entry<?> child : sorted(node.getChildren())) {
87 writeEntry(classes, fields, methods, mappings, child);
88 }
89 }
90
91 private String generateClassLine(ClassEntry sourceEntry, Translator translator) {
92 ClassEntry targetEntry = translator.translate(sourceEntry);
93 return "CL: " + sourceEntry.getFullName() + " " + targetEntry.getFullName();
94 }
95
96 private String generateMethodLine(MethodEntry sourceEntry, Translator translator) {
97 MethodEntry targetEntry = translator.translate(sourceEntry);
98 return "MD: " + describeMethod(sourceEntry) + " " + describeMethod(targetEntry);
99 }
100
101 private String describeMethod(MethodEntry entry) {
102 return entry.getParent().getFullName() + "/" + entry.getName() + " " + entry.getDesc();
103 }
104
105 private String generateFieldLine(FieldEntry sourceEntry, Translator translator) {
106 FieldEntry targetEntry = translator.translate(sourceEntry);
107 return "FD: " + describeField(sourceEntry) + " " + describeField(targetEntry);
108 }
109
110 private String describeField(FieldEntry entry) {
111 return entry.getParent().getFullName() + "/" + entry.getName();
112 }
113
114 private Collection<Entry<?>> sorted(Collection<? extends Entry<?>> collection) {
115 ArrayList<Entry<?>> sorted = new ArrayList<>(collection);
116 sorted.sort(Comparator.comparing(Entry::getName));
117 return sorted;
118 }
119}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java
deleted file mode 100644
index ae003003..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java
+++ /dev/null
@@ -1,117 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.tiny;
2
3import java.io.IOException;
4import java.nio.charset.StandardCharsets;
5import java.nio.file.Files;
6import java.nio.file.Path;
7import java.util.List;
8
9import cuchaz.enigma.ProgressListener;
10import cuchaz.enigma.translation.mapping.EntryMapping;
11import cuchaz.enigma.translation.mapping.MappingPair;
12import cuchaz.enigma.translation.mapping.serde.MappingParseException;
13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
14import cuchaz.enigma.translation.mapping.serde.MappingsReader;
15import cuchaz.enigma.translation.mapping.tree.EntryTree;
16import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
17import cuchaz.enigma.translation.representation.MethodDescriptor;
18import cuchaz.enigma.translation.representation.TypeDescriptor;
19import cuchaz.enigma.translation.representation.entry.ClassEntry;
20import cuchaz.enigma.translation.representation.entry.FieldEntry;
21import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
22import cuchaz.enigma.translation.representation.entry.MethodEntry;
23import cuchaz.enigma.utils.I18n;
24
25public enum TinyMappingsReader implements MappingsReader {
26 INSTANCE;
27
28 @Override
29 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
30 return read(path, Files.readAllLines(path, StandardCharsets.UTF_8), progress);
31 }
32
33 private EntryTree<EntryMapping> read(Path path, List<String> lines, ProgressListener progress) throws MappingParseException {
34 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
35 lines.remove(0);
36
37 progress.init(lines.size(), I18n.translate("progress.mappings.loading_file"));
38
39 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
40 progress.step(lineNumber, "");
41
42 String line = lines.get(lineNumber);
43
44 if (line.trim().startsWith("#")) {
45 continue;
46 }
47
48 try {
49 MappingPair<?, EntryMapping> mapping = parseLine(line);
50 mappings.insert(mapping.getEntry(), mapping.getMapping());
51 } catch (Throwable t) {
52 throw new MappingParseException(path, lineNumber, t);
53 }
54 }
55
56 return mappings;
57 }
58
59 private MappingPair<?, EntryMapping> parseLine(String line) {
60 String[] tokens = line.split("\t");
61
62 String key = tokens[0];
63 switch (key) {
64 case "CLASS":
65 return parseClass(tokens);
66 case "FIELD":
67 return parseField(tokens);
68 case "METHOD":
69 return parseMethod(tokens);
70 case "MTH-ARG":
71 return parseArgument(tokens);
72 default:
73 throw new RuntimeException("Unknown token '" + key + "'!");
74 }
75 }
76
77 private MappingPair<ClassEntry, EntryMapping> parseClass(String[] tokens) {
78 ClassEntry obfuscatedEntry = new ClassEntry(tokens[1]);
79 String mapping = tokens[2];
80
81 if (mapping.indexOf('$') > 0) {
82 // inner classes should map to only the final part
83 mapping = mapping.substring(mapping.lastIndexOf('$') + 1);
84 }
85
86 return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping));
87 }
88
89 private MappingPair<FieldEntry, EntryMapping> parseField(String[] tokens) {
90 ClassEntry ownerClass = new ClassEntry(tokens[1]);
91 TypeDescriptor descriptor = new TypeDescriptor(tokens[2]);
92
93 FieldEntry obfuscatedEntry = new FieldEntry(ownerClass, tokens[3], descriptor);
94 String mapping = tokens[4];
95 return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping));
96 }
97
98 private MappingPair<MethodEntry, EntryMapping> parseMethod(String[] tokens) {
99 ClassEntry ownerClass = new ClassEntry(tokens[1]);
100 MethodDescriptor descriptor = new MethodDescriptor(tokens[2]);
101
102 MethodEntry obfuscatedEntry = new MethodEntry(ownerClass, tokens[3], descriptor);
103 String mapping = tokens[4];
104 return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping));
105 }
106
107 private MappingPair<LocalVariableEntry, EntryMapping> parseArgument(String[] tokens) {
108 ClassEntry ownerClass = new ClassEntry(tokens[1]);
109 MethodDescriptor ownerDescriptor = new MethodDescriptor(tokens[2]);
110 MethodEntry ownerMethod = new MethodEntry(ownerClass, tokens[3], ownerDescriptor);
111 int variableIndex = Integer.parseInt(tokens[4]);
112
113 String mapping = tokens[5];
114 LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerMethod, variableIndex, "", true, null);
115 return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping));
116 }
117}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java
deleted file mode 100644
index 67582be0..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java
+++ /dev/null
@@ -1,144 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.tiny;
2
3import java.io.BufferedWriter;
4import java.io.IOException;
5import java.io.Writer;
6import java.nio.charset.StandardCharsets;
7import java.nio.file.Files;
8import java.nio.file.Path;
9import java.util.ArrayList;
10import java.util.Comparator;
11import java.util.HashSet;
12import java.util.Set;
13
14import cuchaz.enigma.ProgressListener;
15import cuchaz.enigma.translation.MappingTranslator;
16import cuchaz.enigma.translation.Translator;
17import cuchaz.enigma.translation.mapping.EntryMapping;
18import cuchaz.enigma.translation.mapping.MappingDelta;
19import cuchaz.enigma.translation.mapping.VoidEntryResolver;
20import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
21import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
22import cuchaz.enigma.translation.mapping.tree.EntryTree;
23import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
24import cuchaz.enigma.translation.representation.entry.ClassEntry;
25import cuchaz.enigma.translation.representation.entry.Entry;
26import cuchaz.enigma.translation.representation.entry.FieldEntry;
27import cuchaz.enigma.translation.representation.entry.MethodEntry;
28
29public class TinyMappingsWriter implements MappingsWriter {
30 private static final String VERSION_CONSTANT = "v1";
31
32 //Possibly add a gui or a way to select the namespaces when exporting from the gui
33 public static final TinyMappingsWriter INSTANCE = new TinyMappingsWriter("intermediary", "named");
34
35 // HACK: as of enigma 0.13.1, some fields seem to appear duplicated?
36 private final Set<String> writtenLines = new HashSet<>();
37 private final String nameObf;
38 private final String nameDeobf;
39
40 public TinyMappingsWriter(String nameObf, String nameDeobf) {
41 this.nameObf = nameObf;
42 this.nameDeobf = nameDeobf;
43 }
44
45 @Override
46 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
47 try {
48 Files.deleteIfExists(path);
49 Files.createFile(path);
50 } catch (IOException e) {
51 e.printStackTrace();
52 }
53
54 try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
55 writeLine(writer, new String[]{VERSION_CONSTANT, nameObf, nameDeobf});
56
57 new ArrayList<>(mappings).stream().map(EntryTreeNode::getEntry).sorted(Comparator.comparing(Object::toString)).forEach(entry -> writeEntry(writer, mappings, entry));
58 } catch (IOException e) {
59 e.printStackTrace();
60 }
61 }
62
63 private void writeEntry(Writer writer, EntryTree<EntryMapping> mappings, Entry<?> entry) {
64 EntryTreeNode<EntryMapping> node = mappings.findNode(entry);
65
66 if (node == null) {
67 return;
68 }
69
70 Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
71
72 EntryMapping mapping = mappings.get(entry);
73
74 // Do not write mappings without deobfuscated name since tiny v1 doesn't
75 // support comments anyway
76 if (mapping != null && mapping.targetName() != null) {
77 if (entry instanceof ClassEntry) {
78 writeClass(writer, (ClassEntry) entry, translator);
79 } else if (entry instanceof FieldEntry) {
80 writeLine(writer, serializeEntry(entry, mapping.targetName()));
81 } else if (entry instanceof MethodEntry) {
82 writeLine(writer, serializeEntry(entry, mapping.targetName()));
83 }
84 }
85
86 writeChildren(writer, mappings, node);
87 }
88
89 private void writeChildren(Writer writer, EntryTree<EntryMapping> mappings, EntryTreeNode<EntryMapping> node) {
90 node.getChildren().stream().filter(e -> e instanceof FieldEntry).sorted().forEach(child -> writeEntry(writer, mappings, child));
91
92 node.getChildren().stream().filter(e -> e instanceof MethodEntry).sorted().forEach(child -> writeEntry(writer, mappings, child));
93
94 node.getChildren().stream().filter(e -> e instanceof ClassEntry).sorted().forEach(child -> writeEntry(writer, mappings, child));
95 }
96
97 private void writeClass(Writer writer, ClassEntry entry, Translator translator) {
98 ClassEntry translatedEntry = translator.translate(entry);
99
100 String obfClassName = entry.getFullName();
101 String deobfClassName = translatedEntry.getFullName();
102 writeLine(writer, new String[]{"CLASS", obfClassName, deobfClassName});
103 }
104
105 private void writeLine(Writer writer, String[] data) {
106 try {
107 String line = String.join("\t", data) + "\n";
108
109 if (writtenLines.add(line)) {
110 writer.write(line);
111 }
112 } catch (IOException e) {
113 throw new RuntimeException(e);
114 }
115 }
116
117 private String[] serializeEntry(Entry<?> entry, String... extraFields) {
118 String[] data = null;
119
120 if (entry instanceof FieldEntry) {
121 data = new String[4 + extraFields.length];
122 data[0] = "FIELD";
123 data[1] = entry.getContainingClass().getFullName();
124 data[2] = ((FieldEntry) entry).getDesc().toString();
125 data[3] = entry.getName();
126 } else if (entry instanceof MethodEntry) {
127 data = new String[4 + extraFields.length];
128 data[0] = "METHOD";
129 data[1] = entry.getContainingClass().getFullName();
130 data[2] = ((MethodEntry) entry).getDesc().toString();
131 data[3] = entry.getName();
132 } else if (entry instanceof ClassEntry) {
133 data = new String[2 + extraFields.length];
134 data[0] = "CLASS";
135 data[1] = ((ClassEntry) entry).getFullName();
136 }
137
138 if (data != null) {
139 System.arraycopy(extraFields, 0, data, data.length - extraFields.length, extraFields.length);
140 }
141
142 return data;
143 }
144}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java
deleted file mode 100644
index 28185f58..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java
+++ /dev/null
@@ -1,332 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.tinyv2;
2
3import java.io.IOException;
4import java.nio.charset.StandardCharsets;
5import java.nio.file.Files;
6import java.nio.file.Path;
7import java.util.BitSet;
8import java.util.List;
9
10import cuchaz.enigma.ProgressListener;
11import cuchaz.enigma.translation.mapping.EntryMapping;
12import cuchaz.enigma.translation.mapping.MappingPair;
13import cuchaz.enigma.translation.mapping.serde.MappingParseException;
14import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
15import cuchaz.enigma.translation.mapping.serde.MappingsReader;
16import cuchaz.enigma.translation.mapping.serde.RawEntryMapping;
17import cuchaz.enigma.translation.mapping.tree.EntryTree;
18import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
19import cuchaz.enigma.translation.representation.MethodDescriptor;
20import cuchaz.enigma.translation.representation.TypeDescriptor;
21import cuchaz.enigma.translation.representation.entry.ClassEntry;
22import cuchaz.enigma.translation.representation.entry.Entry;
23import cuchaz.enigma.translation.representation.entry.FieldEntry;
24import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
25import cuchaz.enigma.translation.representation.entry.MethodEntry;
26
27public final class TinyV2Reader implements MappingsReader {
28 private static final String MINOR_VERSION = "0";
29 // 0 indent
30 private static final int IN_HEADER = 0;
31 private static final int IN_CLASS = IN_HEADER + 1;
32 // 1 indent
33 private static final int IN_METHOD = IN_CLASS + 1;
34 private static final int IN_FIELD = IN_METHOD + 1;
35 // 2 indent
36 private static final int IN_PARAMETER = IN_FIELD + 1;
37 // general properties
38 private static final int STATE_SIZE = IN_PARAMETER + 1;
39 private static final int[] INDENT_CLEAR_START = {IN_HEADER, IN_METHOD, IN_PARAMETER, STATE_SIZE};
40
41 @Override
42 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
43 return read(path, Files.readAllLines(path, StandardCharsets.UTF_8), progress);
44 }
45
46 private EntryTree<EntryMapping> read(Path path, List<String> lines, ProgressListener progress) throws MappingParseException {
47 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
48
49 progress.init(lines.size(), "progress.mappings.loading_file");
50
51 BitSet state = new BitSet(STATE_SIZE);
52 @SuppressWarnings({"unchecked", "rawtypes"}) MappingPair<? extends Entry<?>, RawEntryMapping>[] holds = new MappingPair[STATE_SIZE];
53 boolean escapeNames = false;
54
55 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
56 try {
57 progress.step(lineNumber, "");
58 String line = lines.get(lineNumber);
59
60 int indent = 0;
61
62 while (line.charAt(indent) == '\t') {
63 indent++;
64 }
65
66 String[] parts = line.substring(indent).split("\t", -1);
67
68 if (parts.length == 0 || indent >= INDENT_CLEAR_START.length) {
69 throw new IllegalArgumentException("Invalid format");
70 }
71
72 // clean and register stuff in stack
73 for (int i = INDENT_CLEAR_START[indent]; i < STATE_SIZE; i++) {
74 state.clear(i);
75
76 if (holds[i] != null) {
77 bakeHeld(mappings, holds[i]);
78 holds[i] = null;
79 }
80 }
81
82 switch (indent) {
83 case 0:
84 switch (parts[0]) {
85 case "tiny": // header
86 if (lineNumber != 0) {
87 throw new IllegalArgumentException("Header can only be on the first line");
88 }
89
90 if (parts.length < 5) {
91 throw new IllegalArgumentException("Not enough header columns, needs at least 5");
92 }
93
94 if (!"2".equals(parts[1]) || !MINOR_VERSION.equals(parts[2])) {
95 throw new IllegalArgumentException("Unsupported TinyV2 version, requires major " + "2" + " and minor " + MINOR_VERSION + "");
96 }
97
98 state.set(IN_HEADER);
99 break;
100 case "c": // class
101 state.set(IN_CLASS);
102 holds[IN_CLASS] = parseClass(parts, escapeNames);
103 break;
104 default:
105 unsupportKey(parts);
106 }
107
108 break;
109 case 1:
110 if (state.get(IN_HEADER)) {
111 if (parts[0].equals("esacpe-names")) {
112 escapeNames = true;
113 }
114
115 break;
116 }
117
118 if (state.get(IN_CLASS)) {
119 switch (parts[0]) {
120 case "m": // method
121 state.set(IN_METHOD);
122 holds[IN_METHOD] = parseMethod(holds[IN_CLASS], parts, escapeNames);
123 break;
124 case "f": // field
125 state.set(IN_FIELD);
126 holds[IN_FIELD] = parseField(holds[IN_CLASS], parts, escapeNames);
127 break;
128 case "c": // class javadoc
129 addJavadoc(holds[IN_CLASS], parts);
130 break;
131 default:
132 unsupportKey(parts);
133 }
134
135 break;
136 }
137
138 unsupportKey(parts);
139 case 2:
140 if (state.get(IN_METHOD)) {
141 switch (parts[0]) {
142 case "p": // parameter
143 state.set(IN_PARAMETER);
144 holds[IN_PARAMETER] = parseArgument(holds[IN_METHOD], parts, escapeNames);
145 break;
146 case "v": // local variable
147 // TODO add local var mapping
148 break;
149 case "c": // method javadoc
150 addJavadoc(holds[IN_METHOD], parts);
151 break;
152 default:
153 unsupportKey(parts);
154 }
155
156 break;
157 }
158
159 if (state.get(IN_FIELD)) {
160 switch (parts[0]) {
161 case "c": // field javadoc
162 addJavadoc(holds[IN_FIELD], parts);
163 break;
164 default:
165 unsupportKey(parts);
166 }
167
168 break;
169 }
170
171 unsupportKey(parts);
172 case 3:
173 if (state.get(IN_PARAMETER)) {
174 switch (parts[0]) {
175 case "c":
176 addJavadoc(holds[IN_PARAMETER], parts);
177 break;
178 default:
179 unsupportKey(parts);
180 }
181
182 break;
183 }
184
185 unsupportKey(parts);
186 default:
187 unsupportKey(parts);
188 }
189 } catch (Throwable t) {
190 throw new MappingParseException(path, lineNumber + 1, t);
191 }
192 }
193
194 //bake any remainders
195 for (MappingPair<? extends Entry<?>, RawEntryMapping> hold : holds) {
196 if (hold != null) {
197 bakeHeld(mappings, hold);
198 }
199 }
200
201 return mappings;
202 }
203
204 private static void bakeHeld(EntryTree<EntryMapping> mappings, MappingPair<? extends Entry<?>, RawEntryMapping> hold2) {
205 RawEntryMapping mapping = hold2.getMapping();
206
207 if (mapping != null) {
208 EntryMapping baked = mapping.bake();
209
210 if (baked != null) {
211 mappings.insert(hold2.getEntry(), baked);
212 }
213 }
214 }
215
216 private void unsupportKey(String[] parts) {
217 throw new IllegalArgumentException("Unsupported key " + parts[0]);
218 }
219
220 private void addJavadoc(MappingPair<? extends Entry, RawEntryMapping> pair, String[] parts) {
221 if (parts.length != 2) {
222 throw new IllegalArgumentException("Invalid javadoc declaration");
223 }
224
225 addJavadoc(pair, parts[1]);
226 }
227
228 private MappingPair<ClassEntry, RawEntryMapping> parseClass(String[] tokens, boolean escapeNames) {
229 ClassEntry obfuscatedEntry = new ClassEntry(unescapeOpt(tokens[1], escapeNames));
230
231 if (tokens.length <= 2) {
232 return new MappingPair<>(obfuscatedEntry);
233 }
234
235 String token2 = unescapeOpt(tokens[2], escapeNames);
236 String mapping = token2.substring(token2.lastIndexOf('$') + 1);
237 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping));
238 }
239
240 private MappingPair<FieldEntry, RawEntryMapping> parseField(MappingPair<? extends Entry, RawEntryMapping> parent, String[] tokens, boolean escapeNames) {
241 ClassEntry ownerClass = (ClassEntry) parent.getEntry();
242 TypeDescriptor descriptor = new TypeDescriptor(unescapeOpt(tokens[1], escapeNames));
243
244 FieldEntry obfuscatedEntry = new FieldEntry(ownerClass, unescapeOpt(tokens[2], escapeNames), descriptor);
245
246 if (tokens.length <= 3) {
247 return new MappingPair<>(obfuscatedEntry);
248 }
249
250 String mapping = unescapeOpt(tokens[3], escapeNames);
251 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping));
252 }
253
254 private MappingPair<MethodEntry, RawEntryMapping> parseMethod(MappingPair<? extends Entry, RawEntryMapping> parent, String[] tokens, boolean escapeNames) {
255 ClassEntry ownerClass = (ClassEntry) parent.getEntry();
256 MethodDescriptor descriptor = new MethodDescriptor(unescapeOpt(tokens[1], escapeNames));
257
258 MethodEntry obfuscatedEntry = new MethodEntry(ownerClass, unescapeOpt(tokens[2], escapeNames), descriptor);
259
260 if (tokens.length <= 3) {
261 return new MappingPair<>(obfuscatedEntry);
262 }
263
264 String mapping = unescapeOpt(tokens[3], escapeNames);
265 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping));
266 }
267
268 private void addJavadoc(MappingPair<? extends Entry, RawEntryMapping> pair, String javadoc) {
269 RawEntryMapping mapping = pair.getMapping();
270
271 if (mapping == null) {
272 throw new IllegalArgumentException("Javadoc requires a mapping in enigma!");
273 }
274
275 mapping.addJavadocLine(unescape(javadoc));
276 }
277
278 private MappingPair<LocalVariableEntry, RawEntryMapping> parseArgument(MappingPair<? extends Entry, RawEntryMapping> parent, String[] tokens, boolean escapeNames) {
279 MethodEntry ownerMethod = (MethodEntry) parent.getEntry();
280 int variableIndex = Integer.parseInt(tokens[1]);
281
282 // tokens[2] is the useless obf name
283
284 LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerMethod, variableIndex, "", true, null);
285
286 if (tokens.length <= 3) {
287 return new MappingPair<>(obfuscatedEntry);
288 }
289
290 String mapping = unescapeOpt(tokens[3], escapeNames);
291 return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping));
292 }
293
294 private static final String TO_ESCAPE = "\\\n\r\0\t";
295 private static final String ESCAPED = "\\nr0t";
296
297 private static String unescapeOpt(String raw, boolean escapedStrings) {
298 return escapedStrings ? unescape(raw) : raw;
299 }
300
301 private static String unescape(String str) {
302 // copied from matcher, lazy!
303 int pos = str.indexOf('\\');
304
305 if (pos < 0) {
306 return str;
307 }
308
309 StringBuilder ret = new StringBuilder(str.length() - 1);
310 int start = 0;
311
312 do {
313 ret.append(str, start, pos);
314 pos++;
315 int type;
316
317 if (pos >= str.length()) {
318 throw new RuntimeException("incomplete escape sequence at the end");
319 } else if ((type = ESCAPED.indexOf(str.charAt(pos))) < 0) {
320 throw new RuntimeException("invalid escape character: \\" + str.charAt(pos));
321 } else {
322 ret.append(TO_ESCAPE.charAt(type));
323 }
324
325 start = pos + 1;
326 } while ((pos = str.indexOf('\\', start)) >= 0);
327
328 ret.append(str, start, str.length());
329
330 return ret.toString();
331 }
332}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java
deleted file mode 100644
index d85ed6e5..00000000
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java
+++ /dev/null
@@ -1,187 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.tinyv2;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5import java.nio.file.Files;
6import java.nio.file.Path;
7import java.util.Deque;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.stream.StreamSupport;
11
12import cuchaz.enigma.ProgressListener;
13import cuchaz.enigma.translation.mapping.EntryMap;
14import cuchaz.enigma.translation.mapping.EntryMapping;
15import cuchaz.enigma.translation.mapping.MappingDelta;
16import cuchaz.enigma.translation.mapping.serde.LfPrintWriter;
17import cuchaz.enigma.translation.mapping.serde.MappingHelper;
18import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
19import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
20import cuchaz.enigma.translation.mapping.tree.EntryTree;
21import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
22import cuchaz.enigma.translation.representation.entry.ClassEntry;
23import cuchaz.enigma.translation.representation.entry.Entry;
24import cuchaz.enigma.translation.representation.entry.FieldEntry;
25import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
26import cuchaz.enigma.translation.representation.entry.MethodEntry;
27
28public final class TinyV2Writer implements MappingsWriter {
29 private static final String MINOR_VERSION = "0";
30 private final String obfHeader;
31 private final String deobfHeader;
32
33 public TinyV2Writer(String obfHeader, String deobfHeader) {
34 this.obfHeader = obfHeader;
35 this.deobfHeader = deobfHeader;
36 }
37
38 @Override
39 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters parameters) {
40 List<EntryTreeNode<EntryMapping>> classes = StreamSupport.stream(mappings.spliterator(), false).filter(node -> node.getEntry() instanceof ClassEntry).toList();
41
42 try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) {
43 writer.println("tiny\t2\t" + MINOR_VERSION + "\t" + obfHeader + "\t" + deobfHeader);
44
45 // no escape names
46
47 for (EntryTreeNode<EntryMapping> node : classes) {
48 writeClass(writer, node, mappings);
49 }
50 } catch (IOException ex) {
51 ex.printStackTrace(); // TODO add some better logging system
52 }
53 }
54
55 private void writeClass(PrintWriter writer, EntryTreeNode<EntryMapping> node, EntryMap<EntryMapping> tree) {
56 writer.print("c\t");
57 ClassEntry classEntry = (ClassEntry) node.getEntry();
58 String fullName = classEntry.getFullName();
59 writer.print(fullName);
60 Deque<String> parts = new LinkedList<>();
61
62 do {
63 EntryMapping mapping = tree.get(classEntry);
64
65 if (mapping != null && mapping.targetName() != null) {
66 parts.addFirst(mapping.targetName());
67 } else {
68 parts.addFirst(classEntry.getName());
69 }
70
71 classEntry = classEntry.getOuterClass();
72 } while (classEntry != null);
73
74 String mappedName = String.join("$", parts);
75
76 writer.print("\t");
77
78 writer.print(mappedName); // todo escaping when we have v2 fixed later
79
80 writer.println();
81
82 writeComment(writer, node.getValue(), 1);
83
84 for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) {
85 Entry<?> entry = child.getEntry();
86
87 if (entry instanceof FieldEntry) {
88 writeField(writer, child);
89 } else if (entry instanceof MethodEntry) {
90 writeMethod(writer, child);
91 }
92 }
93 }
94
95 private void writeMethod(PrintWriter writer, EntryTreeNode<EntryMapping> node) {
96 writer.print(indent(1));
97 writer.print("m\t");
98 writer.print(((MethodEntry) node.getEntry()).getDesc().toString());
99 writer.print("\t");
100 writer.print(node.getEntry().getName());
101 writer.print("\t");
102 EntryMapping mapping = node.getValue();
103
104 if (mapping == null) {
105 mapping = EntryMapping.DEFAULT;
106 }
107
108 if (mapping.targetName() != null) {
109 writer.println(mapping.targetName());
110 } else {
111 writer.println(node.getEntry().getName()); // todo fix v2 name inference
112 }
113
114 writeComment(writer, mapping, 2);
115
116 for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) {
117 Entry<?> entry = child.getEntry();
118
119 if (entry instanceof LocalVariableEntry) {
120 writeParameter(writer, child);
121 }
122
123 // TODO write actual local variables
124 }
125 }
126
127 private void writeField(PrintWriter writer, EntryTreeNode<EntryMapping> node) {
128 if (node.getValue() == null || node.getValue().equals(EntryMapping.DEFAULT)) {
129 return; // Shortcut
130 }
131
132 writer.print(indent(1));
133 writer.print("f\t");
134 writer.print(((FieldEntry) node.getEntry()).getDesc().toString());
135 writer.print("\t");
136 writer.print(node.getEntry().getName());
137 writer.print("\t");
138 EntryMapping mapping = node.getValue();
139
140 if (mapping == null) {
141 mapping = EntryMapping.DEFAULT;
142 }
143
144 if (mapping.targetName() != null) {
145 writer.println(mapping.targetName());
146 } else {
147 writer.println(node.getEntry().getName()); // todo fix v2 name inference
148 }
149
150 writeComment(writer, mapping, 2);
151 }
152
153 private void writeParameter(PrintWriter writer, EntryTreeNode<EntryMapping> node) {
154 if (node.getValue() == null || node.getValue().equals(EntryMapping.DEFAULT)) {
155 return; // Shortcut
156 }
157
158 writer.print(indent(2));
159 writer.print("p\t");
160 writer.print(((LocalVariableEntry) node.getEntry()).getIndex());
161 writer.print("\t");
162 writer.print(node.getEntry().getName());
163 writer.print("\t");
164 EntryMapping mapping = node.getValue();
165
166 if (mapping == null || mapping.targetName() == null) {
167 writer.println(); // todo ???
168 } else {
169 writer.println(mapping.targetName());
170
171 writeComment(writer, mapping, 3);
172 }
173 }
174
175 private void writeComment(PrintWriter writer, EntryMapping mapping, int indent) {
176 if (mapping != null && mapping.javadoc() != null) {
177 writer.print(indent(indent));
178 writer.print("c\t");
179 writer.print(MappingHelper.escape(mapping.javadoc()));
180 writer.println();
181 }
182 }
183
184 private String indent(int level) {
185 return "\t".repeat(level);
186 }
187}
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json
index e0882b9a..a9c7ac91 100644
--- a/enigma/src/main/resources/lang/en_us.json
+++ b/enigma/src/main/resources/lang/en_us.json
@@ -16,7 +16,6 @@
16 "mapping_format.recaf": "Recaf Simple File", 16 "mapping_format.recaf": "Recaf Simple File",
17 "mapping_format.jobf_file": "JOBF File", 17 "mapping_format.jobf_file": "JOBF File",
18 "mapping_format.intellij_migration_map_file": "IntelliJ Migration Map File", 18 "mapping_format.intellij_migration_map_file": "IntelliJ Migration Map File",
19 "legacy": "legacy",
20 19
21 "type.methods": "Methods", 20 "type.methods": "Methods",
22 "type.fields": "Fields", 21 "type.fields": "Fields",
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestComments.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestComments.java
deleted file mode 100644
index 15ec44e4..00000000
--- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestComments.java
+++ /dev/null
@@ -1,37 +0,0 @@
1package cuchaz.enigma.translation.mapping;
2
3import java.io.IOException;
4import java.net.URISyntaxException;
5import java.nio.file.Path;
6import java.nio.file.Paths;
7
8import org.junit.Test;
9
10import cuchaz.enigma.ProgressListener;
11import cuchaz.enigma.translation.mapping.serde.MappingFileNameFormat;
12import cuchaz.enigma.translation.mapping.serde.MappingParseException;
13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
14import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
15import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
16import cuchaz.enigma.translation.mapping.tree.EntryTree;
17
18public class TestComments {
19 private static Path DIRECTORY;
20
21 static {
22 try {
23 DIRECTORY = Paths.get(TestTinyV2InnerClasses.class.getResource("/comments/").toURI());
24 } catch (URISyntaxException e) {
25 throw new RuntimeException(e);
26 }
27 }
28
29 @Test
30 public void testParseAndWrite() throws IOException, MappingParseException {
31 ProgressListener progressListener = ProgressListener.none();
32 MappingSaveParameters params = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF);
33 EntryTree<EntryMapping> mappings = EnigmaMappingsReader.DIRECTORY.read(DIRECTORY, progressListener, params);
34
35 new TinyV2Writer("intermediary", "named").write(mappings, DIRECTORY.resolve("convertedtiny.tiny"), progressListener, params);
36 }
37}
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 25f11fbc..f665c36d 100644
--- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java
+++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java
@@ -104,11 +104,6 @@ public class TestReadWriteCycle {
104 } 104 }
105 105
106 @Test 106 @Test
107 public void testEnigmaZip() throws IOException, MappingParseException {
108 testReadWriteCycle(MappingFormat.ENIGMA_ZIP, true, ".zip");
109 }
110
111 @Test
112 public void testTinyFile() throws IOException, MappingParseException { 107 public void testTinyFile() throws IOException, MappingParseException {
113 testReadWriteCycle(MappingFormat.TINY_FILE, false, ".tiny"); 108 testReadWriteCycle(MappingFormat.TINY_FILE, false, ".tiny");
114 } 109 }
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java
deleted file mode 100644
index 9164abe7..00000000
--- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java
+++ /dev/null
@@ -1,37 +0,0 @@
1/*******************************************************************************
2* Copyright (c) 2015 Jeff Martin.
3* All rights reserved. This program and the accompanying materials
4* are made available under the terms of the GNU Lesser General Public
5* License v3.0 which accompanies this distribution, and is available at
6* http://www.gnu.org/licenses/lgpl.html
7*
8* <p>Contributors:
9* Jeff Martin - initial API and implementation
10******************************************************************************/
11
12package cuchaz.enigma.translation.mapping;
13
14import java.nio.file.Path;
15import java.nio.file.Paths;
16import java.util.List;
17
18import cuchaz.enigma.Enigma;
19import cuchaz.enigma.EnigmaProject;
20import cuchaz.enigma.ProgressListener;
21import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
22
23public final class TestTinyV2InnerClasses {
24 private Path jar;
25 private Path mappings;
26
27 public TestTinyV2InnerClasses() throws Exception {
28 jar = Paths.get("build/test-obf/innerClasses.jar");
29 mappings = Paths.get(TestTinyV2InnerClasses.class.getResource("/tinyV2InnerClasses/").toURI());
30 }
31
32 // @Test
33 public void testMappings() throws Exception {
34 EnigmaProject project = Enigma.create().openJar(jar, List.of(), ProgressListener.none());
35 project.setMappings(EnigmaMappingsReader.DIRECTORY.read(mappings, ProgressListener.none(), project.getEnigma().getProfile().getMappingSaveParameters()));
36 }
37}
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestV2Main.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestV2Main.java
deleted file mode 100644
index cc08b852..00000000
--- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestV2Main.java
+++ /dev/null
@@ -1,23 +0,0 @@
1package cuchaz.enigma.translation.mapping;
2
3import java.nio.file.Path;
4import java.nio.file.Paths;
5
6import cuchaz.enigma.ProgressListener;
7import cuchaz.enigma.translation.mapping.serde.MappingFileNameFormat;
8import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
9import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
10import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
11import cuchaz.enigma.translation.mapping.tree.EntryTree;
12
13public final class TestV2Main {
14 public static void main(String... args) throws Exception {
15 Path path = Paths.get(TestV2Main.class.getResource("/tinyV2InnerClasses/").toURI());
16
17 MappingSaveParameters parameters = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF);
18
19 EntryTree<EntryMapping> tree = EnigmaMappingsReader.DIRECTORY.read(path, ProgressListener.none(), parameters);
20
21 new TinyV2Writer("obf", "deobf").write(tree, Paths.get("currentYarn.tiny"), ProgressListener.none(), parameters);
22 }
23}
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java
deleted file mode 100644
index 5f3e47c0..00000000
--- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java
+++ /dev/null
@@ -1,45 +0,0 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import static org.junit.Assert.assertEquals;
4
5import java.io.InputStream;
6import java.nio.charset.StandardCharsets;
7import java.nio.file.FileSystem;
8import java.nio.file.Files;
9import java.nio.file.Path;
10import java.util.HashSet;
11import java.util.Set;
12
13import com.google.common.jimfs.Jimfs;
14import org.junit.Test;
15
16import cuchaz.enigma.ProgressListener;
17import cuchaz.enigma.translation.mapping.EntryMapping;
18import cuchaz.enigma.translation.mapping.tree.EntryTree;
19
20public class TestRecaf {
21 @Test
22 public void testIntegrity() throws Exception {
23 Set<String> contents;
24
25 try (InputStream in = getClass().getResourceAsStream("/recaf.mappings")) {
26 contents = Set.of(new String(in.readAllBytes(), StandardCharsets.UTF_8).split("\\R"));
27 }
28
29 try (FileSystem fs = Jimfs.newFileSystem()) {
30 Path path = fs.getPath("recaf.mappings");
31 Files.writeString(path, String.join("\n", contents));
32
33 RecafMappingsWriter writer = RecafMappingsWriter.INSTANCE;
34 RecafMappingsReader reader = RecafMappingsReader.INSTANCE;
35
36 EntryTree<EntryMapping> mappings = reader.read(path, ProgressListener.none(), null);
37 writer.write(mappings, path, ProgressListener.none(), null);
38
39 reader.read(path, ProgressListener.none(), null);
40 Set<String> newContents = new HashSet<>(Files.readAllLines(path));
41
42 assertEquals(contents, newContents);
43 }
44 }
45}
diff --git a/enigma/src/test/resources/comments/test.mapping b/enigma/src/test/resources/comments/test.mapping
deleted file mode 100644
index d1345583..00000000
--- a/enigma/src/test/resources/comments/test.mapping
+++ /dev/null
@@ -1,18 +0,0 @@
1CLASS net/minecraft/class_1158 net/minecraft/util/math/Quaternion
2 COMMENT it circel
3 COMMENT next line
4 FIELD field_21493 IDENTITY Lnet/minecraft/class_1158;
5 COMMENT moar comment thing
6 COMMENT near field
7 METHOD foo bar (FFFF)V
8 COMMENT method comment
9 COMMENT second line
10 COMMENT third line
11 ARG 1 b
12 COMMENT arg comment
13 CLASS old new
14 COMMENT inner comment
15 FIELD field_19263 iterator Lnet/minecraft/class_3980;
16 METHOD tryAdvance (Ljava/util/function/Consumer;)Z
17 ARG 1 consumer
18 COMMENT very inner comment \ No newline at end of file
diff --git a/enigma/src/test/resources/recaf.mappings b/enigma/src/test/resources/recaf.mappings
deleted file mode 100644
index 479099ed..00000000
--- a/enigma/src/test/resources/recaf.mappings
+++ /dev/null
@@ -1,10 +0,0 @@
1a testClass
2a.a Z testField
3a.a()V testMethod0
4a.a(Z)V testMethod1
5a.b()V testMethod2
6a/a testInnerClass
7a/a.a Z testInnerField
8a/a.a()V testInnerMethod0
9a/a.a(Z)V testInnerMethod1
10a/a.b()V testInnerMethod2
diff --git a/enigma/src/test/resources/tinyV2InnerClasses/c.mapping b/enigma/src/test/resources/tinyV2InnerClasses/c.mapping
deleted file mode 100644
index f9b04428..00000000
--- a/enigma/src/test/resources/tinyV2InnerClasses/c.mapping
+++ /dev/null
@@ -1,2 +0,0 @@
1CLASS c
2 CLASS a Kid
diff --git a/enigma/src/test/resources/tinyV2InnerClasses/cuchaz/enigma/Dad.mapping b/enigma/src/test/resources/tinyV2InnerClasses/cuchaz/enigma/Dad.mapping
deleted file mode 100644
index 8d43ba90..00000000
--- a/enigma/src/test/resources/tinyV2InnerClasses/cuchaz/enigma/Dad.mapping
+++ /dev/null
@@ -1,5 +0,0 @@
1CLASS f cuchaz/enigma/Dad
2 CLASS a One
3 CLASS a Two
4 CLASS a
5 FIELD a value I