From ab1055017071d6c21310fe60b5dfc6f334a5fef7 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 7 Oct 2023 08:52:02 +0200 Subject: [PATCH 1/4] Rework the mapping read and write APIs --- .../net/fabricmc/mappingio/MappingReader.java | 160 ++++-------------- .../net/fabricmc/mappingio/MappingWriter.java | 34 +--- .../mappingio/format/MappingDirReader.java | 39 +++++ .../mappingio/format/MappingFileReader.java | 38 +++++ .../mappingio/format/MappingFormat.java | 68 +++++++- .../format/enigma/EnigmaDirReader.java | 22 ++- .../format/enigma/EnigmaFileReader.java | 36 ++-- .../format/proguard/ProGuardFileReader.java | 21 ++- .../mappingio/format/srg/SrgFileReader.java | 22 ++- .../mappingio/format/srg/TsrgFileReader.java | 32 ++-- .../format/tiny/Tiny1FileReader.java | 26 ++- .../format/tiny/Tiny1FileWriter.java | 2 + .../format/tiny/Tiny2FileReader.java | 34 ++-- .../net/fabricmc/mappingio/TestHelper.java | 2 +- .../mappingio/read/EmptyContentReadTest.java | 12 +- .../mappingio/read/ValidContentReadTest.java | 3 +- 16 files changed, 322 insertions(+), 229 deletions(-) create mode 100644 src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java create mode 100644 src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java diff --git a/src/main/java/net/fabricmc/mappingio/MappingReader.java b/src/main/java/net/fabricmc/mappingio/MappingReader.java index ee2bef85..fa8aca64 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingReader.java +++ b/src/main/java/net/fabricmc/mappingio/MappingReader.java @@ -16,7 +16,6 @@ package net.fabricmc.mappingio; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; @@ -26,20 +25,14 @@ import java.util.Arrays; import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + import net.fabricmc.mappingio.format.MappingFormat; -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.srg.SrgFileReader; -import net.fabricmc.mappingio.format.srg.TsrgFileReader; -import net.fabricmc.mappingio.format.tiny.Tiny1FileReader; -import net.fabricmc.mappingio.format.tiny.Tiny2FileReader; - -public final class MappingReader { - private MappingReader() { - } - public static MappingFormat detectFormat(Path file) throws IOException { +@ApiStatus.NonExtendable +public interface MappingReader { + static MappingFormat detectFormat(Path file) throws IOException { if (Files.isDirectory(file)) { return MappingFormat.ENIGMA_DIR; } else { @@ -49,7 +42,8 @@ public static MappingFormat detectFormat(Path file) throws IOException { } } - public static MappingFormat detectFormat(Reader reader) throws IOException { + static MappingFormat detectFormat(Reader reader) throws IOException { + int DETECT_HEADER_LEN = 4096; char[] buffer = new char[DETECT_HEADER_LEN]; int pos = 0; int len; @@ -88,126 +82,32 @@ public static MappingFormat detectFormat(Reader reader) throws IOException { return null; // unknown format or corrupted } - public static List getNamespaces(Path file) throws IOException { - return getNamespaces(file, null); - } - - public static List getNamespaces(Path file, MappingFormat format) throws IOException { - if (format == null) { - format = detectFormat(file); - if (format == null) throw new IOException("invalid/unsupported mapping format"); - } - - if (format.hasNamespaces) { - try (Reader reader = Files.newBufferedReader(file)) { - return getNamespaces(reader, format); - } - } else { - return Arrays.asList(MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK); - } - } - - public static List getNamespaces(Reader reader) throws IOException { - return getNamespaces(reader, null); - } - - public static List getNamespaces(Reader reader, MappingFormat format) throws IOException { - if (format == null) { - if (!reader.markSupported()) reader = new BufferedReader(reader); - reader.mark(DETECT_HEADER_LEN); - format = detectFormat(reader); - reader.reset(); - if (format == null) throw new IOException("invalid/unsupported mapping format"); - } - - if (format.hasNamespaces) { - checkReaderCompatible(format); - - switch (format) { - case TINY_FILE: - return Tiny1FileReader.getNamespaces(reader); - case TINY_2_FILE: - return Tiny2FileReader.getNamespaces(reader); - case TSRG_2_FILE: - return TsrgFileReader.getNamespaces(reader); - default: - throw new IllegalStateException(); - } - } else { - return Arrays.asList(MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK); - } - } - - public static void read(Path file, MappingVisitor visitor) throws IOException { - read(file, null, visitor); - } - - public static void read(Path file, MappingFormat format, MappingVisitor visitor) throws IOException { - if (format == null) { - format = detectFormat(file); - if (format == null) throw new IOException("invalid/unsupported mapping format"); - } - - if (format.hasSingleFile()) { - try (Reader reader = Files.newBufferedReader(file)) { - read(reader, format, visitor); - } - } else { - switch (format) { - case ENIGMA_DIR: - EnigmaDirReader.read(file, visitor); - break; - default: - throw new IllegalStateException(); + /** + * Read mappings from a file or directory. + * @param path the file or directory to read from + * @param visitor the visitor receiving the mappings + */ + default void read(Path path, MappingVisitor visitor) throws IOException { + if (!path.toFile().isDirectory()) { + try (Reader reader = Files.newBufferedReader(path)) { + read(reader, path, visitor); + return; } } - } - - public static void read(Reader reader, MappingVisitor visitor) throws IOException { - read(reader, null, visitor); - } - - public static void read(Reader reader, MappingFormat format, MappingVisitor visitor) throws IOException { - if (format == null) { - if (!reader.markSupported()) reader = new BufferedReader(reader); - reader.mark(DETECT_HEADER_LEN); - format = detectFormat(reader); - reader.reset(); - if (format == null) throw new IOException("invalid/unsupported mapping format"); - } - checkReaderCompatible(format); - - switch (format) { - case TINY_FILE: - Tiny1FileReader.read(reader, visitor); - break; - case TINY_2_FILE: - Tiny2FileReader.read(reader, visitor); - break; - case ENIGMA_FILE: - EnigmaFileReader.read(reader, visitor); - break; - case SRG_FILE: - SrgFileReader.read(reader, visitor); - break; - case TSRG_FILE: - case TSRG_2_FILE: - TsrgFileReader.read(reader, visitor); - break; - case PROGUARD_FILE: - ProGuardFileReader.read(reader, visitor); - break; - default: - throw new IllegalStateException(); - } + throw new UnsupportedOperationException("format doesn't support directories"); } - private static void checkReaderCompatible(MappingFormat format) throws IOException { - if (!format.hasSingleFile()) { - throw new IOException("can't read mapping format "+format.name+" using a Reader, use the Path based API"); - } + /** + * Read mappings from the reader if the format supports it, otherwise from the path. + * @param reader the reader to read from, given the format supports it + * @param path the file or directory to read from alternatively + * @param visitor the visitor receiving the mappings + * @throws IOException if an I/O error occurs or none of the given sources could be used + */ + void read(Reader reader, @Nullable Path path, MappingVisitor visitor) throws IOException; + + default List getNamespaces(Reader reader) throws IOException { + return Arrays.asList(MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK); } - - private static final int DETECT_HEADER_LEN = 4096; } diff --git a/src/main/java/net/fabricmc/mappingio/MappingWriter.java b/src/main/java/net/fabricmc/mappingio/MappingWriter.java index 736f1a2f..754125b5 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingWriter.java +++ b/src/main/java/net/fabricmc/mappingio/MappingWriter.java @@ -18,41 +18,11 @@ import java.io.Closeable; import java.io.IOException; -import java.io.Writer; -import java.nio.file.Files; -import java.nio.file.Path; -import net.fabricmc.mappingio.format.MappingFormat; -import net.fabricmc.mappingio.format.enigma.EnigmaDirWriter; -import net.fabricmc.mappingio.format.enigma.EnigmaFileWriter; -import net.fabricmc.mappingio.format.proguard.ProGuardFileWriter; -import net.fabricmc.mappingio.format.tiny.Tiny1FileWriter; -import net.fabricmc.mappingio.format.tiny.Tiny2FileWriter; +import org.jetbrains.annotations.ApiStatus; +@ApiStatus.NonExtendable public interface MappingWriter extends Closeable, MappingVisitor { - static MappingWriter create(Path file, MappingFormat format) throws IOException { - if (format.hasSingleFile()) { - return create(Files.newBufferedWriter(file), format); - } else { - switch (format) { - case ENIGMA_DIR: return new EnigmaDirWriter(file, true); - default: throw new UnsupportedOperationException("format "+format+" is not implemented"); - } - } - } - - static MappingWriter create(Writer writer, MappingFormat format) throws IOException { - if (!format.hasSingleFile()) throw new IllegalArgumentException("format "+format+" is not applicable to a single writer"); - - switch (format) { - case TINY_FILE: return new Tiny1FileWriter(writer); - case TINY_2_FILE: return new Tiny2FileWriter(writer, false); - case ENIGMA_FILE: return new EnigmaFileWriter(writer); - case PROGUARD_FILE: return new ProGuardFileWriter(writer); - default: throw new UnsupportedOperationException("format "+format+" is not implemented"); - } - } - @Override default boolean visitEnd() throws IOException { close(); diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java b/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java new file mode 100644 index 00000000..1d60d7fa --- /dev/null +++ b/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java @@ -0,0 +1,39 @@ +/* + * 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; + +import java.io.IOException; +import java.io.Reader; +import java.nio.file.Path; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingVisitor; + +@ApiStatus.Internal +public interface MappingDirReader extends MappingReader { + @Override + default void read(Path dir, MappingVisitor visitor) throws IOException { + read(null, dir, visitor); + } + + @Override + void read(@Nullable Reader reader, @NotNull Path dir, MappingVisitor visitor) throws IOException; +} diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java b/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java new file mode 100644 index 00000000..e8062d4a --- /dev/null +++ b/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java @@ -0,0 +1,38 @@ +/* + * 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; + +import java.io.IOException; +import java.io.Reader; + +import org.jetbrains.annotations.ApiStatus; + +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingVisitor; + +@ApiStatus.Internal +public interface MappingFileReader extends MappingReader { + /** + * Read mappings from the passed reader. + * @param reader the reader to read from + * @param visitor the visitor receiving the mappings + * @throws IOException if an I/O error occurs + */ + default void read(Reader reader, MappingVisitor visitor) throws IOException { + read(reader, null, visitor); + } +} diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java index 76285670..1610c001 100644 --- a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java +++ b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java @@ -16,6 +16,27 @@ package net.fabricmc.mappingio.format; +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.format.enigma.EnigmaDirReader; +import net.fabricmc.mappingio.format.enigma.EnigmaDirWriter; +import net.fabricmc.mappingio.format.enigma.EnigmaFileReader; +import net.fabricmc.mappingio.format.enigma.EnigmaFileWriter; +import net.fabricmc.mappingio.format.proguard.ProGuardFileReader; +import net.fabricmc.mappingio.format.proguard.ProGuardFileWriter; +import net.fabricmc.mappingio.format.srg.SrgFileReader; +import net.fabricmc.mappingio.format.srg.TsrgFileReader; +import net.fabricmc.mappingio.format.tiny.Tiny1FileReader; +import net.fabricmc.mappingio.format.tiny.Tiny1FileWriter; +import net.fabricmc.mappingio.format.tiny.Tiny2FileReader; +import net.fabricmc.mappingio.format.tiny.Tiny2FileWriter; + /** * Represents a supported mapping format. Feature comparison table: * @@ -98,46 +119,47 @@ public enum MappingFormat { /** * The {@code Tiny} mapping format, as specified here. */ - TINY_FILE("Tiny file", "tiny", true, true, false, false, false), + TINY_FILE("Tiny file", "tiny", true, true, false, false, false, Tiny1FileReader.getInstance()), /** * The {@code Tiny v2} mapping format, as specified here. */ - TINY_2_FILE("Tiny v2 file", "tiny", true, true, true, true, true), + TINY_2_FILE("Tiny v2 file", "tiny", true, true, true, true, true, Tiny2FileReader.getInstance()), /** * Enigma's mapping format, as specified here. */ - ENIGMA_FILE("Enigma file", "mapping", false, true, true, true, false), + ENIGMA_FILE("Enigma file", "mapping", false, true, true, true, false, EnigmaFileReader.getInstance()), /** * Enigma's mapping format (in directory form), as specified here. */ - ENIGMA_DIR("Enigma directory", null, false, true, true, true, false), + ENIGMA_DIR("Enigma directory", null, false, true, true, true, false, EnigmaDirReader.getInstance()), /** * The {@code SRG} ({@code Searge RetroGuard}) mapping format, as specified here. */ - SRG_FILE("SRG file", "srg", false, false, false, false, false), + SRG_FILE("SRG file", "srg", false, false, false, false, false, SrgFileReader.getInstance()), /** * The {@code TSRG} ({@code Tiny SRG}, since it saves disk space over SRG) mapping format, as specified here. */ - TSRG_FILE("TSRG file", "tsrg", false, false, false, false, false), + TSRG_FILE("TSRG file", "tsrg", false, false, false, false, false, TsrgFileReader.getInstance()), /** * The {@code TSRG v2} mapping format, as specified here. */ - TSRG_2_FILE("TSRG2 file", "tsrg", true, false, false, true, false), + TSRG_2_FILE("TSRG2 file", "tsrg", true, false, false, true, false, TsrgFileReader.getInstance()), /** * ProGuard's mapping format, as specified here. */ - PROGUARD_FILE("ProGuard file", "txt", false, true, false, false, false); + PROGUARD_FILE("ProGuard file", "txt", false, true, false, false, false, ProGuardFileReader.getInstance()); MappingFormat(String name, String fileExt, boolean hasNamespaces, boolean hasFieldDescriptors, - boolean supportsComments, boolean supportsArgs, boolean supportsLocals) { + boolean supportsComments, boolean supportsArgs, boolean supportsLocals, + MappingReader reader) { this.name = name; this.fileExt = fileExt; this.hasNamespaces = hasNamespaces; @@ -145,6 +167,7 @@ public enum MappingFormat { this.supportsComments = supportsComments; this.supportsArgs = supportsArgs; this.supportsLocals = supportsLocals; + this.reader = reader; } public boolean hasSingleFile() { @@ -157,6 +180,32 @@ public String getGlobPattern() { return "*."+fileExt; } + public MappingWriter newWriter(Path path) throws IOException { + Objects.requireNonNull(path, "path must not be null"); + + if (hasSingleFile()) { + return newWriter(Files.newBufferedWriter(path)); + } else { + switch (this) { + case ENIGMA_DIR: return new EnigmaDirWriter(path, true); + default: throw new UnsupportedOperationException("format "+this+" is not implemented"); + } + } + } + + public MappingWriter newWriter(Writer writer) throws IOException { + if (!hasSingleFile()) throw new IllegalArgumentException("format "+this+" is not applicable to a single writer"); + Objects.requireNonNull(writer, "writer must not be null"); + + switch (this) { + case TINY_FILE: return new Tiny1FileWriter(writer); + case TINY_2_FILE: return new Tiny2FileWriter(writer, false); + case ENIGMA_FILE: return new EnigmaFileWriter(writer); + case PROGUARD_FILE: return new ProGuardFileWriter(writer); + default: throw new UnsupportedOperationException("format "+this+" is not implemented"); + } + } + public final String name; public final String fileExt; public final boolean hasNamespaces; @@ -164,4 +213,5 @@ public String getGlobPattern() { public final boolean supportsComments; public final boolean supportsArgs; public final boolean supportsLocals; + public final MappingReader reader; } diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java index 54fd3de1..10f4c8f2 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java @@ -16,31 +16,43 @@ package net.fabricmc.mappingio.format.enigma; +import java.io.BufferedReader; import java.io.IOException; +import java.io.Reader; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; +import java.util.Objects; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.format.MappingDirReader; import net.fabricmc.mappingio.format.MappingFormat; -public final class EnigmaDirReader { +public final class EnigmaDirReader implements MappingDirReader { private EnigmaDirReader() { } - public static void read(Path dir, MappingVisitor visitor) throws IOException { + public static EnigmaDirReader getInstance() { + return INSTANCE; + } + + @Override + public void read(Reader reader, Path dir, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(dir, "dir path must not be null"); read(dir, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor); } - public static void read(Path dir, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + public void read(Path dir, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { Files.walkFileTree(dir, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (file.getFileName().toString().endsWith("." + MappingFormat.ENIGMA_FILE.fileExt)) { - EnigmaFileReader.read(Files.newBufferedReader(file), sourceNs, targetNs, visitor); + try (BufferedReader reader = Files.newBufferedReader(file)) { + EnigmaFileReader.getInstance().read(reader, sourceNs, targetNs, visitor); + } } return FileVisitResult.CONTINUE; @@ -48,4 +60,6 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO }); visitor.visitEnd(); } + + private static final EnigmaDirReader INSTANCE = new EnigmaDirReader(); } diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java index 1c44ae7d..4644fed6 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java @@ -18,30 +18,42 @@ import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.Collections; +import java.util.Objects; import java.util.Set; +import org.jetbrains.annotations.Nullable; + 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.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public final class EnigmaFileReader { +public final class EnigmaFileReader implements MappingFileReader { private EnigmaFileReader() { } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + public static EnigmaFileReader getInstance() { + return INSTANCE; + } + + @Override + public void read(Reader reader, @Nullable Path dir, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); + 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 { + public void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor); } - public static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + public void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { Set flags = visitor.getFlags(); MappingVisitor parentVisitor = null; @@ -74,7 +86,7 @@ public static void read(ColumnFileReader reader, String sourceNs, String targetN } } - private static void readClass(ColumnFileReader reader, int indent, String outerSrcClass, String outerDstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private void readClass(ColumnFileReader reader, int indent, String outerSrcClass, String outerDstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { String srcInnerName = reader.nextCol(); if (srcInnerName == null || srcInnerName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber()); @@ -99,7 +111,7 @@ private static void readClass(ColumnFileReader reader, int indent, String outerS readClassBody(reader, indent, srcName, dstName, commentSb, visitor); } - private static void readClassBody(ColumnFileReader reader, int indent, String srcClass, String dstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private void readClassBody(ColumnFileReader reader, int indent, String srcClass, String dstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { boolean visited = false; int state = 0; // 0=invalid 1=visit -1=skip @@ -155,7 +167,7 @@ private static void readClassBody(ColumnFileReader reader, int indent, String sr /** * Re-visit a class if necessary and visit its comment if available. */ - private static int visitClass(String srcClass, String dstClass, int state, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private int visitClass(String srcClass, String dstClass, int state, StringBuilder commentSb, MappingVisitor visitor) throws IOException { // state: 0=invalid 1=visit -1=skip if (state == 0) { @@ -178,7 +190,7 @@ private static int visitClass(String srcClass, String dstClass, int state, Strin return state; } - private static void readMethod(ColumnFileReader reader, int indent, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private void readMethod(ColumnFileReader reader, int indent, StringBuilder commentSb, MappingVisitor visitor) throws IOException { if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; while (reader.nextLine(indent + 2)) { @@ -204,7 +216,7 @@ private static void readMethod(ColumnFileReader reader, int indent, StringBuilde submitComment(MappedElementKind.METHOD, commentSb, visitor); } - private static void readElement(ColumnFileReader reader, MappedElementKind kind, int indent, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private void readElement(ColumnFileReader reader, MappedElementKind kind, int indent, StringBuilder commentSb, MappingVisitor visitor) throws IOException { if (!visitor.visitElementContent(kind)) return; while (reader.nextLine(indent + kind.level + 1)) { @@ -216,7 +228,7 @@ private static void readElement(ColumnFileReader reader, MappedElementKind kind, submitComment(kind, commentSb, visitor); } - private static void readComment(ColumnFileReader reader, StringBuilder commentSb) throws IOException { + private void readComment(ColumnFileReader reader, StringBuilder commentSb) throws IOException { if (commentSb.length() > 0) commentSb.append('\n'); String comment = reader.nextCols(true); @@ -226,10 +238,12 @@ private static void readComment(ColumnFileReader reader, StringBuilder commentSb } } - private static void submitComment(MappedElementKind kind, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private void submitComment(MappedElementKind kind, StringBuilder commentSb, MappingVisitor visitor) throws IOException { if (commentSb.length() == 0) return; visitor.visitComment(kind, commentSb.toString()); commentSb.setLength(0); } + + private static final EnigmaFileReader INSTANCE = new EnigmaFileReader(); } diff --git a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java index d1670b7d..61c31054 100644 --- a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java @@ -20,29 +20,40 @@ import java.io.CharArrayReader; import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; +import java.util.Objects; + +import org.jetbrains.annotations.Nullable; 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.MappingFileReader; -public final class ProGuardFileReader { +public final class ProGuardFileReader implements MappingFileReader { private ProGuardFileReader() { } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + public static ProGuardFileReader getInstance() { + return INSTANCE; + } + + @Override + public void read(Reader reader, @Nullable Path path, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); 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 { + public void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { BufferedReader br = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); read(br, sourceNs, targetNs, visitor); } - private static void read(BufferedReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + private void read(BufferedReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { CharArrayReader parentReader = null; if (visitor.getFlags().contains(MappingFlag.NEEDS_MULTIPLE_PASSES)) { @@ -227,4 +238,6 @@ private static void appendPgTypeToAsm(String type, StringBuilder out) { out.append(';'); } } + + private static final ProGuardFileReader INSTANCE = new ProGuardFileReader(); } 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 4383841f..76cd228a 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java @@ -18,30 +18,42 @@ import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.Collections; +import java.util.Objects; import java.util.Set; +import org.jetbrains.annotations.Nullable; + 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.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public final class SrgFileReader { +public final class SrgFileReader implements MappingFileReader { private SrgFileReader() { } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + public static SrgFileReader getInstance() { + return INSTANCE; + } + + @Override + public void read(Reader reader, @Nullable Path path, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); + 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 { + public 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 { + private void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { Set flags = visitor.getFlags(); MappingVisitor parentVisitor = null; @@ -139,4 +151,6 @@ private static void read(ColumnFileReader reader, String sourceNs, String target ((MappingTree) visitor).accept(parentVisitor); } } + + private static final SrgFileReader INSTANCE = new SrgFileReader(); } 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 5601bf62..d99d4d03 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java @@ -18,26 +18,34 @@ import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; 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.format.MappingFileReader; -public final class TsrgFileReader { +public final class TsrgFileReader implements MappingFileReader { private TsrgFileReader() { } - public static List getNamespaces(Reader reader) throws IOException { + public static TsrgFileReader getInstance() { + return INSTANCE; + } + + @Override + public List getNamespaces(Reader reader) throws IOException { return getNamespaces(new ColumnFileReader(reader, ' ')); } - private static List getNamespaces(ColumnFileReader reader) throws IOException { + private List getNamespaces(ColumnFileReader reader) throws IOException { if (reader.nextCol("tsrg2")) { // tsrg2 magic List ret = new ArrayList<>(); String ns; @@ -52,15 +60,17 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce } } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + @Override + public void read(Reader reader, Path path, 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 { + public void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor); } - private static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + private void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { boolean isTsrg2 = reader.nextCol("tsrg2"); String srcNamespace; List dstNamespaces; @@ -115,7 +125,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target } } - private static void readClass(ColumnFileReader reader, boolean isTsrg2, int dstNsCount, List nameTmp, MappingVisitor visitor) throws IOException { + private void readClass(ColumnFileReader reader, boolean isTsrg2, int dstNsCount, List nameTmp, MappingVisitor visitor) throws IOException { readDstNames(reader, MappedElementKind.CLASS, 0, dstNsCount, visitor); if (!visitor.visitElementContent(MappedElementKind.CLASS)) return; @@ -178,7 +188,7 @@ private static void readClass(ColumnFileReader reader, boolean isTsrg2, int dstN } } - private static void readMethod(ColumnFileReader reader, int dstNsCount, MappingVisitor visitor) throws IOException { + private void readMethod(ColumnFileReader reader, int dstNsCount, MappingVisitor visitor) throws IOException { readDstNames(reader, MappedElementKind.METHOD, 0, dstNsCount, visitor); if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; @@ -202,12 +212,12 @@ private static void readMethod(ColumnFileReader reader, int dstNsCount, MappingV } } - private static void readElement(ColumnFileReader reader, MappedElementKind kind, int dstNsOffset, int dstNsCount, MappingVisitor visitor) throws IOException { + private void readElement(ColumnFileReader reader, MappedElementKind kind, int dstNsOffset, int dstNsCount, MappingVisitor visitor) throws IOException { readDstNames(reader, kind, dstNsOffset, dstNsCount, visitor); visitor.visitElementContent(kind); } - private static void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsOffset, int dstNsCount, MappingVisitor visitor) throws IOException { + private void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsOffset, int dstNsCount, MappingVisitor visitor) throws IOException { for (int dstNs = dstNsOffset; dstNs < dstNsCount; dstNs++) { String name = reader.nextCol(); if (name == null) throw new IOException("missing name columns in line "+reader.getLineNumber()); @@ -215,4 +225,6 @@ private static void readDstNames(ColumnFileReader reader, MappedElementKind subj if (!name.isEmpty()) visitor.visitDstName(subjectKind, dstNs, name); } } + + private static final TsrgFileReader INSTANCE = new TsrgFileReader(); } 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 56e2517c..0f53a68b 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java @@ -18,26 +18,36 @@ import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; +import org.jetbrains.annotations.Nullable; + import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public final class Tiny1FileReader { +public final class Tiny1FileReader implements MappingFileReader { private Tiny1FileReader() { } - public static List getNamespaces(Reader reader) throws IOException { + public static Tiny1FileReader getInstance() { + return INSTANCE; + } + + @Override + public List getNamespaces(Reader reader) throws IOException { return getNamespaces(new ColumnFileReader(reader, '\t')); } - private static List getNamespaces(ColumnFileReader reader) throws IOException { + private List getNamespaces(ColumnFileReader reader) throws IOException { if (!reader.nextCol("v1")) { // magic/version throw new IOException("invalid/unsupported tiny file: no tiny 1 header"); } @@ -52,11 +62,14 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce return ret; } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + @Override + public void read(Reader reader, @Nullable Path path, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); + read(new ColumnFileReader(reader, '\t'), visitor); } - private static void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { + private void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { if (!reader.nextCol("v1")) { // magic/version throw new IOException("invalid/unsupported tiny file: no tiny 1 header"); } @@ -171,7 +184,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws } } - private static void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsCount, MappingVisitor visitor) throws IOException { + private void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsCount, MappingVisitor visitor) throws IOException { for (int dstNs = 0; dstNs < dstNsCount; dstNs++) { String name = reader.nextCol(); if (name == null) throw new IOException("missing name columns in line "+reader.getLineNumber()); @@ -183,4 +196,5 @@ private static void readDstNames(ColumnFileReader reader, MappedElementKind subj static final String nextIntermediaryClassProperty = "next-intermediary-class"; static final String nextIntermediaryFieldProperty = "next-intermediary-field"; static final String nextIntermediaryMethodProperty = "next-intermediary-method"; + private static final Tiny1FileReader INSTANCE = new Tiny1FileReader(); } 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 bcdf2406..b2ed0a1a 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.Set; import net.fabricmc.mappingio.MappedElementKind; @@ -29,6 +30,7 @@ public final class Tiny1FileWriter implements MappingWriter { public Tiny1FileWriter(Writer writer) { + Objects.requireNonNull(writer, "writer must not be null"); this.writer = writer; } diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java index 6381d80f..e349be36 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java @@ -18,23 +18,33 @@ import java.io.IOException; import java.io.Reader; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Objects; + +import org.jetbrains.annotations.Nullable; import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingFileReader; -public final class Tiny2FileReader { +public final class Tiny2FileReader implements MappingFileReader { private Tiny2FileReader() { } - public static List getNamespaces(Reader reader) throws IOException { + public static Tiny2FileReader getInstance() { + return INSTANCE; + } + + @Override + public List getNamespaces(Reader reader) throws IOException { return getNamespaces(new ColumnFileReader(reader, '\t')); } - private static List getNamespaces(ColumnFileReader reader) throws IOException { + private List getNamespaces(ColumnFileReader reader) throws IOException { if (!reader.nextCol("tiny") // magic || reader.nextIntCol() != 2 // major version || reader.nextIntCol() < 0) { // minor version @@ -51,11 +61,13 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce return ret; } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { + @Override + public void read(Reader reader, @Nullable Path path, MappingVisitor visitor) throws IOException { + Objects.requireNonNull(reader, "reader must not be null"); read(new ColumnFileReader(reader, '\t'), visitor); } - private static void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { + private void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { if (!reader.nextCol("tiny") // magic || reader.nextIntCol() != 2 // major version || reader.nextIntCol() < 0) { // minor version @@ -126,7 +138,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws } } - private static void readClass(ColumnFileReader reader, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { + private void readClass(ColumnFileReader reader, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { readDstNames(reader, MappedElementKind.CLASS, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(MappedElementKind.CLASS)) return; @@ -155,7 +167,7 @@ private static void readClass(ColumnFileReader reader, int dstNsCount, boolean e } } - private static void readMethod(ColumnFileReader reader, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { + private void readMethod(ColumnFileReader reader, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { readDstNames(reader, MappedElementKind.METHOD, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; @@ -189,7 +201,7 @@ private static void readMethod(ColumnFileReader reader, int dstNsCount, boolean } } - private static void readElement(ColumnFileReader reader, MappedElementKind kind, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { + private void readElement(ColumnFileReader reader, MappedElementKind kind, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { readDstNames(reader, kind, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(kind)) return; @@ -200,14 +212,14 @@ private static void readElement(ColumnFileReader reader, MappedElementKind kind, } } - private static void readComment(ColumnFileReader reader, MappedElementKind subjectKind, MappingVisitor visitor) throws IOException { + private void readComment(ColumnFileReader reader, MappedElementKind subjectKind, MappingVisitor visitor) throws IOException { String comment = reader.nextEscapedCol(); if (comment == null) throw new IOException("missing comment in line "+reader.getLineNumber()); visitor.visitComment(subjectKind, comment); } - private static void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { + private void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { for (int dstNs = 0; dstNs < dstNsCount; dstNs++) { String name = reader.nextCol(escapeNames); if (name == null) throw new IOException("missing name columns in line "+reader.getLineNumber()); @@ -215,4 +227,6 @@ private static void readDstNames(ColumnFileReader reader, MappedElementKind subj if (!name.isEmpty()) visitor.visitDstName(subjectKind, dstNs, name); } } + + private static final Tiny2FileReader INSTANCE = new Tiny2FileReader(); } diff --git a/src/test/java/net/fabricmc/mappingio/TestHelper.java b/src/test/java/net/fabricmc/mappingio/TestHelper.java index 24cb0e07..cd219593 100644 --- a/src/test/java/net/fabricmc/mappingio/TestHelper.java +++ b/src/test/java/net/fabricmc/mappingio/TestHelper.java @@ -36,7 +36,7 @@ public static Path getResource(String slashPrefixedResourcePath) { } public static void writeToDir(MappingTree tree, MappingFormat format, Path dir) throws IOException { - MappingWriter writer = MappingWriter.create(dir.resolve(format.name() + "." + format.fileExt), format); + MappingWriter writer = format.newWriter(dir.resolve(format.name() + "." + format.fileExt)); tree.accept(writer); writer.close(); } diff --git a/src/test/java/net/fabricmc/mappingio/read/EmptyContentReadTest.java b/src/test/java/net/fabricmc/mappingio/read/EmptyContentReadTest.java index a915520e..64ce4c79 100644 --- a/src/test/java/net/fabricmc/mappingio/read/EmptyContentReadTest.java +++ b/src/test/java/net/fabricmc/mappingio/read/EmptyContentReadTest.java @@ -37,31 +37,31 @@ public class EmptyContentReadTest { @Test public void emptyEnigmaFile() throws Exception { - EnigmaFileReader.read(new StringReader(""), tree); + EnigmaFileReader.getInstance().read(new StringReader(""), tree); } @Test public void emptyTinyFile() throws Exception { - assertThrows(IOException.class, () -> Tiny1FileReader.read(new StringReader(""), tree)); + assertThrows(IOException.class, () -> Tiny1FileReader.getInstance().read(new StringReader(""), tree)); } @Test public void emptyTinyV2File() throws Exception { - assertThrows(IOException.class, () -> Tiny2FileReader.read(new StringReader(""), tree)); + assertThrows(IOException.class, () -> Tiny2FileReader.getInstance().read(new StringReader(""), tree)); } @Test public void emptyProguardFile() throws Exception { - ProGuardFileReader.read(new StringReader(""), tree); + ProGuardFileReader.getInstance().read(new StringReader(""), tree); } @Test public void emptySrgFile() throws Exception { - SrgFileReader.read(new StringReader(""), tree); + SrgFileReader.getInstance().read(new StringReader(""), tree); } @Test public void emptyTsrgFile() throws Exception { - TsrgFileReader.read(new StringReader(""), tree); + TsrgFileReader.getInstance().read(new StringReader(""), tree); } } diff --git a/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java b/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java index 720042bd..84c0841c 100644 --- a/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java +++ b/src/test/java/net/fabricmc/mappingio/read/ValidContentReadTest.java @@ -31,7 +31,6 @@ import org.opentest4j.AssertionFailedError; import net.fabricmc.mappingio.FlatMappingVisitor; -import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.TestHelper; import net.fabricmc.mappingio.adapter.FlatAsRegularMappingVisitor; @@ -92,7 +91,7 @@ public void tsrg2File() throws Exception { private VisitableMappingTree checkCommonContent(String path, MappingFormat format) throws Exception { VisitableMappingTree tree = new MemoryMappingTree(); - MappingReader.read(dir.resolve(path), format, tree); + format.reader.read(dir.resolve(path), tree); assertSubset(tree, format, origTree, null); assertSubset(origTree, null, tree, format); From 43749a1b810fbec694800170ba8b585589172766 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 7 Oct 2023 10:00:57 +0200 Subject: [PATCH 2/4] Return null when no format reader/writer exists --- .../java/net/fabricmc/mappingio/format/MappingFormat.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java index 1610c001..481d4b97 100644 --- a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java +++ b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java @@ -22,6 +22,8 @@ import java.nio.file.Path; import java.util.Objects; +import org.jetbrains.annotations.Nullable; + import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.MappingWriter; import net.fabricmc.mappingio.format.enigma.EnigmaDirReader; @@ -180,6 +182,7 @@ public String getGlobPattern() { return "*."+fileExt; } + @Nullable public MappingWriter newWriter(Path path) throws IOException { Objects.requireNonNull(path, "path must not be null"); @@ -188,11 +191,12 @@ public MappingWriter newWriter(Path path) throws IOException { } else { switch (this) { case ENIGMA_DIR: return new EnigmaDirWriter(path, true); - default: throw new UnsupportedOperationException("format "+this+" is not implemented"); + default: return null; } } } + @Nullable public MappingWriter newWriter(Writer writer) throws IOException { if (!hasSingleFile()) throw new IllegalArgumentException("format "+this+" is not applicable to a single writer"); Objects.requireNonNull(writer, "writer must not be null"); @@ -202,7 +206,7 @@ public MappingWriter newWriter(Writer writer) throws IOException { case TINY_2_FILE: return new Tiny2FileWriter(writer, false); case ENIGMA_FILE: return new EnigmaFileWriter(writer); case PROGUARD_FILE: return new ProGuardFileWriter(writer); - default: throw new UnsupportedOperationException("format "+this+" is not implemented"); + default: return null; } } From bc3345db9a39bacb15e9538f507ef0ceb600e789 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 7 Oct 2023 10:19:41 +0200 Subject: [PATCH 3/4] Provide general-purpose `newWriter` method --- .../mappingio/format/MappingFormat.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java index 481d4b97..ad820656 100644 --- a/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java +++ b/src/main/java/net/fabricmc/mappingio/format/MappingFormat.java @@ -182,30 +182,42 @@ public String getGlobPattern() { return "*."+fileExt; } + /** + * Create a new writer instance for this format. + * @param path the path to write to + * @return the new writer instance, or null if no writer supports this format + */ @Nullable public MappingWriter newWriter(Path path) throws IOException { Objects.requireNonNull(path, "path must not be null"); if (hasSingleFile()) { - return newWriter(Files.newBufferedWriter(path)); - } else { - switch (this) { - case ENIGMA_DIR: return new EnigmaDirWriter(path, true); - default: return null; - } + return newWriter(Files.newBufferedWriter(path), path); } + + return newWriter(null, path); } + /** + * Create a new writer instance for this format. + * @param writer the writer to write to, used if the format is single-file based + * @param path the path to write to, used if the format is directory based + * @return the new writer instance, or null if no writer supports this format + */ @Nullable - public MappingWriter newWriter(Writer writer) throws IOException { - if (!hasSingleFile()) throw new IllegalArgumentException("format "+this+" is not applicable to a single writer"); - Objects.requireNonNull(writer, "writer must not be null"); + public MappingWriter newWriter(Writer writer, @Nullable Path path) throws IOException { + if (hasSingleFile()) { + Objects.requireNonNull(writer, "writer must not be null for single-file based formats"); + } else if (path == null) { + throw new IllegalArgumentException("format "+this+" is not applicable to a single writer. Use the Path based API instead."); + } switch (this) { case TINY_FILE: return new Tiny1FileWriter(writer); case TINY_2_FILE: return new Tiny2FileWriter(writer, false); case ENIGMA_FILE: return new EnigmaFileWriter(writer); case PROGUARD_FILE: return new ProGuardFileWriter(writer); + case ENIGMA_DIR: return new EnigmaDirWriter(path, true); default: return null; } } From 71bf130ffbcde759cb5e69b19ba976d8fc2ecad9 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 7 Oct 2023 10:26:44 +0200 Subject: [PATCH 4/4] Move `MappingFileReader` and `MappingDirReader` --- .../net/fabricmc/mappingio/MappingReader.java | 25 ++++++++++++ .../mappingio/format/MappingDirReader.java | 39 ------------------- .../mappingio/format/MappingFileReader.java | 38 ------------------ .../format/enigma/EnigmaDirReader.java | 2 +- .../format/enigma/EnigmaFileReader.java | 2 +- .../format/proguard/ProGuardFileReader.java | 2 +- .../mappingio/format/srg/SrgFileReader.java | 2 +- .../mappingio/format/srg/TsrgFileReader.java | 2 +- .../format/tiny/Tiny1FileReader.java | 2 +- .../format/tiny/Tiny2FileReader.java | 2 +- 10 files changed, 32 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java delete mode 100644 src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java diff --git a/src/main/java/net/fabricmc/mappingio/MappingReader.java b/src/main/java/net/fabricmc/mappingio/MappingReader.java index fa8aca64..539e9209 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingReader.java +++ b/src/main/java/net/fabricmc/mappingio/MappingReader.java @@ -26,6 +26,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import net.fabricmc.mappingio.format.MappingFormat; @@ -110,4 +111,28 @@ default void read(Path path, MappingVisitor visitor) throws IOException { default List getNamespaces(Reader reader) throws IOException { return Arrays.asList(MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK); } + + @ApiStatus.Internal + interface MappingFileReader extends MappingReader { + /** + * Read mappings from the passed reader. + * @param reader the reader to read from + * @param visitor the visitor receiving the mappings + * @throws IOException if an I/O error occurs + */ + default void read(Reader reader, MappingVisitor visitor) throws IOException { + read(reader, null, visitor); + } + } + + @ApiStatus.Internal + interface MappingDirReader extends MappingReader { + @Override + default void read(Path dir, MappingVisitor visitor) throws IOException { + read(null, dir, visitor); + } + + @Override + void read(@Nullable Reader reader, @NotNull Path dir, MappingVisitor visitor) throws IOException; + } } diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java b/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java deleted file mode 100644 index 1d60d7fa..00000000 --- a/src/main/java/net/fabricmc/mappingio/format/MappingDirReader.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Path; - -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.MappingVisitor; - -@ApiStatus.Internal -public interface MappingDirReader extends MappingReader { - @Override - default void read(Path dir, MappingVisitor visitor) throws IOException { - read(null, dir, visitor); - } - - @Override - void read(@Nullable Reader reader, @NotNull Path dir, MappingVisitor visitor) throws IOException; -} diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java b/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java deleted file mode 100644 index e8062d4a..00000000 --- a/src/main/java/net/fabricmc/mappingio/format/MappingFileReader.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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; - -import java.io.IOException; -import java.io.Reader; - -import org.jetbrains.annotations.ApiStatus; - -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.MappingVisitor; - -@ApiStatus.Internal -public interface MappingFileReader extends MappingReader { - /** - * Read mappings from the passed reader. - * @param reader the reader to read from - * @param visitor the visitor receiving the mappings - * @throws IOException if an I/O error occurs - */ - default void read(Reader reader, MappingVisitor visitor) throws IOException { - read(reader, null, visitor); - } -} diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java index 10f4c8f2..dee0efee 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java @@ -26,9 +26,9 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.Objects; +import net.fabricmc.mappingio.MappingReader.MappingDirReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; -import net.fabricmc.mappingio.format.MappingDirReader; import net.fabricmc.mappingio.format.MappingFormat; public final class EnigmaDirReader implements MappingDirReader { diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java index 4644fed6..00250c68 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java @@ -27,10 +27,10 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; -import net.fabricmc.mappingio.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; diff --git a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java index 61c31054..5c0191f8 100644 --- a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java @@ -29,9 +29,9 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; -import net.fabricmc.mappingio.format.MappingFileReader; public final class ProGuardFileReader implements MappingFileReader { private ProGuardFileReader() { 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 76cd228a..5973be2b 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java @@ -27,10 +27,10 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; -import net.fabricmc.mappingio.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; 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 d99d4d03..f63017ee 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/TsrgFileReader.java @@ -27,10 +27,10 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; -import net.fabricmc.mappingio.format.MappingFileReader; public final class TsrgFileReader implements MappingFileReader { private TsrgFileReader() { 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 0f53a68b..632f507e 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java @@ -28,9 +28,9 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; -import net.fabricmc.mappingio.format.MappingFileReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java index e349be36..19a4fa9d 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java @@ -27,9 +27,9 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; +import net.fabricmc.mappingio.MappingReader.MappingFileReader; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.format.ColumnFileReader; -import net.fabricmc.mappingio.format.MappingFileReader; public final class Tiny2FileReader implements MappingFileReader { private Tiny2FileReader() {