From 39e2e7d84f6099598938de7fd30c672664e371d4 Mon Sep 17 00:00:00 2001 From: joe Date: Sun, 28 Sep 2025 15:32:01 +0100 Subject: [PATCH] Expose visitors to API --- .../tinyremapper/AsmClassRemapper.java | 29 +++++++-- .../fabricmc/tinyremapper/TinyRemapper.java | 65 +++++++++++++++++++ 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java b/src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java index b06aa4d2..bd7080cf 100644 --- a/src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java +++ b/src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java @@ -167,7 +167,7 @@ protected void onVisit(VisitKind kind) { private boolean sourceNameVisited; private MethodNode methodNode; - private static class AsmFieldRemapper extends FieldRemapper { + static class AsmFieldRemapper extends FieldRemapper { AsmFieldRemapper(FieldVisitor fieldVisitor, AsmRemapper remapper) { super(fieldVisitor, remapper); } @@ -178,8 +178,29 @@ public AnnotationVisitor createAnnotationRemapper(String descriptor, AnnotationV } } - private static class AsmMethodRemapper extends MethodRemapper { + static class AsmMethodRemapper extends MethodRemapper { private final TinyRemapper tr; + AsmMethodRemapper(MethodVisitor methodVisitor, + AsmRemapper remapper, + String owner, + int access, + String name, + String desc, + boolean skipLocalMapping, + boolean renameInvalidLocals, + Pattern invalidLvNamePattern, + boolean inferNameFromSameLvIndex) { + this(methodVisitor, + remapper, + owner, + !skipLocalMapping || renameInvalidLocals ? new MethodNode(Opcodes.ASM9, access, name, desc, null, null) : null, + false, + skipLocalMapping, + renameInvalidLocals, + invalidLvNamePattern, + inferNameFromSameLvIndex); + } + AsmMethodRemapper(MethodVisitor methodVisitor, AsmRemapper remapper, String owner, @@ -699,7 +720,7 @@ private static boolean isJavaKeyword(String s) { private final boolean inferNameFromSameLvIndex; } - private static class AsmRecordComponentRemapper extends RecordComponentRemapper { + static class AsmRecordComponentRemapper extends RecordComponentRemapper { AsmRecordComponentRemapper(RecordComponentVisitor recordComponentVisitor, AsmRemapper remapper) { super(recordComponentVisitor, remapper); } @@ -714,7 +735,7 @@ public AnnotationVisitor createAnnotationRemapper(String descriptor, AnnotationV * Since sfPlayer want to infer the method descriptor when possible, we need to implement all remapping logic by * ourselves. */ - private static class AsmAnnotationRemapper extends AnnotationVisitor { + static class AsmAnnotationRemapper extends AnnotationVisitor { protected final String descriptor; protected final AsmRemapper remapper; diff --git a/src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java b/src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java index c9dedc84..998e4936 100644 --- a/src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java +++ b/src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java @@ -52,12 +52,14 @@ import java.util.stream.Collectors; import java.util.zip.ZipError; +import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.RecordComponentVisitor; import org.objectweb.asm.commons.Remapper; import org.objectweb.asm.util.CheckClassAdapter; @@ -1138,6 +1140,69 @@ private byte[] apply(final ClassInstance cls) { return writer.toByteArray(); } + /** + * Creates a class visitor which remaps the visited class before passing it to the downstream visitor. + * + *

This class visitor will only remap, any registered pre- and post-visitors will not be returned by + * this method! Since the class is only analyzed in isolation, package access fixes will also not be applied. + * + *

This method will use the default multi-release jar (MRJ) context, i.e. no context from classes in + * {@code META-INF/versions/*}. + * + * @param delegate The downstream visitor called with the remapped class. + * @return The remapping class visitor. + */ + public ClassVisitor createClassRemapperVisitor(ClassVisitor delegate) { + return new AsmClassRemapper(delegate, defaultState.remapper, rebuildSourceFilenames, + false, skipLocalMapping, renameInvalidLocals, invalidLvNamePattern, inferNameFromSameLvIndex); + } + + /** + * Creates a field visitor which remaps the visited field before passing it to the downstream visitor. + * + * @param delegate The downstream visitor called with the remapped field. + * @return The remapping field visitor. + */ + public FieldVisitor createFieldRemapperVisitor(FieldVisitor delegate) { + return new AsmClassRemapper.AsmFieldRemapper(delegate, defaultState.remapper); + } + + /** + * Creates a method visitor which remaps the visited method before passing it to the downstream visitor. + * + * @param delegate The downstream visitor called with the remapped method. + * @param owner The internal name of the class owning the method. + * @param access The access flags of the method. + * @param name The name of the method being visited. + * @param desc The descriptor of the method being visited. + * @return The remapping method visitor. + */ + public MethodVisitor createMethodRemapperVisitor(MethodVisitor delegate, String owner, int access, String name, String desc) { + return new AsmClassRemapper.AsmMethodRemapper(delegate, defaultState.remapper, owner, access, name, desc, + skipLocalMapping, renameInvalidLocals, invalidLvNamePattern, inferNameFromSameLvIndex); + } + + /** + * Creates a record component visitor which remaps the visited record component before passing it to the downstream visitor. + * + * @param delegate The downstream visitor called with the remapped record component. + * @return The remapping record component visitor. + */ + public RecordComponentVisitor createRecordComponentRemapperVisitor(RecordComponentVisitor delegate) { + return new AsmClassRemapper.AsmRecordComponentRemapper(delegate, defaultState.remapper); + } + + /** + * Creates an annotation visitor which remaps the visited annotation before passing it to the downstream visitor. + * + * @param delegate The downstream visitor that receives the remapped annotation. + * @param desc The descriptor of the annotation. + * @return The remapping annotation visitor. + */ + public AnnotationVisitor createAnnotationRemapperVisitor(AnnotationVisitor delegate, String desc) { + return new AsmClassRemapper.AsmAnnotationRemapper(desc, delegate, defaultState.remapper); + } + private byte[] fixClass(ClassInstance cls, byte[] data) { boolean makeClsPublic = classesToMakePublic.contains(cls); Set clsMembersToMakePublic = null;