From e8acce35310410f7deb9e49ae727fd9ed8929c57 Mon Sep 17 00:00:00 2001 From: Julian Burner <48808497+NebelNidas@users.noreply.github.com> Date: Thu, 16 Jan 2025 02:52:09 +0100 Subject: [PATCH] Make Enigma writer always output destination names if visited explicitly (#125) --- CHANGELOG.md | 1 + .../format/enigma/EnigmaDirWriter.java | 93 ++++++++----------- .../format/enigma/EnigmaFileWriter.java | 15 +-- .../format/enigma/EnigmaWriterBase.java | 19 +++- .../enigma-dir/class1Ns0Rename.mapping | 4 +- .../enigma.mappings | 4 +- .../enigma-dir/class1Ns0Rename.mapping | 4 +- .../propagated/enigma.mappings | 4 +- .../unpropagated/enigma-dir/class_1.mapping | 4 +- .../unpropagated/enigma.mappings | 4 +- 10 files changed, 73 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6561443c..4b38e6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Made `OuterClassNamePropagator` configurable +- Made Enigma writer always output destination names if visited explicitly, establishing consistency across all writers - Added a simplified `MappingNsCompleter` constructor for completing all destination names with the source names ## [0.7.1] - 2025-01-07 diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java index 48709835..2a43a45a 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.List; -import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.format.MappingFormat; /** @@ -80,75 +79,65 @@ public void close() throws IOException { } @Override - public boolean visitElementContent(MappedElementKind targetKind) throws IOException { - if (targetKind == MappedElementKind.CLASS) { - String name = dstName != null ? dstName : srcClassName; - - if (currentClass == null - || !name.startsWith(currentClass) - || name.length() > currentClass.length() && name.charAt(currentClass.length()) != '$') { - int pos = getNextOuterEnd(name, 0); - if (pos >= 0) name = name.substring(0, pos); - - // currentClass is not an outer class of srcName (or the same) - Path file = dir.resolve(name + "." + MappingFormat.ENIGMA_FILE.fileExt).normalize(); - if (!file.startsWith(dir)) throw new RuntimeException("invalid name: " + name); - - if (writer != null) { - writer.close(); - } + void visitClassContent() throws IOException { + String name = dstName != null ? dstName : srcClassName; + + if (currentClass == null + || !name.startsWith(currentClass) + || name.length() > currentClass.length() && name.charAt(currentClass.length()) != '$') { + int pos = getNextOuterEnd(name, 0); + if (pos >= 0) name = name.substring(0, pos); - currentClass = name; + // currentClass is not an outer class of srcName (or the same) + Path file = dir.resolve(name + "." + MappingFormat.ENIGMA_FILE.fileExt).normalize(); + if (!file.startsWith(dir)) throw new RuntimeException("invalid name: " + name); - if (Files.exists(file)) { - // initialize writtenClass with last CLASS entry + if (writer != null) { + writer.close(); + } - List writtenClassParts = new ArrayList<>(); + currentClass = name; - try (BufferedReader reader = Files.newBufferedReader(file)) { - String line; + if (Files.exists(file)) { + // initialize writtenClass with last CLASS entry - while ((line = reader.readLine()) != null) { - int offset = 0; + List writtenClassParts = new ArrayList<>(); - while (offset < line.length() && line.charAt(offset) == '\t') { - offset++; - } + try (BufferedReader reader = Files.newBufferedReader(file)) { + String line; - if (line.startsWith("CLASS ", offset)) { - int start = offset + 6; - int end = line.indexOf(' ', start); - if (end < 0) end = line.length(); - String part = line.substring(start, end); + while ((line = reader.readLine()) != null) { + int offset = 0; - while (writtenClassParts.size() > offset) { - writtenClassParts.remove(writtenClassParts.size() - 1); - } + while (offset < line.length() && line.charAt(offset) == '\t') { + offset++; + } + + if (line.startsWith("CLASS ", offset)) { + int start = offset + 6; + int end = line.indexOf(' ', start); + if (end < 0) end = line.length(); + String part = line.substring(start, end); - writtenClassParts.add(part); + while (writtenClassParts.size() > offset) { + writtenClassParts.remove(writtenClassParts.size() - 1); } + + writtenClassParts.add(part); } } - - lastWrittenClass = String.join("$", writtenClassParts); - } else { - lastWrittenClass = ""; - Files.createDirectories(file.getParent()); } - writer = Files.newBufferedWriter(file, StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE); + lastWrittenClass = String.join("$", writtenClassParts); + } else { + lastWrittenClass = ""; + Files.createDirectories(file.getParent()); } - writeMismatchedOrMissingClasses(); - } else if (targetKind == MappedElementKind.FIELD || targetKind == MappedElementKind.METHOD) { - writer.write(' '); - writer.write(desc); - writer.write('\n'); - } else { - writer.write('\n'); + writer = Files.newBufferedWriter(file, StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE); } - return true; + writeMismatchedOrMissingClasses(); } private final Path dir; diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java index bc920c37..32db3d61 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.Writer; -import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.format.MappingFormat; /** @@ -31,17 +30,7 @@ public EnigmaFileWriter(Writer writer) throws IOException { } @Override - public boolean visitElementContent(MappedElementKind targetKind) throws IOException { - if (targetKind == MappedElementKind.CLASS) { - writeMismatchedOrMissingClasses(); - } else if (targetKind == MappedElementKind.FIELD || targetKind == MappedElementKind.METHOD) { - writer.write(' '); - writer.write(desc); - writer.write('\n'); - } else { - writer.write('\n'); - } - - return true; + void visitClassContent() throws IOException { + writeMismatchedOrMissingClasses(); } } diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java index fd2fc98d..03c519a1 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java @@ -106,7 +106,21 @@ public void visitDstName(MappedElementKind targetKind, int namespace, String nam } @Override - public abstract boolean visitElementContent(MappedElementKind targetKind) throws IOException; + public final boolean visitElementContent(MappedElementKind targetKind) throws IOException { + if (targetKind == MappedElementKind.CLASS) { + visitClassContent(); + } else if (targetKind == MappedElementKind.FIELD || targetKind == MappedElementKind.METHOD) { + writer.write(' '); + writer.write(desc); + writer.write('\n'); + } else { + writer.write('\n'); + } + + return true; + } + + abstract void visitClassContent() throws IOException; protected static int getNextOuterEnd(String name, int startPos) { int pos; @@ -185,7 +199,8 @@ protected void writeMismatchedOrMissingClasses() throws IOException { if (dstEnd < 0) dstEnd = dstName.length(); int dstLen = dstEnd - dstStart; - if (dstLen != srcLen || !srcClassName.regionMatches(srcStart, dstName, dstStart, srcLen)) { // src != dst + if (dstLen != srcLen || !srcClassName.regionMatches(srcStart, dstName, dstStart, srcLen) // src != dst + || dstEnd == dstName.length()) { // always write innermost destination name writer.write(' '); writer.write(dstName, dstStart, dstLen); } diff --git a/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma-dir/class1Ns0Rename.mapping b/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma-dir/class1Ns0Rename.mapping index 9340f589..ca76c972 100644 --- a/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma-dir/class1Ns0Rename.mapping +++ b/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma-dir/class1Ns0Rename.mapping @@ -1,6 +1,6 @@ CLASS class_1 class1Ns0Rename FIELD field_1 field_1 Lclass_1; - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3; diff --git a/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma.mappings b/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma.mappings index 9340f589..ca76c972 100644 --- a/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma.mappings +++ b/src/test/resources/outer-class-name-propagation/propagated-except-remapped-dst/enigma.mappings @@ -1,6 +1,6 @@ CLASS class_1 class1Ns0Rename FIELD field_1 field_1 Lclass_1; - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3; diff --git a/src/test/resources/outer-class-name-propagation/propagated/enigma-dir/class1Ns0Rename.mapping b/src/test/resources/outer-class-name-propagation/propagated/enigma-dir/class1Ns0Rename.mapping index 9340f589..ca76c972 100644 --- a/src/test/resources/outer-class-name-propagation/propagated/enigma-dir/class1Ns0Rename.mapping +++ b/src/test/resources/outer-class-name-propagation/propagated/enigma-dir/class1Ns0Rename.mapping @@ -1,6 +1,6 @@ CLASS class_1 class1Ns0Rename FIELD field_1 field_1 Lclass_1; - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3; diff --git a/src/test/resources/outer-class-name-propagation/propagated/enigma.mappings b/src/test/resources/outer-class-name-propagation/propagated/enigma.mappings index 9340f589..ca76c972 100644 --- a/src/test/resources/outer-class-name-propagation/propagated/enigma.mappings +++ b/src/test/resources/outer-class-name-propagation/propagated/enigma.mappings @@ -1,6 +1,6 @@ CLASS class_1 class1Ns0Rename FIELD field_1 field_1 Lclass_1; - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3; diff --git a/src/test/resources/outer-class-name-propagation/unpropagated/enigma-dir/class_1.mapping b/src/test/resources/outer-class-name-propagation/unpropagated/enigma-dir/class_1.mapping index 137aa22e..f68d72fd 100644 --- a/src/test/resources/outer-class-name-propagation/unpropagated/enigma-dir/class_1.mapping +++ b/src/test/resources/outer-class-name-propagation/unpropagated/enigma-dir/class_1.mapping @@ -1,5 +1,5 @@ CLASS class_1 - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3; diff --git a/src/test/resources/outer-class-name-propagation/unpropagated/enigma.mappings b/src/test/resources/outer-class-name-propagation/unpropagated/enigma.mappings index 9340f589..ca76c972 100644 --- a/src/test/resources/outer-class-name-propagation/unpropagated/enigma.mappings +++ b/src/test/resources/outer-class-name-propagation/unpropagated/enigma.mappings @@ -1,6 +1,6 @@ CLASS class_1 class1Ns0Rename FIELD field_1 field_1 Lclass_1; - CLASS class_2 + CLASS class_2 class_2 FIELD field_2 field_2 Lclass_1$class_2; - CLASS class_3 + CLASS class_3 class_3 FIELD field_2 field_2 Lclass_1$class_2$class_3;