Skip to content

Commit

Permalink
Add TSRG(2) writer
Browse files Browse the repository at this point in the history
  • Loading branch information
NebelNidas committed Nov 19, 2023
1 parent b720406 commit 4fc8568
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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 TSRG and TSRG2 writer
- Fixed NPE in `MemoryMappingTree`
- Fixed TSRG2 reader not handling multiple passes correctly

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/net/fabricmc/mappingio/MappingWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import net.fabricmc.mappingio.format.enigma.EnigmaFileWriter;
import net.fabricmc.mappingio.format.proguard.ProGuardFileWriter;
import net.fabricmc.mappingio.format.srg.SrgFileWriter;
import net.fabricmc.mappingio.format.srg.TsrgFileWriter;
import net.fabricmc.mappingio.format.tiny.Tiny1FileWriter;
import net.fabricmc.mappingio.format.tiny.Tiny2FileWriter;

Expand All @@ -55,6 +56,8 @@ static MappingWriter create(Writer writer, MappingFormat format) throws IOExcept
case ENIGMA_FILE: return new EnigmaFileWriter(writer);
case SRG_FILE: return new SrgFileWriter(writer, false);
case XSRG_FILE: return new SrgFileWriter(writer, true);
case TSRG_FILE: return new TsrgFileWriter(writer, false);
case TSRG_2_FILE: return new TsrgFileWriter(writer, true);
case PROGUARD_FILE: return new ProGuardFileWriter(writer);
default: return null;
}
Expand Down
202 changes: 202 additions & 0 deletions src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* Copyright (c) 2021 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.srg;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import org.jetbrains.annotations.Nullable;

import net.fabricmc.mappingio.MappedElementKind;
import net.fabricmc.mappingio.MappingFlag;
import net.fabricmc.mappingio.MappingWriter;
import net.fabricmc.mappingio.format.MappingFormat;

/**
* {@link MappingFormat#TSRG_FILE TSRG file} and
* {@link MappingFormat#TSRG_2_FILE TSRG2 file} writer.
*/
public final class TsrgFileWriter implements MappingWriter {
public TsrgFileWriter(Writer writer, boolean tsrg2) {
this.writer = writer;
this.tsrg2 = tsrg2;
}

@Override
public void close() throws IOException {
writer.close();
}

@Override
public Set<MappingFlag> getFlags() {
return tsrg2 ? tsrg2Flags : tsrgFlags;
}

@Override
public void visitNamespaces(String srcNamespace, List<String> dstNamespaces) throws IOException {
dstNames = new String[dstNamespaces.size()];

if (tsrg2) {
write("tsrg2 ");
write(srcNamespace);

for (String dstNamespace : dstNamespaces) {
writeSpace();
write(dstNamespace);
}

writeLn();
}
}

@Override
public void visitMetadata(String key, @Nullable String value) throws IOException {
// TODO: Support the static method marker once https://github.com/FabricMC/mapping-io/pull/41 is merged
}

@Override
public boolean visitClass(String srcName) throws IOException {
this.srcName = srcName;

return true;
}

@Override
public boolean visitField(String srcName, @Nullable String srcDesc) throws IOException {
this.srcName = srcName;
this.srcDesc = srcDesc;

return true;
}

@Override
public boolean visitMethod(String srcName, @Nullable String srcDesc) throws IOException {
this.srcName = srcName;
this.srcDesc = srcDesc;

return true;
}

@Override
public boolean visitMethodArg(int argPosition, int lvIndex, @Nullable String srcName) throws IOException {
if (tsrg2) {
this.srcName = srcName;
this.lvIndex = lvIndex;
return true;
}

return false;
}

@Override
public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, @Nullable String srcName) throws IOException {
return false; // not supported, skip
}

@Override
public void visitDstName(MappedElementKind targetKind, int namespace, String name) {
if (!tsrg2 && namespace != 0) return;

dstNames[namespace] = name;
}

@Override
public boolean visitElementContent(MappedElementKind targetKind) throws IOException {
switch (targetKind) {
case CLASS:
break;
case FIELD:
case METHOD:
writeTab();
break;
case METHOD_ARG:
assert tsrg2;
writeTab();
writeTab();
write(Integer.toString(lvIndex));
writeSpace();
case METHOD_VAR:
assert tsrg2;
break;
}

write(srcName);

if (targetKind == MappedElementKind.METHOD
|| (targetKind == MappedElementKind.FIELD && tsrg2)) {
writeSpace();
write(srcDesc);
}

int dstNsCount = tsrg2 ? dstNames.length : 1;

for (int i = 0; i < dstNsCount; i++) {
String dstName = dstNames[i];
writeSpace();
write(dstName != null ? dstName : srcName);
}

writeLn();

srcName = srcDesc = null;
Arrays.fill(dstNames, null);
lvIndex = -1;

return targetKind == MappedElementKind.CLASS
|| (tsrg2 && targetKind == MappedElementKind.METHOD);
}

@Override
public void visitComment(MappedElementKind targetKind, String comment) throws IOException {
// not supported, skip
}

private void write(String str) throws IOException {
writer.write(str);
}

private void writeTab() throws IOException {
writer.write('\t');
}

private void writeSpace() throws IOException {
writer.write(' ');
}

private void writeLn() throws IOException {
writer.write('\n');
}

private static final Set<MappingFlag> tsrgFlags = EnumSet.of(MappingFlag.NEEDS_ELEMENT_UNIQUENESS, MappingFlag.NEEDS_SRC_METHOD_DESC);
private static final Set<MappingFlag> tsrg2Flags;

static {
tsrg2Flags = EnumSet.copyOf(tsrgFlags);
tsrg2Flags.add(MappingFlag.NEEDS_SRC_FIELD_DESC);
}

private final Writer writer;
private final boolean tsrg2;
private String srcName;
private String srcDesc;
private String[] dstNames;
private int lvIndex = -1;
}
11 changes: 11 additions & 0 deletions src/test/java/net/fabricmc/mappingio/write/WriteTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ public void xsrgFile() throws Exception {
write(MappingFormat.XSRG_FILE);
}

@Test
public void tsrgFile() throws Exception {
write(MappingFormat.TSRG_FILE);
}

@Test
public void tsrg2File() throws Exception {
write(MappingFormat.TSRG_2_FILE);
}

@Test
public void proguardFile() throws Exception {
write(MappingFormat.PROGUARD_FILE);
}
Expand Down

0 comments on commit 4fc8568

Please sign in to comment.