diff --git a/src/main/java/net/fabricmc/mappingio/FlatMappingVisitor.java b/src/main/java/net/fabricmc/mappingio/FlatMappingVisitor.java index 056020ed..2c8fd897 100644 --- a/src/main/java/net/fabricmc/mappingio/FlatMappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/FlatMappingVisitor.java @@ -49,10 +49,11 @@ default void visitMetadata(String key, String value) throws IOException { } /** * Determine whether the mapping content (classes and anything below, metadata if not part of the header) should be visited. + * Lazy callers, which don't know beforehand how many elements they're going to have (e.g. mapping readers), must pass -1. * * @return true if content is to be visited, false otherwise */ - default boolean visitContent() throws IOException { + default boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { return true; } diff --git a/src/main/java/net/fabricmc/mappingio/MappingReader.java b/src/main/java/net/fabricmc/mappingio/MappingReader.java index 43dca6d4..87b1045f 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingReader.java +++ b/src/main/java/net/fabricmc/mappingio/MappingReader.java @@ -135,11 +135,11 @@ public static List getNamespaces(Reader reader, MappingFormat format) th } } - public static void read(Path file, MappingVisitor visitor) throws IOException { - read(file, null, visitor); + public static void read(Path file, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(file, null, visitor, progressListener); } - public static void read(Path file, MappingFormat format, MappingVisitor visitor) throws IOException { + public static void read(Path file, MappingFormat format, MappingVisitor visitor, ProgressListener progressListener) throws IOException { if (format == null) { format = detectFormat(file); if (format == null) throw new IOException("invalid/unsupported mapping format"); @@ -147,12 +147,12 @@ public static void read(Path file, MappingFormat format, MappingVisitor visitor) if (format.hasSingleFile()) { try (Reader reader = Files.newBufferedReader(file)) { - read(reader, format, visitor); + read(reader, format, visitor, progressListener); } } else { switch (format) { case ENIGMA_DIR: - EnigmaDirReader.read(file, visitor); + EnigmaDirReader.read(file, visitor, progressListener); break; case MCP_DIR: throw new UnsupportedOperationException(); // TODO: implement @@ -162,11 +162,11 @@ public static void read(Path file, MappingFormat format, MappingVisitor visitor) } } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { - read(reader, null, visitor); + public static void read(Reader reader, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(reader, null, visitor, progressListener); } - public static void read(Reader reader, MappingFormat format, MappingVisitor visitor) throws IOException { + public static void read(Reader reader, MappingFormat format, MappingVisitor visitor, ProgressListener progressListener) throws IOException { if (format == null) { if (!reader.markSupported()) reader = new BufferedReader(reader); reader.mark(DETECT_HEADER_LEN); @@ -179,23 +179,23 @@ public static void read(Reader reader, MappingFormat format, MappingVisitor visi switch (format) { case TINY_FILE: - Tiny1FileReader.read(reader, visitor); + Tiny1FileReader.read(reader, visitor, progressListener); break; case TINY_2_FILE: - Tiny2FileReader.read(reader, visitor); + Tiny2FileReader.read(reader, visitor, progressListener); break; case ENIGMA_FILE: - EnigmaFileReader.read(reader, visitor); + EnigmaFileReader.read(reader, visitor, progressListener); break; case SRG_FILE: - SrgFileReader.read(reader, visitor); + SrgFileReader.read(reader, visitor, progressListener); break; case TSRG_FILE: case TSRG_2_FILE: - TsrgFileReader.read(reader, visitor); + TsrgFileReader.read(reader, visitor, progressListener); break; case PROGUARD_FILE: - ProGuardFileReader.read(reader, visitor); + ProGuardFileReader.read(reader, visitor, progressListener); break; default: throw new IllegalStateException(); diff --git a/src/main/java/net/fabricmc/mappingio/MappingVisitor.java b/src/main/java/net/fabricmc/mappingio/MappingVisitor.java index 5c2455ce..af279095 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/MappingVisitor.java @@ -73,10 +73,11 @@ default void visitMetadata(String key, String value) throws IOException { } /** * Determine whether the mapping content (classes and anything below, metadata if not part of the header) should be visited. + * Lazy callers, which don't know beforehand how many elements they're going to have (e.g. mapping readers), must pass -1. * * @return true if content is to be visited, false otherwise */ - default boolean visitContent() throws IOException { + default boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { return true; } diff --git a/src/main/java/net/fabricmc/mappingio/MappingWriter.java b/src/main/java/net/fabricmc/mappingio/MappingWriter.java index ee8768d1..0f2a3621 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingWriter.java +++ b/src/main/java/net/fabricmc/mappingio/MappingWriter.java @@ -30,25 +30,25 @@ import net.fabricmc.mappingio.format.tiny.Tiny2FileWriter; public interface MappingWriter extends Closeable, MappingVisitor { - static MappingWriter create(Path file, MappingFormat format) throws IOException { + static MappingWriter create(Path file, MappingFormat format, ProgressListener progressListener) throws IOException { if (format.hasSingleFile()) { - return create(Files.newBufferedWriter(file), format); + return create(Files.newBufferedWriter(file), format, progressListener); } else { switch (format) { - case ENIGMA_DIR: return new EnigmaDirWriter(file, true); + case ENIGMA_DIR: return new EnigmaDirWriter(file, true, progressListener); default: throw new UnsupportedOperationException("format "+format+" is not implemented"); } } } - static MappingWriter create(Writer writer, MappingFormat format) throws IOException { + static MappingWriter create(Writer writer, MappingFormat format, ProgressListener progressListener) 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); + case TINY_FILE: return new Tiny1FileWriter(writer, progressListener); + case TINY_2_FILE: return new Tiny2FileWriter(writer, false, progressListener); + case ENIGMA_FILE: return new EnigmaFileWriter(writer, progressListener); + case PROGUARD_FILE: return new ProGuardFileWriter(writer, progressListener); default: throw new UnsupportedOperationException("format "+format+" is not implemented"); } } diff --git a/src/main/java/net/fabricmc/mappingio/ProgressListener.java b/src/main/java/net/fabricmc/mappingio/ProgressListener.java new file mode 100644 index 00000000..4eaa3dd3 --- /dev/null +++ b/src/main/java/net/fabricmc/mappingio/ProgressListener.java @@ -0,0 +1,161 @@ +/* + * 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; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +public abstract class ProgressListener { + protected ProgressListener(LogLevel logLevel) { + this.logLevel = logLevel; + this.forwarder = this instanceof Forwarder ? (Forwarder) this : new Forwarder(logLevel, this); + } + + /** + * Sets the progress listener's total amount of steps and provides a name for the job. + * If the total amount of steps isn't known beforehand, {@code totalWork} must be set to -1. + * Can only be called once. + */ + protected abstract void init(int totalWork, String title); + + /** + * Indicates the start of a new step being processed, and optionally gives it a name. + */ + protected abstract void startStep(LogLevel logLevel, @Nullable String stepName); + + /** + * Updates the name of the current step. + */ + protected abstract void updateMessage(LogLevel logLevel, @Nullable String stepName); + + /** + * Indicates that all steps have finished processing. + * After that point, further method invocations are illegal. + */ + protected abstract void finish(); + + /** + * Determines the granularity of progress reports the progress listener wishes to receive. + */ + public enum LogLevel { + FILES, + CLASSES, + MEMBERS; + + public boolean allows(LogLevel logLevel) { + if (logLevel.compareTo(this) <= 0) { + return true; + } + + return false; + } + } + + /** + * Class which forwards only applicable log levels to the passed receiver, + * and automatically checks for illegal calls. + */ + @ApiStatus.Internal + public final class Forwarder extends ProgressListener { + private Forwarder(LogLevel logLevel, ProgressListener receiver) { + super(logLevel); + + this.receiver = receiver; + } + + @Override + public void init(int totalWork, String title) { + assertNotFinished(); + + if (initialized && receiver != NOP) { + throw new RuntimeException("Progress listener can only be initialized once!"); + } + + receiver.init(totalWork, title); + initialized = true; + } + + @Override + public void startStep(LogLevel logLevel, @Nullable String stepName) { + assertNotFinished(); + + if (this.logLevel.allows(logLevel)) { + receiver.startStep(logLevel, stepName); + } + } + + @Override + public void updateMessage(LogLevel logLevel, @Nullable String stepName) { + assertNotFinished(); + + if (this.logLevel.allows(logLevel)) { + receiver.updateMessage(logLevel, stepName); + } + } + + @Override + public void finish() { + assertNotFinished(); + receiver.finish(); + finished = true; + } + + private void assertNotFinished() { + if (finished && receiver != NOP) { + throw new RuntimeException("Illegal method invocation, progress listener has already finished!"); + } + } + + private final ProgressListener receiver; + private boolean initialized; + private boolean finished; + } + + /** + * No-op progress listener that ignores all events. + */ + public static final ProgressListener NOP = new ProgressListener(LogLevel.FILES) { + @Override + public void init(int totalWork, String title) { + } + + @Override + public void startStep(LogLevel logLevel, @Nullable String stepName) { + } + + @Override + public void updateMessage(LogLevel logLevel, @Nullable String stepName) { + } + + @Override + public void finish() { + } + }; + + /** + * Finest log level the progress listener accepts. + */ + public final LogLevel logLevel; + + /** + * Public-facing progress listener interface for progress passers to interact with, + * which automatically checks for illegal calls and only forwards the applicable + * log levels to the actual {@link ProgressListener}. + */ + @ApiStatus.Internal + public final Forwarder forwarder; +} diff --git a/src/main/java/net/fabricmc/mappingio/adapter/FlatAsRegularMappingVisitor.java b/src/main/java/net/fabricmc/mappingio/adapter/FlatAsRegularMappingVisitor.java index 34da310f..0e4b16df 100644 --- a/src/main/java/net/fabricmc/mappingio/adapter/FlatAsRegularMappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/adapter/FlatAsRegularMappingVisitor.java @@ -70,8 +70,8 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { - return next.visitContent(); + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { + return next.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); } @Override diff --git a/src/main/java/net/fabricmc/mappingio/adapter/ForwardingMappingVisitor.java b/src/main/java/net/fabricmc/mappingio/adapter/ForwardingMappingVisitor.java index 71d9574f..adf38a16 100644 --- a/src/main/java/net/fabricmc/mappingio/adapter/ForwardingMappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/adapter/ForwardingMappingVisitor.java @@ -58,8 +58,8 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { - return next.visitContent(); + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { + return next.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); } @Override diff --git a/src/main/java/net/fabricmc/mappingio/adapter/MappingNsCompleter.java b/src/main/java/net/fabricmc/mappingio/adapter/MappingNsCompleter.java index fb3fb326..e9f5a880 100644 --- a/src/main/java/net/fabricmc/mappingio/adapter/MappingNsCompleter.java +++ b/src/main/java/net/fabricmc/mappingio/adapter/MappingNsCompleter.java @@ -92,10 +92,10 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { relayHeaderOrMetadata = true; // for in-content metadata - return next.visitContent(); + return next.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); } @Override diff --git a/src/main/java/net/fabricmc/mappingio/adapter/MappingSourceNsSwitch.java b/src/main/java/net/fabricmc/mappingio/adapter/MappingSourceNsSwitch.java index de52a900..f21d00ad 100644 --- a/src/main/java/net/fabricmc/mappingio/adapter/MappingSourceNsSwitch.java +++ b/src/main/java/net/fabricmc/mappingio/adapter/MappingSourceNsSwitch.java @@ -132,12 +132,16 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { if (!classMapReady) return true; relayHeaderOrMetadata = true; // for in-content metadata - return next.visitContent(); + if (dropMissingNewSrcName) { + return next.visitContent(-1, -1, -1, -1, -1, -1, -1); + } else { + return next.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); + } } @Override diff --git a/src/main/java/net/fabricmc/mappingio/adapter/RegularAsFlatMappingVisitor.java b/src/main/java/net/fabricmc/mappingio/adapter/RegularAsFlatMappingVisitor.java index 2c6408e8..ac2109a8 100644 --- a/src/main/java/net/fabricmc/mappingio/adapter/RegularAsFlatMappingVisitor.java +++ b/src/main/java/net/fabricmc/mappingio/adapter/RegularAsFlatMappingVisitor.java @@ -64,8 +64,8 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { - return next.visitContent(); + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { + return next.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); } @Override diff --git a/src/main/java/net/fabricmc/mappingio/format/AbstractMappingWriter.java b/src/main/java/net/fabricmc/mappingio/format/AbstractMappingWriter.java new file mode 100644 index 00000000..51c4f979 --- /dev/null +++ b/src/main/java/net/fabricmc/mappingio/format/AbstractMappingWriter.java @@ -0,0 +1,126 @@ +/* + * 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.Writer; +import java.util.List; + +import org.jetbrains.annotations.ApiStatus; + +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.ProgressListener.LogLevel; + +/** + * A MappingWriter which automatically: + * + */ +@ApiStatus.Internal +public abstract class AbstractMappingWriter implements MappingWriter { + public AbstractMappingWriter(MappingFormat format, Writer writer, ProgressListener progressListener, String taskTitle) { + this.format = format; + this.writer = writer; + this.progressListener = progressListener; + this.taskTitle = taskTitle; + } + + @Override + public void visitNamespaces(String srcNamespace, List dstNamespaces) throws IOException { + } + + @Override + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { + int totalWork = 0; + + if (progressListener.logLevel.allows(LogLevel.CLASSES)) { + if (metadataCount > 0) totalWork += metadataCount; + if (classCount > 0) totalWork += classCount; + } + + if (progressListener.logLevel.allows(LogLevel.MEMBERS)) { + if (fieldCount > 0) totalWork += fieldCount; + if (methodCount > 0) totalWork += methodCount; + } + + progressListener.forwarder.init(totalWork > 0 ? totalWork : -1, taskTitle); + progressListenerInitialized = true; + return true; + } + + @Override + public void visitMetadata(String key, String value) throws IOException { + if (!progressListenerInitialized) return; + + progressListener.forwarder.startStep(LogLevel.CLASSES, "Writing metadata"); + } + + @Override + public boolean visitClass(String srcName) throws IOException { + progressListener.forwarder.startStep(LogLevel.CLASSES, "Writing class: " + srcName); + return true; + } + + @Override + public boolean visitField(String srcName, String srcDesc) throws IOException { + progressListener.forwarder.startStep(LogLevel.MEMBERS, "Writing field: " + srcName); + return true; + } + + @Override + public boolean visitMethod(String srcName, String srcDesc) throws IOException { + progressListener.forwarder.startStep(LogLevel.MEMBERS, "Writing method: " + srcName); + return true; + } + + @Override + public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) throws IOException { + return format.supportsArgs; + } + + @Override + public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, String srcName) throws IOException { + return format.supportsLocals; + } + + @Override + public void visitComment(MappedElementKind targetKind, String comment) throws IOException { + } + + @Override + public boolean visitEnd() throws IOException { + progressListener.forwarder.finish(); + return true; + } + + @Override + public void close() throws IOException { + writer.close(); + } + + protected final MappingFormat format; + protected final ProgressListener progressListener; + protected final String taskTitle; + protected Writer writer; + private boolean progressListenerInitialized; +} diff --git a/src/main/java/net/fabricmc/mappingio/format/MappingReaderProgressListenerHelper.java b/src/main/java/net/fabricmc/mappingio/format/MappingReaderProgressListenerHelper.java new file mode 100644 index 00000000..87a1e1b1 --- /dev/null +++ b/src/main/java/net/fabricmc/mappingio/format/MappingReaderProgressListenerHelper.java @@ -0,0 +1,66 @@ +/* + * 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 org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.ProgressListener.LogLevel; + +/** + * Helper for MappingReaders, which takes care of forwarding steps to the passed progress listener. + */ +@ApiStatus.Internal +public class MappingReaderProgressListenerHelper { + public MappingReaderProgressListenerHelper(ProgressListener progressListener) { + this.progressListener = progressListener; + } + + public void init(int totalWork, String taskTitle) { + progressListener.forwarder.init(-1, taskTitle); + progressListenerInitialized = true; + } + + public void readFile(@Nullable String name) { + progressListener.forwarder.startStep(LogLevel.FILES, "Reading file" + (name == null ? "" : ": " + name)); + } + + public void readMetadata() { + if (!progressListenerInitialized) return; + progressListener.forwarder.startStep(LogLevel.CLASSES, "Reading metadata"); + } + + public void readClass(@Nullable String name) { + progressListener.forwarder.startStep(LogLevel.CLASSES, "Reading class" + (name == null ? "" : ": " + name)); + } + + public void readField(@Nullable String name) { + progressListener.forwarder.startStep(LogLevel.MEMBERS, "Reading field" + (name == null ? "" : ": " + name)); + } + + public void readMethod(@Nullable String name) { + progressListener.forwarder.startStep(LogLevel.MEMBERS, "Reading method" + (name == null ? "" : ": " + name)); + } + + public void finish() { + progressListener.forwarder.finish(); + } + + protected final ProgressListener progressListener; + protected boolean progressListenerInitialized; +} 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 637397ed..0b1484fa 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirReader.java @@ -17,32 +17,58 @@ package net.fabricmc.mappingio.format.enigma; import java.io.IOException; -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.List; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.ProgressListener.LogLevel; public final class EnigmaDirReader { - public static void read(Path dir, MappingVisitor visitor) throws IOException { - read(dir, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor); + public static void read(Path dir, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(dir, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor, progressListener); } - public static void read(Path dir, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { - Files.walkFileTree(dir, new SimpleFileVisitor() { + public static void read(Path dir, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + ProgressListener delegatingProgressListener = new ProgressListener(progressListener.logLevel) { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.getFileName().toString().endsWith("." + DIR_FILE_EXT)) { - EnigmaFileReader.read(Files.newBufferedReader(file), sourceNs, targetNs, visitor); - } + public void init(int totalWork, String title) { + } - return FileVisitResult.CONTINUE; + @Override + public void startStep(LogLevel logLevel, @Nullable String message) { + progressListener.forwarder.updateMessage(logLevel, message); } - }); + + @Override + public void updateMessage(LogLevel logLevel, @Nullable String message) { + progressListener.forwarder.updateMessage(logLevel, message); + } + + @Override + public void finish() { + } + }; + + List files = Files.walk(dir) + .filter(file -> !Files.isDirectory(file)) + .filter(file -> file.toString().endsWith("." + DIR_FILE_EXT)) + .collect(Collectors.toList()); + + progressListener.forwarder.init(files.size(), "Reading Enigma directory"); + + for (Path file : files) { + progressListener.forwarder.startStep(LogLevel.FILES, dir.relativize(file).toString()); + EnigmaFileReader.read(Files.newBufferedReader(file), sourceNs, targetNs, visitor, delegatingProgressListener); + } + visitor.visitEnd(); + progressListener.forwarder.finish(); } static final String DIR_FILE_EXT = "mapping"; // non-plural form unlike ENIGMA_FILE diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java index ea5332e1..1b550170 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaDirWriter.java @@ -29,10 +29,12 @@ import java.util.List; import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.MappingFormat; public final class EnigmaDirWriter extends EnigmaWriterBase { - public EnigmaDirWriter(Path dir, boolean deleteExistingFiles) throws IOException { - super(null); + public EnigmaDirWriter(Path dir, boolean deleteExistingFiles, ProgressListener progressListener) throws IOException { + super(MappingFormat.ENIGMA_DIR, null, progressListener, "Writing Enigma directory"); this.dir = dir.toAbsolutePath().normalize(); if (deleteExistingFiles && Files.exists(dir)) { 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 641ccdda..757f1a51 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileReader.java @@ -25,20 +25,25 @@ import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; public final class EnigmaFileReader { - 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, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(reader, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor, progressListener); } - public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { - read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor); + public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor, progressListener); } - public static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + public static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + MappingReaderProgressListenerHelper progressHelper = new MappingReaderProgressListenerHelper(progressListener); + progressHelper.init(-1, "Reading Enigma file"); + Set flags = visitor.getFlags(); MappingVisitor parentVisitor = null; @@ -47,19 +52,17 @@ public static void read(ColumnFileReader reader, String sourceNs, String targetN visitor = new MemoryMappingTree(); } - boolean visitHeader = visitor.visitHeader(); - - if (visitHeader) { + if (visitor.visitHeader()) { visitor.visitNamespaces(sourceNs, Collections.singletonList(targetNs)); } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { StringBuilder commentSb = new StringBuilder(200); final MappingVisitor finalVisitor = visitor; do { if (reader.nextCol("CLASS")) { // class: CLASS [] - readClass(reader, 0, null, null, commentSb, finalVisitor); + readClass(reader, 0, null, null, commentSb, finalVisitor, progressHelper); } } while (reader.nextLine(0)); } @@ -69,9 +72,12 @@ public static void read(ColumnFileReader reader, String sourceNs, String targetN if (parentVisitor != null) { ((MappingTree) visitor).accept(parentVisitor); } + + progressHelper.finish(); } - private static void readClass(ColumnFileReader reader, int indent, String outerSrcClass, String outerDstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private static void readClass(ColumnFileReader reader, int indent, String outerSrcClass, String outerDstClass, + StringBuilder commentSb, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { String srcInnerName = reader.nextCol(); if (srcInnerName == null || srcInnerName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber()); @@ -93,10 +99,12 @@ private static void readClass(ColumnFileReader reader, int indent, String outerS dstName = String.format("%s$%s", outerDstClass, dstInnerName); } - readClassBody(reader, indent, srcName, dstName, commentSb, visitor); + progressHelper.readClass(srcName); + readClassBody(reader, indent, srcName, dstName, commentSb, visitor, progressHelper); } - private static void readClassBody(ColumnFileReader reader, int indent, String srcClass, String dstClass, StringBuilder commentSb, MappingVisitor visitor) throws IOException { + private static void readClassBody(ColumnFileReader reader, int indent, String srcClass, String dstClass, + StringBuilder commentSb, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { boolean visited = false; int state = 0; // 0=invalid 1=visit -1=skip @@ -109,7 +117,7 @@ private static void readClassBody(ColumnFileReader reader, int indent, String sr visited = true; } - readClass(reader, indent + 1, srcClass, dstClass, commentSb, visitor); + readClass(reader, indent + 1, srcClass, dstClass, commentSb, visitor, progressHelper); state = 0; } else if (reader.nextCol("COMMENT")) { // comment: COMMENT readComment(reader, commentSb); @@ -136,10 +144,12 @@ private static void readClassBody(ColumnFileReader reader, int indent, String sr if (isMethod && visitor.visitMethod(srcName, srcDesc)) { if (dstName != null && !dstName.isEmpty()) visitor.visitDstName(MappedElementKind.METHOD, 0, dstName); - readMethod(reader, indent, commentSb, visitor); + progressHelper.readMethod(srcName); + readMethod(reader, indent, commentSb, visitor, progressHelper); } else if (!isMethod && visitor.visitField(srcName, srcDesc)) { if (dstName != null && !dstName.isEmpty()) visitor.visitDstName(MappedElementKind.FIELD, 0, dstName); - readElement(reader, MappedElementKind.FIELD, indent, commentSb, visitor); + progressHelper.readField(srcName); + readElement(reader, MappedElementKind.FIELD, indent, commentSb, visitor, progressHelper); } } } @@ -175,7 +185,8 @@ 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 static void readMethod(ColumnFileReader reader, int indent, StringBuilder commentSb, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; while (reader.nextLine(indent + 2)) { @@ -193,7 +204,7 @@ private static void readMethod(ColumnFileReader reader, int indent, StringBuilde if (dstName == null) throw new IOException("missing var-name-b column in line "+reader.getLineNumber()); if (!dstName.isEmpty()) visitor.visitDstName(MappedElementKind.METHOD_ARG, 0, dstName); - readElement(reader, MappedElementKind.METHOD_ARG, indent, commentSb, visitor); + readElement(reader, MappedElementKind.METHOD_ARG, indent, commentSb, visitor, progressHelper); } } } @@ -202,7 +213,8 @@ 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 static void readElement(ColumnFileReader reader, MappedElementKind kind, int indent, StringBuilder commentSb, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { if (!visitor.visitElementContent(kind)) return; while (reader.nextLine(indent + kind.level + 1)) { @@ -216,7 +228,6 @@ private static void readElement(ColumnFileReader reader, MappedElementKind kind, private static void readComment(ColumnFileReader reader, StringBuilder commentSb) throws IOException { if (commentSb.length() > 0) commentSb.append('\n'); - String comment = reader.nextCols(true); if (comment != null) { diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java index 4c285707..33b120d0 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaFileWriter.java @@ -20,10 +20,12 @@ import java.io.Writer; import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.MappingFormat; public final class EnigmaFileWriter extends EnigmaWriterBase { - public EnigmaFileWriter(Writer writer) throws IOException { - super(writer); + public EnigmaFileWriter(Writer writer, ProgressListener progressListener) throws IOException { + super(MappingFormat.ENIGMA_FILE, writer, progressListener, "Writing Enigma file"); } @Override diff --git a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java index 11277530..9f718fc1 100644 --- a/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java +++ b/src/main/java/net/fabricmc/mappingio/format/enigma/EnigmaWriterBase.java @@ -19,21 +19,17 @@ import java.io.IOException; import java.io.Writer; import java.util.EnumSet; -import java.util.List; import java.util.Set; import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; -import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.AbstractMappingWriter; +import net.fabricmc.mappingio.format.MappingFormat; -abstract class EnigmaWriterBase implements MappingWriter { - EnigmaWriterBase(Writer writer) throws IOException { - this.writer = writer; - } - - @Override - public void close() throws IOException { - writer.close(); +abstract class EnigmaWriterBase extends AbstractMappingWriter { + EnigmaWriterBase(MappingFormat format, Writer writer, ProgressListener progressListener, String taskTitle) throws IOException { + super(format, writer, progressListener, taskTitle); } @Override @@ -41,39 +37,41 @@ public Set getFlags() { return flags; } - @Override - public void visitNamespaces(String srcNamespace, List dstNamespaces) { } - @Override public boolean visitClass(String srcName) throws IOException { + super.visitClass(srcName); srcClassName = srcName; return true; } @Override public boolean visitField(String srcName, String srcDesc) throws IOException { + super.visitField(srcName, srcDesc); + writeIndent(0); writer.write("FIELD "); writer.write(srcName); desc = srcDesc; - return true; } @Override public boolean visitMethod(String srcName, String srcDesc) throws IOException { + super.visitMethod(srcName, srcDesc); + writeIndent(0); writer.write("METHOD "); writer.write(srcName); desc = srcDesc; - return true; } @Override public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) throws IOException { + super.visitMethodArg(argPosition, lvIndex, srcName); + writeIndent(1); writer.write("ARG "); writer.write(Integer.toString(lvIndex)); @@ -81,15 +79,10 @@ public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) thro return true; } - @Override - public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, String srcName) { - return false; - } - @Override public boolean visitEnd() throws IOException { + super.visitEnd(); close(); - return true; } @@ -121,6 +114,7 @@ protected static int getNextOuterEnd(String name, int startPos) { @Override public void visitComment(MappedElementKind targetKind, String comment) throws IOException { + super.visitComment(targetKind, comment); int start = 0; int pos; @@ -213,9 +207,7 @@ protected void writeIndent(int extra) throws IOException { protected static final String toEscape = "\\\n\r\0\t"; protected static final String escaped = "\\nr0t"; - protected Writer writer; protected int indent; - protected String srcClassName; protected String currentClass; protected String lastWrittenClass = ""; 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 3f1189f2..759d1d8c 100644 --- a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileReader.java @@ -27,19 +27,24 @@ import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; public final class ProGuardFileReader { - 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, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(reader, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor, progressListener); } - public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { BufferedReader br = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); + MappingReaderProgressListenerHelper progressHelper = new MappingReaderProgressListenerHelper(progressListener); - read(br, sourceNs, targetNs, visitor); + read(br, sourceNs, targetNs, visitor, progressHelper); } - private static void read(BufferedReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + private static void read(BufferedReader reader, String sourceNs, String targetNs, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { + progressHelper.init(-1, "Reading Proguard file"); CharArrayReader parentReader = null; if (visitor.getFlags().contains(MappingFlag.NEEDS_MULTIPLE_PASSES)) { @@ -66,7 +71,7 @@ private static void read(BufferedReader reader, String sourceNs, String targetNs visitor.visitNamespaces(sourceNs, Collections.singletonList(targetNs)); } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { if (tmp == null) tmp = new StringBuilder(); String line; @@ -83,6 +88,7 @@ private static void read(BufferedReader reader, String sourceNs, String targetNs if (pos + 4 + 1 >= line.length()) throw new IOException("invalid proguard line (empty dst class): "+line); String name = line.substring(0, pos).replace('.', '/'); + progressHelper.readClass(name); visitClass = visitor.visitClass(name); if (visitClass) { @@ -102,6 +108,7 @@ private static void read(BufferedReader reader, String sourceNs, String targetNs if (parts[1].indexOf('(') < 0) { // field: -> String name = parts[1]; String desc = pgTypeToAsm(parts[0], tmp); + progressHelper.readField(name); if (visitor.visitField(name, desc)) { String mappedName = parts[3]; @@ -134,6 +141,7 @@ private static void read(BufferedReader reader, String sourceNs, String targetNs String name = part1.substring(0, pos); String argDesc = part1.substring(pos, pos3 + 1); String desc = pgDescToAsm(argDesc, retType, tmp); + progressHelper.readMethod(name); if (visitor.visitMethod(name, desc)) { String mappedName = parts[3]; @@ -155,6 +163,8 @@ private static void read(BufferedReader reader, String sourceNs, String targetNs reader = new BufferedReader(parentReader); } } + + progressHelper.finish(); } private static String pgDescToAsm(String pgArgDesc, String pgRetType, StringBuilder tmp) { diff --git a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java index f41d4450..1ac5e77b 100644 --- a/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/proguard/ProGuardFileWriter.java @@ -24,7 +24,9 @@ import org.objectweb.asm.Type; import net.fabricmc.mappingio.MappedElementKind; -import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.AbstractMappingWriter; +import net.fabricmc.mappingio.format.MappingFormat; /** * A mapping writer for the ProGuard mapping format. @@ -34,8 +36,7 @@ * * @see Official format documentation */ -public final class ProGuardFileWriter implements MappingWriter { - private final Writer writer; +public final class ProGuardFileWriter extends AbstractMappingWriter { private int dstNamespace = -1; private final String dstNamespaceString; @@ -45,8 +46,8 @@ public final class ProGuardFileWriter implements MappingWriter { * * @param writer the writer where the mappings will be written */ - public ProGuardFileWriter(Writer writer) { - this(writer, 0); + public ProGuardFileWriter(Writer writer, ProgressListener progressListener) { + this(writer, 0, progressListener); } /** @@ -55,7 +56,9 @@ public ProGuardFileWriter(Writer writer) { * @param writer the writer where the mappings will be written * @param dstNamespace the namespace index to write as the destination namespace, must be at least 0 */ - public ProGuardFileWriter(Writer writer, int dstNamespace) { + public ProGuardFileWriter(Writer writer, int dstNamespace, ProgressListener progressListener) { + super(MappingFormat.PROGUARD_FILE, writer, progressListener, "Writing Proguard file"); + this.writer = Objects.requireNonNull(writer, "writer cannot be null"); this.dstNamespace = dstNamespace; this.dstNamespaceString = null; @@ -71,23 +74,17 @@ public ProGuardFileWriter(Writer writer, int dstNamespace) { * @param writer the writer where the mappings will be written * @param dstNamespace the namespace name to write as the destination namespace */ - public ProGuardFileWriter(Writer writer, String dstNamespace) { + public ProGuardFileWriter(Writer writer, String dstNamespace, ProgressListener progressListener) { + super(MappingFormat.PROGUARD_FILE, writer, progressListener, "Writing Proguard file"); + this.writer = Objects.requireNonNull(writer, "writer cannot be null"); this.dstNamespaceString = Objects.requireNonNull(dstNamespace, "namespace cannot be null"); } - /** - * Closes the internal {@link Writer}. - * - * @throws IOException if an IO error occurs - */ - @Override - public void close() throws IOException { - writer.close(); - } - @Override public void visitNamespaces(String srcNamespace, List dstNamespaces) throws IOException { + super.visitNamespaces(srcNamespace, dstNamespaces); + if (dstNamespaceString != null) { dstNamespace = dstNamespaces.indexOf(dstNamespaceString); @@ -103,6 +100,7 @@ public void visitNamespaces(String srcNamespace, List dstNamespaces) thr @Override public boolean visitClass(String srcName) throws IOException { + super.visitClass(srcName); writer.write(toJavaClassName(srcName)); writeArrow(); return true; @@ -110,16 +108,21 @@ public boolean visitClass(String srcName) throws IOException { @Override public boolean visitField(String srcName, String srcDesc) throws IOException { + super.visitField(srcName, srcDesc); + writeIndent(); writer.write(toJavaType(srcDesc)); writer.write(' '); writer.write(srcName); writeArrow(); + return true; } @Override public boolean visitMethod(String srcName, String srcDesc) throws IOException { + super.visitMethod(srcName, srcDesc); + Type type = Type.getMethodType(srcDesc); writeIndent(); writer.write(toJavaType(type.getReturnType().getDescriptor())); @@ -141,18 +144,6 @@ public boolean visitMethod(String srcName, String srcDesc) throws IOException { return true; } - @Override - public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) throws IOException { - // ignored - return false; - } - - @Override - public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, String srcName) throws IOException { - // ignored - return false; - } - @Override public void visitDstName(MappedElementKind targetKind, int namespace, String name) throws IOException { if (this.dstNamespace != namespace) { @@ -169,11 +160,6 @@ public void visitDstName(MappedElementKind targetKind, int namespace, String nam writer.write('\n'); } - @Override - public void visitComment(MappedElementKind targetKind, String comment) throws IOException { - // ignored - } - private void writeArrow() throws IOException { writer.write(" -> "); } 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 1bc21d56..822dcf05 100644 --- a/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/srg/SrgFileReader.java @@ -25,20 +25,24 @@ import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; public final class SrgFileReader { - 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, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(reader, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor, progressListener); } - public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { - read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor); + public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor, new MappingReaderProgressListenerHelper(progressListener)); } - private static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + private static void read(ColumnFileReader reader, String sourceNs, String targetNs, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { + progressHelper.init(-1, "Reading SRG file"); Set flags = visitor.getFlags(); MappingVisitor parentVisitor = null; @@ -56,7 +60,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target visitor.visitNamespaces(sourceNs, Collections.singletonList(targetNs)); } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { String lastClass = null; boolean visitLastClass = false; @@ -66,6 +70,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target if (reader.nextCol("CL:")) { // class: CL: String srcName = reader.nextCol(); if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber()); + progressHelper.readClass(srcName); if (!srcName.equals(lastClass)) { lastClass = srcName; @@ -116,6 +121,12 @@ private static void read(ColumnFileReader reader, String sourceNs, String target if (visitLastClass) { String srcName = src.substring(srcSepPos + 1); + if (isMethod) { + progressHelper.readMethod(srcName); + } else { + progressHelper.readField(srcName); + } + if (isMethod && visitor.visitMethod(srcName, srcDesc) || !isMethod && visitor.visitField(srcName, srcDesc)) { MappedElementKind kind = isMethod ? MappedElementKind.METHOD : MappedElementKind.FIELD; @@ -135,5 +146,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target if (parentVisitor != null) { ((MappingTree) visitor).accept(parentVisitor); } + + progressHelper.finish(); } } 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 18acbd8c..9041b7d5 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileReader.java @@ -25,7 +25,9 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -49,15 +51,16 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce return ret; } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { - read(new ColumnFileReader(reader, '\t'), visitor); + public static void read(Reader reader, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(new ColumnFileReader(reader, '\t'), visitor, new MappingReaderProgressListenerHelper(progressListener)); } - private static void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { + private static void read(ColumnFileReader reader, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { if (!reader.nextCol("v1")) { // magic/version throw new IOException("invalid/unsupported tiny file: no tiny 1 header"); } + progressHelper.init(-1, "Reading Tiny v1 file"); String srcNamespace = reader.nextCol(); List dstNamespaces = new ArrayList<>(); String dstNamespace; @@ -84,7 +87,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws visitor.visitNamespaces(srcNamespace, dstNamespaces); } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { String lastClass = null; boolean lastClassDstNamed = false;; boolean visitLastClass = false; @@ -99,6 +102,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws if (!lastClassDstNamed || !srcName.equals(lastClass)) { lastClass = srcName; lastClassDstNamed = true; + progressHelper.readClass(srcName); visitLastClass = visitor.visitClass(srcName); if (visitLastClass) { @@ -113,6 +117,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws if (!srcOwner.equals(lastClass)) { lastClass = srcOwner; lastClassDstNamed = false; + progressHelper.readClass(srcOwner); visitLastClass = visitor.visitClass(srcOwner) && visitor.visitElementContent(MappedElementKind.CLASS); } @@ -122,6 +127,12 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws String srcName = reader.nextCol(); if (srcName == null || srcName.isEmpty()) throw new IOException("missing name-a in line "+reader.getLineNumber()); + if (isMethod) { + progressHelper.readMethod(srcName); + } else { + progressHelper.readField(srcName); + } + if (isMethod && visitor.visitMethod(srcName, srcDesc) || !isMethod && visitor.visitField(srcName, srcDesc)) { MappedElementKind kind = isMethod ? MappedElementKind.METHOD : MappedElementKind.FIELD; @@ -151,6 +162,7 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws } if (property != null) { + progressHelper.readMetadata(); visitor.visitMetadata(property, parts[1]); } } @@ -166,6 +178,8 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws if (parentVisitor != null) { ((MappingTree) visitor).accept(parentVisitor); } + + progressHelper.finish(); } private static void readDstNames(ColumnFileReader reader, MappedElementKind subjectKind, int dstNsCount, MappingVisitor visitor) throws IOException { 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..8f232296 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny1FileWriter.java @@ -25,16 +25,13 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; -import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.AbstractMappingWriter; +import net.fabricmc.mappingio.format.MappingFormat; -public final class Tiny1FileWriter implements MappingWriter { - public Tiny1FileWriter(Writer writer) { - this.writer = writer; - } - - @Override - public void close() throws IOException { - writer.close(); +public final class Tiny1FileWriter extends AbstractMappingWriter { + public Tiny1FileWriter(Writer writer, ProgressListener progressListener) { + super(MappingFormat.TINY_FILE, writer, progressListener, "Writing Tiny v1 file"); } @Override @@ -44,6 +41,7 @@ public Set getFlags() { @Override public void visitNamespaces(String srcNamespace, List dstNamespaces) throws IOException { + super.visitNamespaces(srcNamespace, dstNamespaces); dstNames = new String[dstNamespaces.size()]; write("v1\t"); @@ -59,6 +57,8 @@ public void visitNamespaces(String srcNamespace, List dstNamespaces) thr @Override public void visitMetadata(String key, String value) throws IOException { + super.visitMetadata(key, value); + switch (key) { case Tiny1FileReader.nextIntermediaryClassProperty: case Tiny1FileReader.nextIntermediaryFieldProperty: @@ -87,13 +87,15 @@ public void visitMetadata(String key, String value) throws IOException { @Override public boolean visitClass(String srcName) throws IOException { + super.visitClass(srcName); classSrcName = srcName; - return true; } @Override public boolean visitField(String srcName, String srcDesc) throws IOException { + super.visitField(srcName, srcDesc); + memberSrcName = srcName; memberSrcDesc = srcDesc; @@ -102,22 +104,14 @@ public boolean visitField(String srcName, String srcDesc) throws IOException { @Override public boolean visitMethod(String srcName, String srcDesc) throws IOException { + super.visitMethod(srcName, srcDesc); + memberSrcName = srcName; memberSrcDesc = srcDesc; return true; } - @Override - public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) throws IOException { - return false; // not supported, skip - } - - @Override - public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, String srcName) throws IOException { - return false; // not supported, skip - } - @Override public void visitDstName(MappedElementKind targetKind, int namespace, String name) { dstNames[namespace] = name; @@ -173,11 +167,6 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept return targetKind == MappedElementKind.CLASS; // only members are supported, skip anything but class contents } - @Override - public void visitComment(MappedElementKind targetKind, String comment) throws IOException { - // not supported, skip - } - private void write(String str) throws IOException { writer.write(str); } @@ -192,7 +181,6 @@ private void writeTab() throws IOException { private static final Set flags = EnumSet.of(MappingFlag.NEEDS_SRC_FIELD_DESC, MappingFlag.NEEDS_SRC_METHOD_DESC); - private final Writer writer; private String classSrcName; private String memberSrcName; private String memberSrcDesc; 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 db88a3c7..cb128cd9 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileReader.java @@ -24,7 +24,9 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; public final class Tiny2FileReader { public static List getNamespaces(Reader reader) throws IOException { @@ -48,17 +50,18 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce return ret; } - public static void read(Reader reader, MappingVisitor visitor) throws IOException { - read(new ColumnFileReader(reader, '\t'), visitor); + public static void read(Reader reader, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(new ColumnFileReader(reader, '\t'), visitor, new MappingReaderProgressListenerHelper(progressListener)); } - private static void read(ColumnFileReader reader, MappingVisitor visitor) throws IOException { + private static void read(ColumnFileReader reader, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { if (!reader.nextCol("tiny") // magic || reader.nextIntCol() != 2 // major version || reader.nextIntCol() < 0) { // minor version throw new IOException("invalid/unsupported tiny file: no tiny 2 header"); } + progressHelper.init(-1, "Reading Tiny v2 file"); String srcNamespace = reader.nextCol(); List dstNamespaces = new ArrayList<>(); String dstNamespace; @@ -98,19 +101,21 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws escapeNames = true; } + progressHelper.readMetadata(); visitor.visitMetadata(key, value); } } } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { while (reader.nextLine(0)) { if (reader.nextCol("c")) { // class: c ... String srcName = reader.nextCol(escapeNames); if (srcName == null || srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber()); + progressHelper.readClass(srcName); if (visitor.visitClass(srcName)) { - readClass(reader, dstNsCount, escapeNames, visitor); + readClass(reader, dstNsCount, escapeNames, visitor, progressHelper); } } } @@ -121,9 +126,12 @@ private static void read(ColumnFileReader reader, MappingVisitor visitor) throws reader.reset(); firstIteration = false; } + + progressHelper.finish(); } - private static void readClass(ColumnFileReader reader, int dstNsCount, boolean escapeNames, MappingVisitor visitor) throws IOException { + private static void readClass(ColumnFileReader reader, int dstNsCount, boolean escapeNames, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { readDstNames(reader, MappedElementKind.CLASS, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(MappedElementKind.CLASS)) return; @@ -133,18 +141,20 @@ private static void readClass(ColumnFileReader reader, int dstNsCount, boolean e if (srcDesc == null || srcDesc.isEmpty()) throw new IOException("missing field-desc-a in line "+reader.getLineNumber()); String srcName = reader.nextCol(escapeNames); if (srcName == null || srcName.isEmpty()) throw new IOException("missing field-name-a in line "+reader.getLineNumber()); + progressHelper.readField(srcName); if (visitor.visitField(srcName, srcDesc)) { - readElement(reader, MappedElementKind.FIELD, dstNsCount, escapeNames, visitor); + readElement(reader, MappedElementKind.FIELD, dstNsCount, escapeNames, visitor, progressHelper); } } else if (reader.nextCol("m")) { // method: m ... String srcDesc = reader.nextCol(escapeNames); if (srcDesc == null || srcDesc.isEmpty()) throw new IOException("missing method-desc-a in line "+reader.getLineNumber()); String srcName = reader.nextCol(escapeNames); if (srcName == null || srcName.isEmpty()) throw new IOException("missing method-name-a in line "+reader.getLineNumber()); + progressHelper.readMethod(srcName); if (visitor.visitMethod(srcName, srcDesc)) { - readMethod(reader, dstNsCount, escapeNames, visitor); + readMethod(reader, dstNsCount, escapeNames, visitor, progressHelper); } } else if (reader.nextCol("c")) { // comment: c readComment(reader, MappedElementKind.CLASS, visitor); @@ -152,7 +162,8 @@ 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 static void readMethod(ColumnFileReader reader, int dstNsCount, boolean escapeNames, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { readDstNames(reader, MappedElementKind.METHOD, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; @@ -165,7 +176,7 @@ private static void readMethod(ColumnFileReader reader, int dstNsCount, boolean if (srcName.isEmpty()) srcName = null; if (visitor.visitMethodArg(-1, lvIndex, srcName)) { - readElement(reader, MappedElementKind.METHOD_ARG, dstNsCount, escapeNames, visitor); + readElement(reader, MappedElementKind.METHOD_ARG, dstNsCount, escapeNames, visitor, progressHelper); } } else if (reader.nextCol("v")) { // method variable: v ... int lvIndex = reader.nextIntCol(); @@ -178,7 +189,7 @@ private static void readMethod(ColumnFileReader reader, int dstNsCount, boolean if (srcName.isEmpty()) srcName = null; if (visitor.visitMethodVar(lvtRowIndex, lvIndex, startOpIdx, -1, srcName)) { - readElement(reader, MappedElementKind.METHOD_VAR, dstNsCount, escapeNames, visitor); + readElement(reader, MappedElementKind.METHOD_VAR, dstNsCount, escapeNames, visitor, progressHelper); } } else if (reader.nextCol("c")) { // comment: c readComment(reader, MappedElementKind.METHOD, visitor); @@ -186,7 +197,8 @@ 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 static void readElement(ColumnFileReader reader, MappedElementKind kind, int dstNsCount, + boolean escapeNames, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { readDstNames(reader, kind, dstNsCount, escapeNames, visitor); if (!visitor.visitElementContent(kind)) return; diff --git a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java index aee1bdc0..584bb005 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java +++ b/src/main/java/net/fabricmc/mappingio/format/tiny/Tiny2FileWriter.java @@ -25,19 +25,16 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.MappingFlag; -import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.ProgressListener; +import net.fabricmc.mappingio.format.AbstractMappingWriter; +import net.fabricmc.mappingio.format.MappingFormat; -public final class Tiny2FileWriter implements MappingWriter { - public Tiny2FileWriter(Writer writer, boolean escapeNames) { - this.writer = writer; +public final class Tiny2FileWriter extends AbstractMappingWriter { + public Tiny2FileWriter(Writer writer, boolean escapeNames, ProgressListener progressListener) { + super(MappingFormat.TINY_2_FILE, writer, progressListener, "Writing Tiny v2 file"); this.escapeNames = escapeNames; } - @Override - public void close() throws IOException { - writer.close(); - } - @Override public Set getFlags() { return flags; @@ -45,6 +42,7 @@ public Set getFlags() { @Override public void visitNamespaces(String srcNamespace, List dstNamespaces) throws IOException { + super.visitNamespaces(srcNamespace, dstNamespaces); dstNames = new String[dstNamespaces.size()]; write("tiny\t2\t0\t"); @@ -60,6 +58,8 @@ public void visitNamespaces(String srcNamespace, List dstNamespaces) thr @Override public void visitMetadata(String key, String value) throws IOException { + super.visitMetadata(key, value); + if (key.equals(Tiny2Util.escapedNamesProperty)) { escapeNames = true; wroteEscapedNamesProperty = true; @@ -77,7 +77,9 @@ public void visitMetadata(String key, String value) throws IOException { } @Override - public boolean visitContent() throws IOException { + public boolean visitContent(int classCount, int fieldCount, int methodCount, int methodArgCount, int methodVarCount, int commentCount, int metadataCount) throws IOException { + super.visitContent(classCount, fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadataCount); + if (escapeNames && !wroteEscapedNamesProperty) { write("\t"); write(Tiny2Util.escapedNamesProperty); @@ -89,6 +91,7 @@ public boolean visitContent() throws IOException { @Override public boolean visitClass(String srcName) throws IOException { + super.visitClass(srcName); write("c\t"); writeName(srcName); @@ -97,6 +100,7 @@ public boolean visitClass(String srcName) throws IOException { @Override public boolean visitField(String srcName, String srcDesc) throws IOException { + super.visitField(srcName, srcDesc); write("\tf\t"); writeName(srcDesc); writeTab(); @@ -107,6 +111,7 @@ public boolean visitField(String srcName, String srcDesc) throws IOException { @Override public boolean visitMethod(String srcName, String srcDesc) throws IOException { + super.visitMethod(srcName, srcDesc); write("\tm\t"); writeName(srcDesc); writeTab(); @@ -117,6 +122,7 @@ public boolean visitMethod(String srcName, String srcDesc) throws IOException { @Override public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) throws IOException { + super.visitMethodArg(argPosition, lvIndex, srcName); write("\t\tp\t"); write(lvIndex); writeTab(); @@ -127,6 +133,7 @@ public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) thro @Override public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int endOpIdx, String srcName) throws IOException { + super.visitMethodVar(lvtRowIndex, lvIndex, startOpIdx, endOpIdx, srcName); write("\t\tv\t"); write(lvIndex); writeTab(); @@ -152,7 +159,6 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept } writeLn(); - Arrays.fill(dstNames, null); return true; @@ -160,6 +166,7 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept @Override public void visitComment(MappedElementKind targetKind, String comment) throws IOException { + super.visitComment(targetKind, comment); writeTabs(targetKind.level); write("\tc\t"); writeEscaped(comment); @@ -202,7 +209,6 @@ private void writeTabs(int count) throws IOException { private static final Set flags = EnumSet.of(MappingFlag.NEEDS_HEADER_METADATA, MappingFlag.NEEDS_UNIQUENESS, MappingFlag.NEEDS_SRC_FIELD_DESC, MappingFlag.NEEDS_SRC_METHOD_DESC); - private final Writer writer; private boolean escapeNames; private boolean wroteEscapedNamesProperty; private String[] dstNames; diff --git a/src/main/java/net/fabricmc/mappingio/format/tsrg/TsrgFileReader.java b/src/main/java/net/fabricmc/mappingio/format/tsrg/TsrgFileReader.java index 0c3b621d..9eb9376c 100644 --- a/src/main/java/net/fabricmc/mappingio/format/tsrg/TsrgFileReader.java +++ b/src/main/java/net/fabricmc/mappingio/format/tsrg/TsrgFileReader.java @@ -27,7 +27,9 @@ import net.fabricmc.mappingio.MappingFlag; import net.fabricmc.mappingio.MappingUtil; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.ProgressListener; import net.fabricmc.mappingio.format.ColumnFileReader; +import net.fabricmc.mappingio.format.MappingReaderProgressListenerHelper; public final class TsrgFileReader { public static List getNamespaces(Reader reader) throws IOException { @@ -49,20 +51,22 @@ private static List getNamespaces(ColumnFileReader reader) throws IOExce } } - 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, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(reader, MappingUtil.NS_SOURCE_FALLBACK, MappingUtil.NS_TARGET_FALLBACK, visitor, progressListener); } - public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { - read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor); + public static void read(Reader reader, String sourceNs, String targetNs, MappingVisitor visitor, ProgressListener progressListener) throws IOException { + read(new ColumnFileReader(reader, ' '), sourceNs, targetNs, visitor, new MappingReaderProgressListenerHelper(progressListener)); } - private static void read(ColumnFileReader reader, String sourceNs, String targetNs, MappingVisitor visitor) throws IOException { + private static void read(ColumnFileReader reader, String sourceNs, String targetNs, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { boolean isTsrg2 = reader.nextCol("tsrg2"); String srcNamespace; List dstNamespaces; if (isTsrg2) { + progressHelper.init(-1, "Reading TSRG2 file"); srcNamespace = reader.nextCol(); dstNamespaces = new ArrayList<>(); String dstNamespace; @@ -73,6 +77,7 @@ private static void read(ColumnFileReader reader, String sourceNs, String target reader.nextLine(0); } else { + progressHelper.init(-1, "Reading TSRG file"); srcNamespace = sourceNs; dstNamespaces = Collections.singletonList(targetNs); } @@ -92,16 +97,17 @@ private static void read(ColumnFileReader reader, String sourceNs, String target visitor.visitNamespaces(srcNamespace, dstNamespaces); } - if (visitor.visitContent()) { + if (visitor.visitContent(-1, -1, -1, -1, -1, -1, -1)) { do { if (reader.hasExtraIndents()) continue; String srcName = reader.nextCol(); if (srcName == null || srcName.endsWith("/")) continue; if (srcName.isEmpty()) throw new IOException("missing class-name-a in line "+reader.getLineNumber()); + progressHelper.readClass(srcName); if (visitor.visitClass(srcName)) { - readClass(reader, isTsrg2, dstNsCount, nameTmp, visitor); + readClass(reader, isTsrg2, dstNsCount, nameTmp, visitor, progressHelper); } } while (reader.nextLine(0)); } @@ -110,9 +116,12 @@ private static void read(ColumnFileReader reader, String sourceNs, String target reader.reset(); } + + progressHelper.finish(); } - private static void readClass(ColumnFileReader reader, boolean isTsrg2, int dstNsCount, List nameTmp, MappingVisitor visitor) throws IOException { + private static void readClass(ColumnFileReader reader, boolean isTsrg2, int dstNsCount, List nameTmp, + MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { readDstNames(reader, MappedElementKind.CLASS, 0, dstNsCount, visitor); if (!visitor.visitElementContent(MappedElementKind.CLASS)) return; @@ -126,10 +135,14 @@ private static void readClass(ColumnFileReader reader, boolean isTsrg2, int dstN if (arg == null) throw new IOException("missing desc/name-b in line "+reader.getLineNumber()); if (arg.startsWith("(")) { // method: ... + progressHelper.readMethod(srcName); + if (visitor.visitMethod(srcName, arg)) { - readMethod(reader, dstNsCount, visitor); + readMethod(reader, dstNsCount, visitor, progressHelper); } } else if (!isTsrg2) { // tsrg1 field, never has a desc: ... + progressHelper.readField(srcName); + if (visitor.visitField(srcName, null)) { if (!arg.isEmpty()) visitor.visitDstName(MappedElementKind.FIELD, 0, arg); readElement(reader, MappedElementKind.FIELD, 1, dstNsCount, visitor); @@ -175,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 static void readMethod(ColumnFileReader reader, int dstNsCount, MappingVisitor visitor, MappingReaderProgressListenerHelper progressHelper) throws IOException { readDstNames(reader, MappedElementKind.METHOD, 0, dstNsCount, visitor); if (!visitor.visitElementContent(MappedElementKind.METHOD)) return; diff --git a/src/main/java/net/fabricmc/mappingio/tree/MemoryMappingTree.java b/src/main/java/net/fabricmc/mappingio/tree/MemoryMappingTree.java index 20b3a9ac..d64efb8a 100644 --- a/src/main/java/net/fabricmc/mappingio/tree/MemoryMappingTree.java +++ b/src/main/java/net/fabricmc/mappingio/tree/MemoryMappingTree.java @@ -309,7 +309,7 @@ public void accept(MappingVisitor visitor, VisitOrder order) throws IOException } } - if (visitor.visitContent()) { + if (visitor.visitContent(classesBySrcName.size(), fieldCount, methodCount, methodArgCount, methodVarCount, commentCount, metadata.size())) { Set flags = visitor.getFlags(); boolean supplyFieldDstDescs = flags.contains(MappingFlag.NEEDS_DST_FIELD_DESC); boolean supplyMethodDstDescs = flags.contains(MappingFlag.NEEDS_DST_METHOD_DESC); @@ -429,6 +429,7 @@ public boolean visitField(String srcName, String srcDesc) { } else { field = new FieldEntry(currentClass, srcName, srcDesc); field = currentClass.addField(field); + fieldCount++; } } else if (srcDesc != null && field.srcDesc == null) { field.setSrcDesc(mapDesc(srcDesc, srcNsMap, SRC_NAMESPACE_ID)); // assumes the class mapping is already sufficiently present.. @@ -451,6 +452,7 @@ public boolean visitMethod(String srcName, String srcDesc) { } else { method = new MethodEntry(currentClass, srcName, srcDesc); method = currentClass.addMethod(method); + methodCount++; } } else if (srcDesc != null && (method.srcDesc == null || method.srcDesc.endsWith(")") && !srcDesc.endsWith(")"))) { method.setSrcDesc(mapDesc(srcDesc, srcNsMap, SRC_NAMESPACE_ID)); // assumes the class mapping is already sufficiently present.. @@ -501,6 +503,8 @@ private void addPendingMember(MemberEntry member) { } else { // copy remaining data field.copyFrom((FieldEntry) member, false); } + + fieldCount++; } else { MethodEntry method = member.getOwner().getMethod(name, desc); @@ -510,6 +514,8 @@ private void addPendingMember(MemberEntry member) { } else { // copy remaining data method.copyFrom((MethodEntry) member, false); } + + methodCount++; } } @@ -522,6 +528,7 @@ public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) { if (arg == null) { arg = new MethodArgEntry(currentMethod, argPosition, lvIndex, srcName); arg = currentMethod.addArg(arg); + methodArgCount++; } else { if (argPosition >= 0 && arg.argPosition < 0) arg.setArgPosition(argPosition); if (lvIndex >= 0 && arg.lvIndex < 0) arg.setLvIndex(lvIndex); @@ -546,6 +553,7 @@ public boolean visitMethodVar(int lvtRowIndex, int lvIndex, int startOpIdx, int if (var == null) { var = new MethodVarEntry(currentMethod, lvtRowIndex, lvIndex, startOpIdx, endOpIdx, srcName); var = currentMethod.addVar(var); + methodVarCount++; } else { if (lvtRowIndex >= 0 && var.lvtRowIndex < 0) var.setLvtRowIndex(lvtRowIndex); if (lvIndex >= 0 && startOpIdx >= 0 && (var.lvIndex < 0 || var.startOpIdx < 0)) var.setLvIndex(lvIndex, startOpIdx, endOpIdx); @@ -686,6 +694,13 @@ public void visitComment(MappedElementKind targetKind, String comment) { } if (entry == null) throw new UnsupportedOperationException("Tried to visit comment before owning target"); + + if (comment == null && entry.comment != null) { + commentCount--; + } else if (comment != null && entry.comment == null) { + commentCount++; + } + entry.setComment(comment); } @@ -1742,6 +1757,11 @@ public String toString() { private final List> metadata = new ArrayList<>(); private final Map classesBySrcName = new LinkedHashMap<>(); private Map[] classesByDstNames; + private int fieldCount; + private int methodCount; + private int methodArgCount; + private int methodVarCount; + private int commentCount; private HierarchyInfoProvider hierarchyInfo;