Skip to content

Commit

Permalink
Add Recaf Simple reader
Browse files Browse the repository at this point in the history
  • Loading branch information
NebelNidas committed Oct 11, 2023
1 parent 06f00b9 commit 5a5208b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/main/java/net/fabricmc/mappingio/MappingReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.fabricmc.mappingio.format.enigma.EnigmaDirReader;
import net.fabricmc.mappingio.format.enigma.EnigmaFileReader;
import net.fabricmc.mappingio.format.proguard.ProGuardFileReader;
import net.fabricmc.mappingio.format.simple.RecafSimpleFileReader;
import net.fabricmc.mappingio.format.srg.SrgFileReader;
import net.fabricmc.mappingio.format.srg.TsrgFileReader;
import net.fabricmc.mappingio.format.tiny.Tiny1FileReader;
Expand Down Expand Up @@ -198,6 +199,9 @@ public static void read(Reader reader, MappingFormat format, MappingVisitor visi
case PROGUARD_FILE:
ProGuardFileReader.read(reader, visitor);
break;
case RECAF_SIMPLE_FILE:
RecafSimpleFileReader.read(reader, visitor);
break;
default:
throw new IllegalStateException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ public enum MappingFormat {
/**
* ProGuard's mapping format, as specified <a href="https://www.guardsquare.com/manual/tools/retrace">here</a>.
*/
PROGUARD_FILE("ProGuard file", "txt", false, true, false, false, false);
PROGUARD_FILE("ProGuard file", "txt", false, true, false, false, false),

/**
* Recaf's {@code Simple} mapping format, as specified <a href="https://github.com/Col-E/Recaf/blob/e9765d4e02991a9dd48e67c9572a063c14552e7c/src/main/java/me/coley/recaf/mapping/SimpleMappings.java#L14-L23">here</a>.
*/
RECAF_SIMPLE_FILE("Recaf Simple file", "txt", false, true, false, false, false);

MappingFormat(String name, String fileExt,
boolean hasNamespaces, boolean hasFieldDescriptors,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2023 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.mappingio.format.simple;

import java.io.IOException;
import java.io.Reader;
import java.util.Collections;
import java.util.Set;

import net.fabricmc.mappingio.MappedElementKind;
import net.fabricmc.mappingio.MappingFlag;
import net.fabricmc.mappingio.MappingUtil;
import net.fabricmc.mappingio.MappingVisitor;
import net.fabricmc.mappingio.format.ColumnFileReader;
import net.fabricmc.mappingio.tree.MappingTree;
import net.fabricmc.mappingio.tree.MemoryMappingTree;

public final class RecafSimpleFileReader {
private RecafSimpleFileReader() {
}

public static void read(Reader reader, MappingVisitor visitor) throws IOException {
read(reader, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor);
}

public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException {
read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor);
}

private static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException {
Set<MappingFlag> flags = visitor.getFlags();
MappingVisitor parentVisitor = null;

if (flags.contains(MappingFlag.NEEDS_ELEMENT_UNIQUENESS)) {
parentVisitor = visitor;
visitor = new MemoryMappingTree();
} else if (flags.contains(MappingFlag.NEEDS_MULTIPLE_PASSES)) {
reader.mark();
}

for (;;) {
if (visitor.visitHeader()) {
visitor.visitNamespaces(sourceNs, Collections.singletonList(targetNs));
}

if (visitor.visitContent()) {
String line;
String lastClass = null;
boolean visitClass = false;

do {
line = reader.nextCols(true);

// Skip comments and empty lines
if (line == null || line.trim().isEmpty() || line.trim().startsWith("#")) continue;

String[] parts = line.split(" ");
int dotPos = parts[0].lastIndexOf('.');
String clsSrcName;
String clsDstName = null;
String memberSrcName = null;
String memberSrcDesc = null;
String memberDstName = null;
boolean isMethod = false;

if (dotPos < 0) { // class
clsSrcName = parts[0];
clsDstName = parts[1];
} else { // member
clsSrcName = parts[0].substring(0, dotPos);
String memberIdentifier = parts[0].substring(dotPos + 1);
memberDstName = parts[1];

if (parts.length >= 3) { // field with descriptor
memberSrcName = memberIdentifier;
memberSrcDesc = parts[1];
memberDstName = parts[2];
} else if (parts.length == 2) { // field without descriptor or method
int mthDescPos = memberIdentifier.lastIndexOf("(");

if (mthDescPos < 0) { // field
memberSrcName = memberIdentifier;
} else { // method
isMethod = true;
memberSrcName = memberIdentifier.substring(0, mthDescPos);
memberSrcDesc = memberIdentifier.substring(mthDescPos);
}
} else {
throw new IOException("Invalid Recaf Simple line "+reader.getLineNumber()+": Insufficient column count!");
}
}

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);
} else if (isMethod && visitor.visitMethod(memberSrcName, memberSrcDesc)) {
visitor.visitDstName(MappedElementKind.METHOD, 0, memberDstName);
}
}
} while (reader.nextLine(0));
}

if (visitor.visitEnd()) break;
reader.reset();
}

if (parentVisitor != null) {
((MappingTree) visitor).accept(parentVisitor);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import net.fabricmc.mappingio.format.enigma.EnigmaFileReader;
import net.fabricmc.mappingio.format.proguard.ProGuardFileReader;
import net.fabricmc.mappingio.format.simple.RecafSimpleFileReader;
import net.fabricmc.mappingio.format.srg.SrgFileReader;
import net.fabricmc.mappingio.format.srg.TsrgFileReader;
import net.fabricmc.mappingio.format.tiny.Tiny1FileReader;
Expand Down Expand Up @@ -64,4 +65,9 @@ public void emptySrgFile() throws Exception {
public void emptyTsrgFile() throws Exception {
TsrgFileReader.read(new StringReader(""), tree);
}

@Test
public void emptyRecafSimpleFile() throws Exception {
RecafSimpleFileReader.read(new StringReader(""), tree);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ public void tsrg2File() throws Exception {
checkHoles(filename, format);
}

@Test
public void recafSimpleFile() throws Exception {
MappingFormat format = MappingFormat.RECAF_SIMPLE_FILE;
String filename = "recaf-simple.txt";
checkDefault(filename, format);
checkHoles(filename, format);
}

private VisitableMappingTree checkDefault(String path, MappingFormat format) throws Exception {
VisitableMappingTree tree = new MemoryMappingTree();
MappingReader.read(dir.resolve("valid/" + path), format, tree);
Expand Down
10 changes: 10 additions & 0 deletions src/test/resources/read/valid-with-holes/recaf-simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class_2 class2Ns0Rename
class_5 class5Ns0Rename
class_7$class_8 class_7$class8Ns0Rename
class_13$class_14 class_13$class14Ns0Rename
class_17$class_18$class_19 class_17$class_18$class19Ns0Rename
class_26$class_27$class_28 class_26$class_27$class28Ns0Rename
class_32.field_2 field2Ns0Rename
class_32.field_5 field5Ns0Rename
class_32.method_2()I method2Ns0Rename
class_32.method_5()I method5Ns0Rename
6 changes: 6 additions & 0 deletions src/test/resources/read/valid/recaf-simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class_1 class1Ns0Rename
class_1.field_1 I field1Ns0Rename
class_1.method_1()I method1Ns0Rename
class_1$class_2 class1Ns0Rename$class2Ns0Rename
class_1$class_2.field_2 I field2Ns0Rename
class_3 class3Ns0Rename

0 comments on commit 5a5208b

Please sign in to comment.