Skip to content

Commit

Permalink
Fix handling of repeated elements (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
NebelNidas authored Aug 26, 2024
1 parent d84108e commit ed68729
Show file tree
Hide file tree
Showing 24 changed files with 416 additions and 165 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Made some internal methods in Enigma and TSRG readers actually private
- Added missing `visitElementContent` calls to CSRG and Recaf Simple readers
- Fixed member mapping merging via tree-API in `MemoryMappingTree`
- Fixed duplicate mapping definitions not being handled correctly in multiple readers

## [0.6.1] - 2024-04-15
- Fixed CSRG and JAM writers sometimes skipping elements whose parents have incomplete destination names
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,17 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());
srcName = srcName.replace('.', '/');

if (!srcName.equals(lastClass)) {
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);

if (visitLastClass) {
readSeparator(reader);
if (visitLastClass) {
readSeparator(reader);

String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());
String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());

visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
} else if ((isField = reader.nextCol("f")) || reader.nextCol("m")) {
// field: f <cls-a>.<name-a>:<desc-a> = <name-b>
Expand All @@ -113,11 +111,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target

if (!srcOwner.equals(lastClass)) {
lastClass = srcOwner;
visitLastClass = visitor.visitClass(srcOwner);

if (visitLastClass) {
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
visitLastClass = visitor.visitClass(srcOwner) && visitor.visitElementContent(MappedElementKind.CLASS);
}

if (visitLastClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,24 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
if (dotPos < 0) { // class
clsSrcName = parts[0];
clsDstName = parts[1];

lastClass = clsSrcName;
visitClass = visitor.visitClass(clsSrcName);

if (visitClass) {
visitor.visitDstName(MappedElementKind.CLASS, 0, clsDstName);
visitClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
} else { // member
clsSrcName = parts[0].substring(0, dotPos);

if (!clsSrcName.equals(lastClass)) {
lastClass = clsSrcName;
visitClass = visitor.visitClass(clsSrcName) && visitor.visitElementContent(MappedElementKind.CLASS);
}

if (!visitClass) continue;

String memberIdentifier = parts[0].substring(dotPos + 1);
memberDstName = parts[1];

Expand All @@ -117,19 +133,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
} else {
insufficientColumnCount(reader);
}
}

if (!clsSrcName.equals(lastClass)) {
visitClass = visitor.visitClass(clsSrcName);
lastClass = clsSrcName;

if (visitClass) {
if (clsDstName != null) visitor.visitDstName(MappedElementKind.CLASS, 0, clsDstName);
visitClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
}

if (visitClass && memberSrcName != null) {
if (!isMethod && visitor.visitField(memberSrcName, memberSrcDesc)) {
visitor.visitDstName(MappedElementKind.FIELD, 0, memberDstName);
visitor.visitElementContent(MappedElementKind.FIELD);
Expand Down
88 changes: 43 additions & 45 deletions src/main/java/net/fabricmc/mappingio/format/srg/JamFileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
}

if (visitor.visitContent()) {
String lastClass = null;
boolean visitLastClass = false;
String lastMethod = null;
boolean visitLastMethod = false;
boolean visitLastMethodContent = false;
String lastClassName = null;
boolean visitClass = false;
String lastMethodName = null;
String lastMethodDesc = null;
boolean visitMember = false;
boolean visitMethodContent = false;

do {
boolean isMethod;
Expand All @@ -81,22 +82,20 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
String srcName = reader.nextCol();
if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

if (!srcName.equals(lastClass)) {
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);
lastClassName = srcName;
visitClass = visitor.visitClass(srcName);

if (visitLastClass) {
String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());
if (visitClass) {
String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());

visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
visitClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
} else if ((isMethod = reader.nextCol("MD")) || reader.nextCol("FD") // method/field: MD/FD <cls-a> <name-a> <desc-a> <name-b>
|| (isArg = reader.nextCol("MP"))) { // parameter: MP <cls-a> <mth-name-a> <mth-desc-a> <arg-pos> [<arg-desc-a>] <name-b>
String clsSrcClsName = reader.nextCol();
if (clsSrcClsName == null) throw new IOException("missing class-name-a in line "+reader.getLineNumber());
String clsSrcName = reader.nextCol();
if (clsSrcName == null) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

String memberSrcName = reader.nextCol();
if (memberSrcName == null || memberSrcName.isEmpty()) throw new IOException("missing member-name-a in line "+reader.getLineNumber());
Expand Down Expand Up @@ -129,44 +128,43 @@ private static void read(ColumnFileReader reader, String sourceNs, String target

if (dstName == null || dstName.isEmpty()) throw new IOException("missing name-b in line "+reader.getLineNumber());

if (!clsSrcClsName.equals(lastClass)) {
lastClass = clsSrcClsName;
visitLastClass = visitor.visitClass(clsSrcClsName);

if (visitLastClass) {
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
if (!clsSrcName.equals(lastClassName)) {
lastClassName = clsSrcName;
lastMethodName = null;
lastMethodDesc = null;
visitClass = visitor.visitClass(clsSrcName) && visitor.visitElementContent(MappedElementKind.CLASS);
}

if (!visitLastClass) continue;
boolean isNewMethod = false;
if (!visitClass) continue;
boolean newMethod = false;
boolean isField = !isMethod && !isArg;

if (!isField && !memberSrcName.equals(lastMethod)) {
isNewMethod = true;
lastMethod = memberSrcName;
visitLastMethod = visitor.visitMethod(memberSrcName, memberSrcDesc);
visitLastMethodContent = false;
if (isField) {
visitMember = visitor.visitField(memberSrcName, memberSrcDesc);
} else if (!isArg || (newMethod = !memberSrcName.equals(lastMethodName) || !memberSrcDesc.equals(lastMethodDesc))) {
lastMethodName = memberSrcName;
lastMethodDesc = memberSrcDesc;
visitMember = visitor.visitMethod(memberSrcName, memberSrcDesc);
visitMethodContent = false;
}

if (!visitMember) continue;

if (isField) {
if (visitor.visitField(memberSrcName, memberSrcDesc)) {
visitor.visitDstName(MappedElementKind.FIELD, 0, dstName);
visitor.visitElementContent(MappedElementKind.FIELD);
}
} else if (visitLastMethod) {
if (isMethod) {
visitor.visitDstName(MappedElementKind.METHOD, 0, dstName);
}
visitor.visitDstName(MappedElementKind.FIELD, 0, dstName);
visitor.visitElementContent(MappedElementKind.FIELD);
continue;
} else if (isMethod) {
visitor.visitDstName(MappedElementKind.METHOD, 0, dstName);
}

if (isMethod || isNewMethod) {
visitLastMethodContent = visitor.visitElementContent(MappedElementKind.METHOD);
}
if (isMethod || newMethod) {
visitMethodContent = visitor.visitElementContent(MappedElementKind.METHOD);
}

if (isArg && visitLastMethodContent && visitor.visitMethodArg(argSrcPos, -1, null)) {
visitor.visitDstName(MappedElementKind.METHOD_ARG, 0, dstName);
visitor.visitElementContent(MappedElementKind.METHOD_ARG);
}
if (isArg && visitMethodContent && visitor.visitMethodArg(argSrcPos, -1, null)) {
visitor.visitDstName(MappedElementKind.METHOD_ARG, 0, dstName);
visitor.visitElementContent(MappedElementKind.METHOD_ARG);
}
}
} while (reader.nextLine(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
} else if (targetKind == MappedElementKind.FIELD
|| (isMethod = targetKind == MappedElementKind.METHOD)
|| (isArg = targetKind == MappedElementKind.METHOD_ARG)) {
if (classOnlyPass) {
if (classOnlyPass || memberSrcDesc == null) {
return false;
} else if (memberSrcDesc == null || (!isArg && memberDstName == null)) {
} else if (!isArg && memberDstName == null) {
return isMethod;
}

Expand Down
76 changes: 50 additions & 26 deletions src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
}

if (visitor.visitContent()) {
String lastClass = null;
boolean visitLastClass = false;
String lastClassSrcName = null;
String lastClassDstName = null;
boolean classContentVisitPending = false;

do {
boolean isMethod;
Expand All @@ -79,17 +80,20 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
String srcName = reader.nextCol();
if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

if (!srcName.equals(lastClass)) {
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);
if (classContentVisitPending) {
visitor.visitElementContent(MappedElementKind.CLASS);
classContentVisitPending = false;
}

if (visitLastClass) {
String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());
lastClassSrcName = srcName;

visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
if (visitor.visitClass(srcName)) {
String dstName = reader.nextCol();
if (dstName == null || dstName.isEmpty()) throw new IOException("missing class-name-b in line "+reader.getLineNumber());

lastClassDstName = dstName;
visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
classContentVisitPending = true;
}
} else if ((isMethod = reader.nextCol("MD:")) || reader.nextCol("FD:")) { // method: MD: <cls-a><name-a> <desc-a> <cls-b><name-b> <desc-b> or field: FD: <cls-a><name-a> <cls-b><name-b>
String src = reader.nextCol();
Expand Down Expand Up @@ -127,30 +131,50 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
if (dstSepPos <= 0 || dstSepPos == dstName.length() - 1) throw new IOException("invalid class-/name-b in line "+reader.getLineNumber());

String srcOwner = src.substring(0, srcSepPos);
String dstOwner = dstName.substring(0, dstSepPos);
boolean classVisitRequired = !srcOwner.equals(lastClassSrcName) || !dstOwner.equals(lastClassDstName);

if (!srcOwner.equals(lastClass)) {
lastClass = srcOwner;
visitLastClass = visitor.visitClass(srcOwner);
if (classVisitRequired) {
if (classContentVisitPending) {
visitor.visitElementContent(MappedElementKind.CLASS);
classContentVisitPending = false;
}

if (visitLastClass) {
visitor.visitDstName(MappedElementKind.CLASS, 0, dstName.substring(0, dstSepPos));
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
if (!visitor.visitClass(srcOwner)) {
lastClassSrcName = srcOwner;
continue;
}

classContentVisitPending = true;
}

if (visitLastClass) {
String srcName = src.substring(srcSepPos + 1);
lastClassSrcName = srcOwner;

if (isMethod && visitor.visitMethod(srcName, srcDesc)
|| !isMethod && visitor.visitField(srcName, srcDesc)) {
MappedElementKind kind = isMethod ? MappedElementKind.METHOD : MappedElementKind.FIELD;
visitor.visitDstName(kind, 0, dstName.substring(dstSepPos + 1));
visitor.visitDstDesc(kind, 0, dstDesc);
visitor.visitElementContent(kind);
}
if (classVisitRequired) {
visitor.visitDstName(MappedElementKind.CLASS, 0, dstOwner);
lastClassDstName = dstOwner;
}

if (classContentVisitPending) {
classContentVisitPending = false;
if (!visitor.visitElementContent(MappedElementKind.CLASS)) continue;
}

String srcName = src.substring(srcSepPos + 1);

if (isMethod && visitor.visitMethod(srcName, srcDesc)
|| !isMethod && visitor.visitField(srcName, srcDesc)) {
MappedElementKind kind = isMethod ? MappedElementKind.METHOD : MappedElementKind.FIELD;
visitor.visitDstName(kind, 0, dstName.substring(dstSepPos + 1));
visitor.visitDstDesc(kind, 0, dstDesc);
visitor.visitElementContent(kind);
}
}
} while (reader.nextLine(0));

if (classContentVisitPending) {
visitor.visitElementContent(MappedElementKind.CLASS);
}
}

if (visitor.visitEnd()) break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,11 @@ private static void read(ColumnFileReader reader, String sourceNs, String target
if (srcName == null || srcName.endsWith("/")) continue;
if (srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

if (!srcName.equals(lastClass)) {
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);

if (visitLastClass) {
visitLastClass = readClass(reader, format == MappingFormat.TSRG_2_FILE, dstNsCount, nameTmp, visitor);
}
if (visitLastClass) {
visitLastClass = readClass(reader, format == MappingFormat.TSRG_2_FILE, dstNsCount, nameTmp, visitor);
}
} while (reader.nextLine(0));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws

if (visitor.visitContent()) {
String lastClass = null;
boolean lastClassDstNamed = false;;
boolean visitLastClass = false;

while (reader.nextLine(0)) {
Expand All @@ -111,23 +110,19 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws
String srcName = reader.nextCol();
if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

if (!lastClassDstNamed || !srcName.equals(lastClass)) {
lastClass = srcName;
lastClassDstNamed = true;
visitLastClass = visitor.visitClass(srcName);
lastClass = srcName;
visitLastClass = visitor.visitClass(srcName);

if (visitLastClass) {
readDstNames(reader, MappedElementKind.CLASS, dstNsCount, visitor);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
if (visitLastClass) {
readDstNames(reader, MappedElementKind.CLASS, dstNsCount, visitor);
visitLastClass = visitor.visitElementContent(MappedElementKind.CLASS);
}
} else if ((isMethod = reader.nextCol("METHOD")) || reader.nextCol("FIELD")) { // method: METHOD cls-a desc-a <names>... or field: FIELD cls-a desc-a <names>...
String srcOwner = reader.nextCol();
if (srcOwner == null || srcOwner.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber());

if (!srcOwner.equals(lastClass)) {
lastClass = srcOwner;
lastClassDstNamed = false;
visitLastClass = visitor.visitClass(srcOwner) && visitor.visitElementContent(MappedElementKind.CLASS);
}

Expand Down
1 change: 1 addition & 0 deletions src/test/java/net/fabricmc/mappingio/TestHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ public static MemoryMappingTree getCorrespondingTree(Path dir) {
public static final Path DETECTION = getResource("/detection/");
public static final Path VALID = getResource("/read/valid/");
public static final Path VALID_WITH_HOLES = getResource("/read/valid-with-holes/");
public static final Path REPEATED_ELEMENTS = getResource("/read/repeated-elements/");
}

private static final String fldDesc = "I";
Expand Down
Loading

0 comments on commit ed68729

Please sign in to comment.