diff --git a/CHANGELOG.md b/CHANGELOG.md index e2524cab..14e71b8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- Added a simplified `MappingNsCompleter` constructor for completing all destination names with the source names - 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 - Adjusted format detection to only return ENIGMA_DIR for non-empty directories with at least one `.mapping` file +- Fixed writer NPEs when metadata or member source descriptors are null +- Fixed SRG writer omitting fields with missing source descriptors ## [0.7.1] - 2025-01-07 - Restored the ability to read source-namespace-only mapping files, even if not spec-compliant diff --git a/src/main/java/net/fabricmc/mappingio/MappingVisitor.java b/src/main/java/net/fabricmc/mappingio/MappingVisitor.java index 5b3389cd..7dd01e12 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/MappingVisitor.java @@ -37,7 +37,7 @@ * * *
The elements with a skip-return (Header/Content/Class/Field/Method/Arg/Var/ElementContent) abort processing the - * remainder of their associated item in the above listing if requested by a {@code true} return value. For example + * remainder of their associated item in the above listing if requested by a {@code false} return value. For example * skipping in Class does neither DstName nor ElementContent, but continues with another class or End. * *
Returning {@code false} in End requests another complete visitation pass if the flag
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 03c519a1..02713e40 100644
--- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java
+++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java
@@ -59,6 +59,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
writeIndent(0);
writer.write("FIELD ");
writer.write(srcName);
@@ -70,6 +74,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
writeIndent(0);
writer.write("METHOD ");
writer.write(srcName);
diff --git a/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapConstants.java b/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapConstants.java
index b9da53eb..b9989b63 100644
--- a/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapConstants.java
+++ b/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapConstants.java
@@ -25,4 +25,5 @@ private MigrationMapConstants() {
public static final String ORDER_KEY = "migrationmap:order";
public static final String MISSING_NAME = "Unnamed migration map";
+ public static final String DEFAULT_ORDER = "0";
}
diff --git a/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileWriter.java
index 45ed47ae..95c9b5e2 100644
--- a/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileWriter.java
@@ -55,7 +55,7 @@ public void close() throws IOException {
if (!wroteOrder) {
xmlWriter.writeCharacters("\n\t");
xmlWriter.writeEmptyElement("order");
- xmlWriter.writeAttribute("value", "0");
+ xmlWriter.writeAttribute("value", MigrationMapConstants.DEFAULT_ORDER);
}
xmlWriter.writeCharacters("\n");
@@ -101,9 +101,11 @@ public void visitMetadata(String key, @Nullable String value) throws IOException
try {
switch (key) {
case "name":
+ if (value == null) return;
wroteName = true;
break;
case MigrationMapConstants.ORDER_KEY:
+ if (value == null) return;
wroteOrder = true;
key = "order";
break;
@@ -111,7 +113,10 @@ public void visitMetadata(String key, @Nullable String value) throws IOException
xmlWriter.writeCharacters("\n\t");
xmlWriter.writeEmptyElement(key);
- xmlWriter.writeAttribute("value", value);
+
+ if (value != null) {
+ xmlWriter.writeAttribute("value", value);
+ }
} catch (XMLStreamException e) {
throw new IOException(e);
}
diff --git a/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileWriter.java
index 15da0320..39af0dbe 100644
--- a/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileWriter.java
@@ -61,6 +61,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
dstName = null;
@@ -70,6 +74,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
dstName = null;
@@ -114,7 +122,6 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
write("c ");
} else if ((isField = targetKind == MappedElementKind.FIELD)
|| targetKind == MappedElementKind.METHOD) {
- if (memberSrcDesc == null) return false;
write(isField ? "f " : "m ");
} else {
throw new IllegalStateException("unexpected invocation for "+targetKind);
diff --git a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java
index cd771bcc..81113987 100644
--- a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java
@@ -110,6 +110,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
@@ -118,6 +122,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
diff --git a/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileWriter.java
index 47e16586..574c7cae 100644
--- a/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileWriter.java
@@ -66,6 +66,10 @@ public boolean visitField(String srcName, String srcDesc) throws IOException {
@Override
public boolean visitMethod(String srcName, String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/CsrgFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/srg/CsrgFileWriter.java
index 7bd17a82..50ceedbb 100644
--- a/src/main/java/net/fabricmc/mappingio/format/srg/CsrgFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/srg/CsrgFileWriter.java
@@ -68,6 +68,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
methodSrcDesc = srcDesc;
diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java
index f39bac3d..d7822a74 100644
--- a/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java
@@ -61,6 +61,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
memberDstName = null;
diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileWriter.java
index 377d3876..84251990 100644
--- a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileWriter.java
@@ -63,6 +63,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (xsrg && srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
memberDstName = null;
@@ -73,6 +77,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
memberDstName = null;
@@ -123,11 +131,11 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
write("CL: ");
break;
case FIELD:
- if (memberSrcDesc == null || memberDstName == null || (xsrg && memberDstDesc == null)) return false;
+ if (memberDstName == null || xsrg && memberDstDesc == null) return false;
write("FD: ");
break;
case METHOD:
- if (memberSrcDesc == null || memberDstName == null || memberDstDesc == null) return false;
+ if (memberDstName == null || memberDstDesc == null) return false;
write("MD: ");
break;
default:
diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileWriter.java
index 5acd1884..1536914b 100644
--- a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileWriter.java
@@ -91,6 +91,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
hasAnyDstNames = false;
@@ -183,7 +187,7 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
write(srcName);
if (targetKind == MappedElementKind.METHOD
- || (targetKind == MappedElementKind.FIELD && tsrg2)) {
+ || (targetKind == MappedElementKind.FIELD && tsrg2 && memberSrcDesc != null)) {
writeSpace();
write(memberSrcDesc);
}
diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java
index 511afaa2..167e730e 100644
--- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java
@@ -100,6 +100,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
@@ -108,6 +112,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
memberSrcName = srcName;
memberSrcDesc = srcDesc;
diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java
index 2931845c..cf4d0777 100644
--- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java
+++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java
@@ -108,6 +108,10 @@ public boolean visitClass(String srcName) throws IOException {
@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
write("\tf\t");
writeName(srcDesc);
writeTab();
@@ -118,6 +122,10 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc
@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
+ if (srcDesc == null) {
+ return false;
+ }
+
write("\tm\t");
writeName(srcDesc);
writeTab();
diff --git a/src/test/java/net/fabricmc/mappingio/test/NameGen.java b/src/test/java/net/fabricmc/mappingio/test/NameGen.java
index 2772fd34..bcfa6ac4 100644
--- a/src/test/java/net/fabricmc/mappingio/test/NameGen.java
+++ b/src/test/java/net/fabricmc/mappingio/test/NameGen.java
@@ -253,8 +253,8 @@ private String getPrefix(MappedElementKind kind) {
private static final String argPrefix = "param";
private static final String varPrefix = "var";
private static final String comment = "This is a comment";
- private static final List