From ed68729272ae27f8199de1b55afa06e49dfad171 Mon Sep 17 00:00:00 2001 From: NebelNidas <48808497+NebelNidas@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:00:03 +0200 Subject: [PATCH] Fix handling of repeated elements (#107) --- CHANGELOG.md | 1 + .../mappingio/format/jobf/JobfFileReader.java | 24 ++--- .../format/simple/RecafSimpleFileReader.java | 28 +++--- .../mappingio/format/srg/JamFileReader.java | 88 ++++++++--------- .../mappingio/format/srg/JamFileWriter.java | 4 +- .../mappingio/format/srg/SrgFileReader.java | 76 +++++++++----- .../mappingio/format/srg/TsrgFileReader.java | 10 +- .../format/tiny/Tiny1FileReader.java | 15 +-- .../net/fabricmc/mappingio/TestHelper.java | 1 + .../mappingio/VisitOrderVerifyingVisitor.java | 98 ++++++++++++------- .../mappingio/read/ValidContentReadTest.java | 64 +++++++++--- .../read/repeated-elements/csrg.csrg | 12 +++ .../read/repeated-elements/enigma.mappings | 17 ++++ .../resources/read/repeated-elements/jam.jam | 14 +++ .../read/repeated-elements/jobf.jobf | 12 +++ .../read/repeated-elements/migration-map.xml | 10 ++ .../read/repeated-elements/proguard.txt | 12 +++ .../read/repeated-elements/recaf-simple.txt | 12 +++ .../resources/read/repeated-elements/srg.srg | 12 +++ .../read/repeated-elements/tiny.tiny | 13 +++ .../read/repeated-elements/tinyV2.tiny | 19 ++++ .../read/repeated-elements/tsrg.tsrg | 12 +++ .../read/repeated-elements/tsrgV2.tsrg | 15 +++ .../read/repeated-elements/xsrg.xsrg | 12 +++ 24 files changed, 416 insertions(+), 165 deletions(-) create mode 100644 src/test/resources/read/repeated-elements/csrg.csrg create mode 100644 src/test/resources/read/repeated-elements/enigma.mappings create mode 100644 src/test/resources/read/repeated-elements/jam.jam create mode 100644 src/test/resources/read/repeated-elements/jobf.jobf create mode 100644 src/test/resources/read/repeated-elements/migration-map.xml create mode 100644 src/test/resources/read/repeated-elements/proguard.txt create mode 100644 src/test/resources/read/repeated-elements/recaf-simple.txt create mode 100644 src/test/resources/read/repeated-elements/srg.srg create mode 100644 src/test/resources/read/repeated-elements/tiny.tiny create mode 100644 src/test/resources/read/repeated-elements/tinyV2.tiny create mode 100644 src/test/resources/read/repeated-elements/tsrg.tsrg create mode 100644 src/test/resources/read/repeated-elements/tsrgV2.tsrg create mode 100644 src/test/resources/read/repeated-elements/xsrg.xsrg diff --git a/CHANGELOG.md b/CHANGELOG.md index e27a4b0a..7dde2bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileReader.java b/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileReader.java index ce007a6e..a776e9ae 100644 --- a/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/jobf/JobfFileReader.java @@ -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 .: = @@ -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) { diff --git a/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileReader.java b/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileReader.java index 6fbdd887..cfc17944 100644 --- a/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/simple/RecafSimpleFileReader.java @@ -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]; @@ -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); diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/JamFileReader.java b/src/main/java/net/fabricmc/mappingio/format/srg/JamFileReader.java index 42c5fa56..093a41bc 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/JamFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/JamFileReader.java @@ -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; @@ -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 || (isArg = reader.nextCol("MP"))) { // parameter: MP [] - 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()); @@ -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)); 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 81d6861a..f39bac3d 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/JamFileWriter.java @@ -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; } diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java index 02e0ce92..7884b41a 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java @@ -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; @@ -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: or field: FD: String src = reader.nextCol(); @@ -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; diff --git a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java index e5f75eb1..cb02e054 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java @@ -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)); } diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java index e2cf183f..1c740dc8 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java @@ -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)) { @@ -111,15 +110,12 @@ 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 ... or field: FIELD cls-a desc-a ... String srcOwner = reader.nextCol(); @@ -127,7 +123,6 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws if (!srcOwner.equals(lastClass)) { lastClass = srcOwner; - lastClassDstNamed = false; visitLastClass = visitor.visitClass(srcOwner) && visitor.visitElementContent(MappedElementKind.CLASS); } diff --git a/src/test/java/net/fabricmc/mappingio/TestHelper.java b/src/test/java/net/fabricmc/mappingio/TestHelper.java index 7d227b94..bae2c536 100644 --- a/src/test/java/net/fabricmc/mappingio/TestHelper.java +++ b/src/test/java/net/fabricmc/mappingio/TestHelper.java @@ -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"; diff --git a/src/test/java/net/fabricmc/mappingio/VisitOrderVerifyingVisitor.java b/src/test/java/net/fabricmc/mappingio/VisitOrderVerifyingVisitor.java index 43c4a220..4092f250 100644 --- a/src/test/java/net/fabricmc/mappingio/VisitOrderVerifyingVisitor.java +++ b/src/test/java/net/fabricmc/mappingio/VisitOrderVerifyingVisitor.java @@ -32,7 +32,12 @@ */ public class VisitOrderVerifyingVisitor extends ForwardingMappingVisitor { public VisitOrderVerifyingVisitor(MappingVisitor next) { + this(next, false); + } + + public VisitOrderVerifyingVisitor(MappingVisitor next, boolean allowConsecutiveDuplicateElementVisits) { super(next); + this.allowConsecutiveDuplicateElementVisits = allowConsecutiveDuplicateElementVisits; init(); } @@ -46,19 +51,27 @@ private void init() { visitedMethod = false; visitedMethodArg = false; visitedMethodVar = false; - resetVisitedElementContentUpTo(0); + resetVisitedElementContentDownTo(0); visitedEnd = false; lastVisitedElement = null; visitedLastElement = false; - lastSrcInfo.clear(); + resetLastSrcInfoDownTo(0); } - private void resetVisitedElementContentUpTo(int inclusiveLevel) { + private void resetVisitedElementContentDownTo(int inclusiveLevel) { for (int i = visitedElementContent.length - 1; i >= inclusiveLevel; i--) { visitedElementContent[i] = false; } } + private void resetLastSrcInfoDownTo(int inclusiveLevel) { + for (MappedElementKind kind : MappedElementKind.values()) { + if (kind.level >= inclusiveLevel) { + lastSrcInfo.remove(kind); + } + } + } + @Override public boolean visitHeader() throws IOException { assertHeaderNotVisited(); @@ -106,6 +119,7 @@ public boolean visitClass(String srcName) throws IOException { assertContentVisited(); assertLastElementContentVisited(); + resetLastSrcInfoDownTo(elementKind.level); assertNewSrcInfo(elementKind, srcInfo); visitedClass = true; @@ -115,7 +129,7 @@ public boolean visitClass(String srcName) throws IOException { visitedMethodVar = false; lastVisitedElement = elementKind; lastSrcInfo.put(elementKind, srcInfo); - resetVisitedElementContentUpTo(elementKind.level); + resetVisitedElementContentDownTo(elementKind.level); return visitedLastElement = super.visitClass(srcName); } @@ -130,6 +144,7 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc assertClassVisited(); assertLastElementContentVisited(); assertElementContentVisited(elementKind.level - 1); + resetLastSrcInfoDownTo(elementKind.level); assertNewSrcInfo(elementKind, srcInfo); visitedField = true; @@ -138,7 +153,7 @@ public boolean visitField(String srcName, @Nullable String srcDesc) throws IOExc visitedMethodVar = false; lastVisitedElement = elementKind; lastSrcInfo.put(elementKind, srcInfo); - resetVisitedElementContentUpTo(elementKind.level); + resetVisitedElementContentDownTo(elementKind.level); return visitedLastElement = super.visitField(srcName, srcDesc); } @@ -153,6 +168,7 @@ public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOEx assertClassVisited(); assertLastElementContentVisited(); assertElementContentVisited(elementKind.level - 1); + resetLastSrcInfoDownTo(elementKind.level); assertNewSrcInfo(elementKind, srcInfo); visitedField = false; @@ -161,7 +177,7 @@ public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOEx visitedMethodVar = false; lastVisitedElement = elementKind; lastSrcInfo.put(elementKind, srcInfo); - resetVisitedElementContentUpTo(elementKind.level); + resetVisitedElementContentDownTo(elementKind.level); return visitedLastElement = super.visitMethod(srcName, srcDesc); } @@ -178,13 +194,14 @@ public boolean visitMethodArg(int argPosition, int lvIndex, @Nullable String src assertMethodVisited(); assertLastElementContentVisited(); assertElementContentVisited(elementKind.level - 1); + resetLastSrcInfoDownTo(elementKind.level); assertNewSrcInfo(elementKind, srcInfo); visitedMethodArg = true; visitedMethodVar = false; lastVisitedElement = elementKind; lastSrcInfo.put(elementKind, srcInfo); - resetVisitedElementContentUpTo(elementKind.level); + resetVisitedElementContentDownTo(elementKind.level); return visitedLastElement = super.visitMethodArg(argPosition, lvIndex, srcName); } @@ -203,13 +220,14 @@ public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int assertMethodVisited(); assertLastElementContentVisited(); assertElementContentVisited(elementKind.level - 1); + resetLastSrcInfoDownTo(elementKind.level); assertNewSrcInfo(elementKind, srcInfo); visitedMethodArg = false; visitedMethodVar = true; lastVisitedElement = elementKind; lastSrcInfo.put(elementKind, srcInfo); - resetVisitedElementContentUpTo(elementKind.level); + resetVisitedElementContentDownTo(elementKind.level); return visitedLastElement = super.visitMethodVar(lvtRowIndex, lvIndex, startOpIdx, endOpIdx, srcName); } @@ -217,7 +235,8 @@ public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int @Override public void visitDstName(MappedElementKind targetKind, int namespace, String name) throws IOException { assertElementVisited(targetKind); - assertElementContentNotVisitedUpTo(targetKind.level + 1); // prevent visitation after visitElementContent of same level + assertLastVisitedElement(targetKind); + assertElementContentNotVisitedDownTo(targetKind.level + 1); // prevent visitation after visitElementContent of same level super.visitDstName(targetKind, namespace, name); } @@ -225,7 +244,8 @@ public void visitDstName(MappedElementKind targetKind, int namespace, String nam @Override public void visitDstDesc(MappedElementKind targetKind, int namespace, String desc) throws IOException { assertElementVisited(targetKind); - assertElementContentNotVisitedUpTo(targetKind.level + 1); // prevent visitation after visitElementContent of same level + assertLastVisitedElement(targetKind); + assertElementContentNotVisitedDownTo(targetKind.level + 1); // prevent visitation after visitElementContent of same level super.visitDstDesc(targetKind, namespace, desc); } @@ -233,7 +253,8 @@ public void visitDstDesc(MappedElementKind targetKind, int namespace, String des @Override public boolean visitElementContent(MappedElementKind targetKind) throws IOException { assertElementVisited(targetKind); - assertElementContentNotVisitedUpTo(targetKind.level); // no +1 to prevent repeated visitation + assertLastVisitedElement(targetKind); + assertElementContentNotVisitedDownTo(targetKind.level); // no +1 to prevent repeated visitation if (targetKind.level > 0) { assertElementContentVisited(targetKind.level - 1); @@ -241,10 +262,6 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept visitedElementContent[targetKind.level] = true; - if (targetKind.level < visitedElementContent.length - 1) { - resetVisitedElementContentUpTo(targetKind.level + 1); - } - return super.visitElementContent(targetKind); } @@ -316,11 +333,17 @@ private void assertContentVisited() { } private void assertElementVisited(MappedElementKind kind) { - if (lastVisitedElement != kind) { + if (lastVisitedElement.level < kind.level) { throw new IllegalStateException("Element not visited"); } } + private void assertLastVisitedElement(MappedElementKind kind) { + if (lastVisitedElement != kind) { + throw new IllegalStateException("Last visited element is not " + kind); + } + } + private void assertClassNotVisited() { if (visitedClass) { throw new IllegalStateException("Class already visited"); @@ -384,11 +407,11 @@ private void assertMethodVarVisited() { private void assertLastElementContentVisited() { if (visitedLastElement) { assertElementContentVisited(lastVisitedElement.level); - assertElementContentNotVisitedUpTo(lastVisitedElement.level + 1); + assertElementContentNotVisitedDownTo(lastVisitedElement.level + 1); } } - private void assertElementContentNotVisitedUpTo(int inclusiveLevel) { + private void assertElementContentNotVisitedDownTo(int inclusiveLevel) { for (int i = visitedElementContent.length - 1; i >= inclusiveLevel; i--) { if (visitedElementContent[i]) { throw new IllegalStateException(lastVisitedElement + " element content already visited"); @@ -409,25 +432,26 @@ private void assertEndNotVisited() { } private void assertNewSrcInfo(MappedElementKind kind, SrcInfo srcInfo) { - if (srcInfo.equals(lastSrcInfo.get(kind))) { - throw new IllegalStateException("Same source name visited twice in a row"); - } - } - - boolean visitedHeader; - boolean visitedNamespaces; - boolean visitedMetadata; - boolean visitedContent; - boolean visitedClass; - boolean visitedField; - boolean visitedMethod; - boolean visitedMethodArg; - boolean visitedMethodVar; - boolean[] visitedElementContent = new boolean[3]; - boolean visitedEnd; - MappedElementKind lastVisitedElement; - boolean visitedLastElement; - Map lastSrcInfo = new HashMap<>(); + if (!allowConsecutiveDuplicateElementVisits && srcInfo.equals(lastSrcInfo.get(kind))) { + throw new IllegalStateException("Same element visited twice in a row"); + } + } + + private final boolean allowConsecutiveDuplicateElementVisits; + private boolean visitedHeader; + private boolean visitedNamespaces; + private boolean visitedMetadata; + private boolean visitedContent; + private boolean visitedClass; + private boolean visitedField; + private boolean visitedMethod; + private boolean visitedMethodArg; + private boolean visitedMethodVar; + private boolean[] visitedElementContent = new boolean[3]; + private boolean visitedEnd; + private MappedElementKind lastVisitedElement; + private boolean visitedLastElement; + private Map lastSrcInfo = new HashMap<>(); private static class SrcInfo { SrcInfo srcName(String srcName) { diff --git a/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java b/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java index 90539995..577f0d02 100644 --- a/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java +++ b/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java @@ -37,11 +37,13 @@ public class ValidContentReadTest { private static MappingTree testTree; private static MappingTree testTreeWithHoles; + private static MappingTree testTreeWithRepeatedElements; @BeforeAll public static void setup() throws Exception { testTree = TestHelper.createTestTree(); testTreeWithHoles = TestHelper.createTestTreeWithHoles(); + testTreeWithRepeatedElements = testTree; } @Test @@ -49,6 +51,7 @@ public void enigmaFile() throws Exception { MappingFormat format = MappingFormat.ENIGMA_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -63,6 +66,7 @@ public void tinyFile() throws Exception { MappingFormat format = MappingFormat.TINY_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -70,6 +74,7 @@ public void tinyV2File() throws Exception { MappingFormat format = MappingFormat.TINY_2_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); // TODO: The Tiny v2 spec disallows repeated elements, there should at least be a warning } @Test @@ -77,6 +82,7 @@ public void srgFile() throws Exception { MappingFormat format = MappingFormat.SRG_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -84,6 +90,7 @@ public void xsrgFile() throws Exception { MappingFormat format = MappingFormat.XSRG_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -91,6 +98,7 @@ public void jamFile() throws Exception { MappingFormat format = MappingFormat.JAM_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -98,6 +106,7 @@ public void csrgFile() throws Exception { MappingFormat format = MappingFormat.CSRG_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -105,6 +114,7 @@ public void tsrgFile() throws Exception { MappingFormat format = MappingFormat.TSRG_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -112,6 +122,7 @@ public void tsrgV2File() throws Exception { MappingFormat format = MappingFormat.TSRG_2_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -119,6 +130,7 @@ public void proguardFile() throws Exception { MappingFormat format = MappingFormat.PROGUARD_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -126,6 +138,7 @@ public void migrationMapFile() throws Exception { MappingFormat format = MappingFormat.INTELLIJ_MIGRATION_MAP_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -133,6 +146,7 @@ public void recafSimpleFile() throws Exception { MappingFormat format = MappingFormat.RECAF_SIMPLE_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } @Test @@ -140,43 +154,69 @@ public void jobfFile() throws Exception { MappingFormat format = MappingFormat.JOBF_FILE; checkDefault(format); checkHoles(format); + checkRepeated(format, true); } private void checkDefault(MappingFormat format) throws Exception { Path path = TestHelper.MappingDirs.VALID.resolve(TestHelper.getFileName(format)); VisitableMappingTree tree = new MemoryMappingTree(); - MappingReader.read(path, format, new VisitOrderVerifyingVisitor(tree)); - assertEqual(format, tree, testTree); + boolean allowConsecutiveDuplicateElementVisits = false; + + MappingReader.read(path, format, new VisitOrderVerifyingVisitor(tree, allowConsecutiveDuplicateElementVisits)); + assertEqual(tree, format, testTree, allowConsecutiveDuplicateElementVisits); tree = new MemoryMappingTree(); MappingReader.read(path, format, new MappingSourceNsSwitch( new VisitOrderVerifyingVisitor( new MappingSourceNsSwitch( - new VisitOrderVerifyingVisitor(tree), - testTree.getSrcNamespace())), + new VisitOrderVerifyingVisitor(tree, allowConsecutiveDuplicateElementVisits), + testTree.getSrcNamespace()), + allowConsecutiveDuplicateElementVisits), testTree.getDstNamespaces().get(0))); - assertEqual(format, tree, testTree); + assertEqual(tree, format, testTree, allowConsecutiveDuplicateElementVisits); } private void checkHoles(MappingFormat format) throws Exception { Path path = TestHelper.MappingDirs.VALID_WITH_HOLES.resolve(TestHelper.getFileName(format)); VisitableMappingTree tree = new MemoryMappingTree(); - MappingReader.read(path, format, new VisitOrderVerifyingVisitor(tree)); - assertEqual(format, tree, testTreeWithHoles); + boolean allowConsecutiveDuplicateElementVisits = false; + + MappingReader.read(path, format, new VisitOrderVerifyingVisitor(tree, allowConsecutiveDuplicateElementVisits)); + assertEqual(tree, format, testTreeWithHoles, allowConsecutiveDuplicateElementVisits); + } + + private void checkRepeated(MappingFormat format, boolean allowConsecutiveDuplicateElementVisits) throws Exception { + Path path = TestHelper.MappingDirs.REPEATED_ELEMENTS.resolve(TestHelper.getFileName(format)); + + VisitableMappingTree tree = new MemoryMappingTree(); + MappingReader.read(path, format, new VisitOrderVerifyingVisitor(tree, allowConsecutiveDuplicateElementVisits)); + assertEqual(tree, format, testTreeWithRepeatedElements, allowConsecutiveDuplicateElementVisits); + + tree = new MemoryMappingTree(); + MappingReader.read(path, format, + new MappingSourceNsSwitch( + new VisitOrderVerifyingVisitor( + new MappingSourceNsSwitch( + new VisitOrderVerifyingVisitor(tree, allowConsecutiveDuplicateElementVisits), + testTreeWithRepeatedElements.getSrcNamespace()), + allowConsecutiveDuplicateElementVisits), + testTreeWithRepeatedElements.getDstNamespaces().get(0))); + assertEqual(tree, format, testTreeWithRepeatedElements, allowConsecutiveDuplicateElementVisits); } - private void assertEqual(MappingFormat format, MappingTreeView tree, MappingTreeView referenceTree) throws Exception { - assertSubset(tree, format, referenceTree, null); - assertSubset(referenceTree, null, tree, format); + private void assertEqual(MappingTreeView tree, MappingFormat format, MappingTreeView referenceTree, boolean allowConsecutiveDuplicateElementVisits) throws Exception { + assertSubset(tree, format, referenceTree, null, allowConsecutiveDuplicateElementVisits); + assertSubset(referenceTree, null, tree, format, allowConsecutiveDuplicateElementVisits); } - private void assertSubset(MappingTreeView subTree, @Nullable MappingFormat subFormat, MappingTreeView supTree, @Nullable MappingFormat supFormat) throws Exception { + private void assertSubset(MappingTreeView subTree, @Nullable MappingFormat subFormat, MappingTreeView supTree, @Nullable MappingFormat supFormat, boolean allowConsecutiveDuplicateElementVisits) throws Exception { subTree.accept( new VisitOrderVerifyingVisitor( new FlatAsRegularMappingVisitor( - new SubsetAssertingVisitor(supTree, supFormat, subFormat)))); + new SubsetAssertingVisitor(supTree, supFormat, subFormat)), + allowConsecutiveDuplicateElementVisits)); } } diff --git a/src/test/resources/read/repeated-elements/csrg.csrg b/src/test/resources/read/repeated-elements/csrg.csrg new file mode 100644 index 00000000..9edddc04 --- /dev/null +++ b/src/test/resources/read/repeated-elements/csrg.csrg @@ -0,0 +1,12 @@ +class_1 class1Ns0Rename0 +class_1 class1Ns0Rename +class_1 field_1 field1Ns0Rename0 +class_1 field_1 field1Ns0Rename +class_1 method_1 ()I method1Ns0Rename0 +class_1 method_1 ()I method1Ns0Rename +class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +class_1$class_2 class1Ns0Rename$class2Ns0Rename +class_1$class_2 field_2 field2Ns0Rename0 +class_1$class_2 field_2 field2Ns0Rename +class_3 class3Ns0Rename0 +class_3 class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/enigma.mappings b/src/test/resources/read/repeated-elements/enigma.mappings new file mode 100644 index 00000000..446a78c3 --- /dev/null +++ b/src/test/resources/read/repeated-elements/enigma.mappings @@ -0,0 +1,17 @@ +CLASS class_1 class1Ns0Rename0 +CLASS class_1 class1Ns0Rename + FIELD field_1 field1Ns0Rename0 I + FIELD field_1 field1Ns0Rename I + METHOD method_1 method1Ns0Rename0 ()I + METHOD method_1 method1Ns0Rename ()I + ARG 1 param1Ns0Rename0 + ARG 1 param1Ns0Rename + CLASS class_2 class2Ns0Rename0 + CLASS class_2 class2Ns0Rename1 + COMMENT This is a comment. + CLASS class_2 class2Ns0Rename + COMMENT This is a comment + FIELD field_2 field2Ns0Rename0 I + FIELD field_2 field2Ns0Rename I +CLASS class_3 class3Ns0Rename0 +CLASS class_3 class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/jam.jam b/src/test/resources/read/repeated-elements/jam.jam new file mode 100644 index 00000000..7ad1e710 --- /dev/null +++ b/src/test/resources/read/repeated-elements/jam.jam @@ -0,0 +1,14 @@ +CL class_1 class1Ns0Rename0 +CL class_1 class1Ns0Rename +CL class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +CL class_1$class_2 class1Ns0Rename$class2Ns0Rename +CL class_3 class3Ns0Rename0 +CL class_3 class3Ns0Rename +FD class_1 field_1 I field1Ns0Rename0 +FD class_1 field_1 I field1Ns0Rename +MD class_1 method_1 ()I method1Ns0Rename0 +MD class_1 method_1 ()I method1Ns0Rename +MP class_1 method_1 ()I 0 param1Ns0Rename0 +MP class_1 method_1 ()I 0 param1Ns0Rename +FD class_1$class_2 field_2 I field2Ns0Rename0 +FD class_1$class_2 field_2 I field2Ns0Rename diff --git a/src/test/resources/read/repeated-elements/jobf.jobf b/src/test/resources/read/repeated-elements/jobf.jobf new file mode 100644 index 00000000..6c9ce7d4 --- /dev/null +++ b/src/test/resources/read/repeated-elements/jobf.jobf @@ -0,0 +1,12 @@ +c class_1 = class1Ns0Rename0 +c class_1 = class1Ns0Rename +f class_1.field_1:I = field1Ns0Rename0 +f class_1.field_1:I = field1Ns0Rename +m class_1.method_1()I = method1Ns0Rename0 +m class_1.method_1()I = method1Ns0Rename +c class_1$class_2 = class1Ns0Rename$class2Ns0Rename0 +c class_1$class_2 = class1Ns0Rename$class2Ns0Rename +f class_1$class_2.field_2:I = field2Ns0Rename0 +f class_1$class_2.field_2:I = field2Ns0Rename +c class_3 = class3Ns0Rename0 +c class_3 = class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/migration-map.xml b/src/test/resources/read/repeated-elements/migration-map.xml new file mode 100644 index 00000000..dc689ab6 --- /dev/null +++ b/src/test/resources/read/repeated-elements/migration-map.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/test/resources/read/repeated-elements/proguard.txt b/src/test/resources/read/repeated-elements/proguard.txt new file mode 100644 index 00000000..477b3bdd --- /dev/null +++ b/src/test/resources/read/repeated-elements/proguard.txt @@ -0,0 +1,12 @@ +class_1 -> class1Ns0Rename0: +class_1 -> class1Ns0Rename: + int field_1 -> field1Ns0Rename0 + int field_1 -> field1Ns0Rename + int method_1() -> method1Ns0Rename0 + int method_1() -> method1Ns0Rename +class_1$class_2 -> class1Ns0Rename$class2Ns0Rename0: +class_1$class_2 -> class1Ns0Rename$class2Ns0Rename: + int field_2 -> field2Ns0Rename0 + int field_2 -> field2Ns0Rename +class_3 -> class3Ns0Rename0: +class_3 -> class3Ns0Rename: diff --git a/src/test/resources/read/repeated-elements/recaf-simple.txt b/src/test/resources/read/repeated-elements/recaf-simple.txt new file mode 100644 index 00000000..1c50114d --- /dev/null +++ b/src/test/resources/read/repeated-elements/recaf-simple.txt @@ -0,0 +1,12 @@ +class_1 class1Ns0Rename0 +class_1 class1Ns0Rename +class_1.field_1 I field1Ns0Rename0 +class_1.field_1 I field1Ns0Rename +class_1.method_1()I method1Ns0Rename0 +class_1.method_1()I method1Ns0Rename +class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +class_1$class_2 class1Ns0Rename$class2Ns0Rename +class_1$class_2.field_2 I field2Ns0Rename0 +class_1$class_2.field_2 I field2Ns0Rename +class_3 class3Ns0Rename0 +class_3 class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/srg.srg b/src/test/resources/read/repeated-elements/srg.srg new file mode 100644 index 00000000..c6a08347 --- /dev/null +++ b/src/test/resources/read/repeated-elements/srg.srg @@ -0,0 +1,12 @@ +CL: class_1 class1Ns0Rename0 +CL: class_1 class1Ns0Rename1 +FD: class_1/field_1 class1Ns0Rename/field1Ns0Rename0 +FD: class_1/field_1 class1Ns0Rename/field1Ns0Rename +MD: class_1/method_1 ()I class1Ns0Rename/method1Ns0Rename0 ()I +MD: class_1/method_1 ()I class1Ns0Rename/method1Ns0Rename ()I +CL: class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +CL: class_1$class_2 class1Ns0Rename$class2Ns0Rename +FD: class_1$class_2/field_2 class1Ns0Rename$class2Ns0Rename/field2Ns0Rename0 +FD: class_1$class_2/field_2 class1Ns0Rename$class2Ns0Rename/field2Ns0Rename +CL: class_3 class3Ns0Rename0 +CL: class_3 class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/tiny.tiny b/src/test/resources/read/repeated-elements/tiny.tiny new file mode 100644 index 00000000..196bd3d7 --- /dev/null +++ b/src/test/resources/read/repeated-elements/tiny.tiny @@ -0,0 +1,13 @@ +v1 source target target2 +CLASS class_1 class1Ns0Rename0 class1Ns1Rename0 +CLASS class_1 class1Ns0Rename class1Ns1Rename +FIELD class_1 I field_1 field1Ns0Rename0 field1Ns1Rename0 +FIELD class_1 I field_1 field1Ns0Rename field1Ns1Rename +METHOD class_1 ()I method_1 method1Ns0Rename0 method1Ns1Rename0 +METHOD class_1 ()I method_1 method1Ns0Rename method1Ns1Rename +CLASS class_1$class_2 class1Ns0Rename$class2Ns0Rename0 class1Ns1Rename$class2Ns1Rename0 +CLASS class_1$class_2 class1Ns0Rename$class2Ns0Rename class1Ns1Rename$class2Ns1Rename +FIELD class_1$class_2 I field_2 field2Ns0Rename0 field2Ns1Rename0 +FIELD class_1$class_2 I field_2 field2Ns0Rename field2Ns1Rename +CLASS class_3 class3Ns0Rename0 class3Ns1Rename0 +CLASS class_3 class3Ns0Rename class3Ns1Rename diff --git a/src/test/resources/read/repeated-elements/tinyV2.tiny b/src/test/resources/read/repeated-elements/tinyV2.tiny new file mode 100644 index 00000000..01be3216 --- /dev/null +++ b/src/test/resources/read/repeated-elements/tinyV2.tiny @@ -0,0 +1,19 @@ +tiny 2 0 source target target2 +c class_1 class1Ns0Rename0 class1Ns1Rename0 +c class_1 class1Ns0Rename class1Ns1Rename + f I field_1 field1Ns0Rename0 field1Ns1Rename0 + f I field_1 field1Ns0Rename field1Ns1Rename + m ()I method_1 method1Ns0Rename0 method1Ns1Rename0 + m ()I method_1 method1Ns0Rename method1Ns1Rename + p 1 param_1 param1Ns0Rename0 param1Ns1Rename0 + p 1 param_1 param1Ns0Rename param1Ns1Rename + v 2 2 2 var_1 var1Ns0Rename0 var1Ns1Rename0 + v 2 2 2 var_1 var1Ns0Rename var1Ns1Rename +c class_1$class_2 class1Ns0Rename$class2Ns0Rename0 class1Ns1Rename$class2Ns1Rename0 +c class_1$class_2 class1Ns0Rename$class2Ns0Rename class1Ns1Rename$class2Ns1Rename + c This is a comment. + c This is a comment + f I field_2 field2Ns0Rename0 field2Ns1Rename0 + f I field_2 field2Ns0Rename field2Ns1Rename +c class_3 class3Ns0Rename0 class3Ns1Rename0 +c class_3 class3Ns0Rename class3Ns1Rename diff --git a/src/test/resources/read/repeated-elements/tsrg.tsrg b/src/test/resources/read/repeated-elements/tsrg.tsrg new file mode 100644 index 00000000..fa71b48e --- /dev/null +++ b/src/test/resources/read/repeated-elements/tsrg.tsrg @@ -0,0 +1,12 @@ +class_1 class1Ns0Rename0 +class_1 class1Ns0Rename + field_1 field1Ns0Rename0 + field_1 field1Ns0Rename + method_1 ()I method1Ns0Rename0 + method_1 ()I method1Ns0Rename +class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +class_1$class_2 class1Ns0Rename$class2Ns0Rename + field_2 field2Ns0Rename0 + field_2 field2Ns0Rename +class_3 class3Ns0Rename0 +class_3 class3Ns0Rename diff --git a/src/test/resources/read/repeated-elements/tsrgV2.tsrg b/src/test/resources/read/repeated-elements/tsrgV2.tsrg new file mode 100644 index 00000000..8cfa6b7f --- /dev/null +++ b/src/test/resources/read/repeated-elements/tsrgV2.tsrg @@ -0,0 +1,15 @@ +tsrg2 source target target2 +class_1 class1Ns0Rename0 class1Ns1Rename0 +class_1 class1Ns0Rename class1Ns1Rename + field_1 I field1Ns0Rename0 field1Ns1Rename0 + field_1 I field1Ns0Rename field1Ns1Rename + method_1 ()I method1Ns0Rename0 method1Ns1Rename0 + method_1 ()I method1Ns0Rename method1Ns1Rename + 1 param_1 param1Ns0Rename0 param1Ns1Rename0 + 1 param_1 param1Ns0Rename param1Ns1Rename +class_1$class_2 class1Ns0Rename$class2Ns0Rename0 class1Ns1Rename$class2Ns1Rename0 +class_1$class_2 class1Ns0Rename$class2Ns0Rename class1Ns1Rename$class2Ns1Rename + field_2 I field2Ns0Rename0 field2Ns1Rename0 + field_2 I field2Ns0Rename field2Ns1Rename +class_3 class3Ns0Rename0 class3Ns1Rename0 +class_3 class3Ns0Rename class3Ns1Rename diff --git a/src/test/resources/read/repeated-elements/xsrg.xsrg b/src/test/resources/read/repeated-elements/xsrg.xsrg new file mode 100644 index 00000000..6ae2a193 --- /dev/null +++ b/src/test/resources/read/repeated-elements/xsrg.xsrg @@ -0,0 +1,12 @@ +CL: class_1 class1Ns0Rename0 +CL: class_1 class1Ns0Rename +FD: class_1/field_1 I class1Ns0Rename/field1Ns0Rename0 I +FD: class_1/field_1 I class1Ns0Rename/field1Ns0Rename I +MD: class_1/method_1 ()I class1Ns0Rename/method1Ns0Rename0 ()I +MD: class_1/method_1 ()I class1Ns0Rename/method1Ns0Rename ()I +CL: class_1$class_2 class1Ns0Rename$class2Ns0Rename0 +CL: class_1$class_2 class1Ns0Rename$class2Ns0Rename +FD: class_1$class_2/field_2 I class1Ns0Rename$class2Ns0Rename/field2Ns0Rename0 I +FD: class_1$class_2/field_2 I class1Ns0Rename$class2Ns0Rename/field2Ns0Rename I +CL: class_3 class3Ns0Rename0 +CL: class_3 class3Ns0Rename