diff --git a/build.gradle b/build.gradle index 7e68d615..edeb45e2 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,7 @@ dependencies { // tinyfile management implementation libs.fabric.tiny.remapper - implementation libs.fabric.access.widener + implementation libs.fabric.clazz.tweaker implementation libs.fabric.mapping.io implementation (libs.fabric.lorenz.tiny) { transitive = false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c1093217..bc51d2a7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ gson = "2.10.1" stitch = "0.6.2" tiny-remapper = "0.12.0" -access-widener = "2.1.0" +clazz-tweaker = "0.1.1" mapping-io = "0.7.1" lorenz-tiny = "4.0.2" mercury = "0.4.2" @@ -30,7 +30,7 @@ gson = { module = "com.google.code.gson:gson", version.ref = "gson" } fabric-stitch = { module = "net.fabricmc:stitch", version.ref = "stitch" } fabric-tiny-remapper = { module = "net.fabricmc:tiny-remapper", version.ref = "tiny-remapper" } -fabric-access-widener = { module = "net.fabricmc:access-widener", version.ref = "access-widener" } +fabric-clazz-tweaker = { module = "net.fabricmc:class-tweaker", version.ref = "clazz-tweaker" } fabric-mapping-io = { module = "net.fabricmc:mapping-io", version.ref = "mapping-io" } fabric-lorenz-tiny = { module = "net.fabricmc:lorenz-tiny", version.ref = "lorenz-tiny" } fabric-mercury = { module = "net.fabricmc:mercury", version.ref = "mercury" } diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerEntry.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerEntry.java index 802b7c85..a2bf7d94 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerEntry.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerEntry.java @@ -28,7 +28,7 @@ import java.io.IOException; import org.jetbrains.annotations.Nullable; -import net.fabricmc.accesswidener.AccessWidenerVisitor; +import net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor; import net.fabricmc.loom.util.LazyCloseable; import net.fabricmc.loom.util.fmj.ModEnvironment; import net.fabricmc.tinyremapper.TinyRemapper; @@ -44,5 +44,5 @@ public interface AccessWidenerEntry { String getSortKey(); - void read(AccessWidenerVisitor visitor, LazyCloseable remapper) throws IOException; + void read(ClassTweakerVisitor visitor, LazyCloseable remapper) throws IOException; } diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java index 212ef932..ef0f6ce6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java @@ -38,7 +38,7 @@ import javax.inject.Inject; import org.gradle.api.file.RegularFileProperty; import org.jetbrains.annotations.Nullable; -import net.fabricmc.accesswidener.AccessWidener; +import net.fabricmc.classtweaker.api.ClassTweaker; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.processor.MinecraftJarProcessor; import net.fabricmc.loom.api.processor.ProcessorContext; @@ -131,7 +131,7 @@ public class AccessWidenerJarProcessor implements MinecraftJarProcessor accessWideners = spec.accessWidenersForContext(context); - final var accessWidener = new AccessWidener(); + final var accessWidener = ClassTweaker.newInstance(); try (LazyCloseable remapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) { for (AccessWidenerEntry widener : accessWideners) { diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java index 0eb195af..7cd33b5e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java @@ -37,8 +37,7 @@ import org.objectweb.asm.ClassWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.fabricmc.accesswidener.AccessWidener; -import net.fabricmc.accesswidener.AccessWidenerClassVisitor; +import net.fabricmc.classtweaker.api.ClassTweaker; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.Pair; import net.fabricmc.loom.util.ZipUtils; @@ -46,9 +45,9 @@ import net.fabricmc.loom.util.ZipUtils; final class AccessWidenerTransformer { private static final Logger LOGGER = LoggerFactory.getLogger(AccessWidenerTransformer.class); - private final AccessWidener accessWidener; + private final ClassTweaker accessWidener; - AccessWidenerTransformer(AccessWidener accessWidener) { + AccessWidenerTransformer(ClassTweaker accessWidener) { this.accessWidener = accessWidener; } @@ -57,7 +56,14 @@ final class AccessWidenerTransformer { */ void apply(Path jarFile) { try { - ZipUtils.transform(jarFile, getTransformers(accessWidener.getTargets())); + Set targets = accessWidener.getTargets(); + int transformed = ZipUtils.transform(jarFile, getTransformers(targets)); + + LOGGER.debug("Applied access wideners to {} classes in {}", transformed, jarFile); + + if (targets.size() != transformed) { + LOGGER.debug("Access widener target count ({}) does not match transformed class count ({}).", targets.size(), transformed); + } } catch (IOException e) { throw new UncheckedIOException("Failed to apply access wideners to %s".formatted(jarFile), e); } @@ -65,17 +71,22 @@ final class AccessWidenerTransformer { private List>> getTransformers(Set classes) { return classes.stream() - .map(string -> new Pair<>(string.replaceAll("\\.", "/") + ".class", getTransformer(string))) + .map(string -> new Pair<>(string + ".class", getTransformer(string))) .collect(Collectors.toList()); } private ZipUtils.UnsafeUnaryOperator getTransformer(String className) { return input -> { ClassReader reader = new ClassReader(input); - ClassWriter writer = new ClassWriter(0); - ClassVisitor classVisitor = AccessWidenerClassVisitor.createClassVisitor(Constants.ASM_VERSION, writer, accessWidener); - LOGGER.debug("Applying access widener to " + className); + if (!reader.getClassName().equals(className)) { + throw new IllegalStateException("Class name mismatch: expected %s but transforming %s".formatted(className, reader.getClassName())); + } + + ClassWriter writer = new ClassWriter(0); + ClassVisitor classVisitor = accessWidener.createClassVisitor(Constants.ASM_VERSION, writer, null); + + LOGGER.debug("Applying access widener to {}", className); reader.accept(classVisitor, 0); return writer.toByteArray(); diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/LocalAccessWidenerEntry.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/LocalAccessWidenerEntry.java index c2aed2d6..24db25ea 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/LocalAccessWidenerEntry.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/LocalAccessWidenerEntry.java @@ -30,8 +30,8 @@ import java.nio.file.Path; import org.jetbrains.annotations.Nullable; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerVisitor; +import net.fabricmc.classtweaker.api.ClassTweakerReader; +import net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.LazyCloseable; import net.fabricmc.loom.util.fmj.ModEnvironment; @@ -43,9 +43,9 @@ public record LocalAccessWidenerEntry(Path path, String hash) implements AccessW } @Override - public void read(AccessWidenerVisitor visitor, LazyCloseable remapper) throws IOException { - var reader = new AccessWidenerReader(visitor); - reader.read(Files.readAllBytes(path)); + public void read(ClassTweakerVisitor visitor, LazyCloseable remapper) throws IOException { + var reader = ClassTweakerReader.create(visitor); + reader.read(Files.readAllBytes(path), null); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/ModAccessWidenerEntry.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/ModAccessWidenerEntry.java index 4731422c..32904c78 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/ModAccessWidenerEntry.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/ModAccessWidenerEntry.java @@ -32,10 +32,10 @@ import java.util.Map; import org.jetbrains.annotations.Nullable; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerRemapper; -import net.fabricmc.accesswidener.AccessWidenerVisitor; -import net.fabricmc.accesswidener.TransitiveOnlyFilter; +import net.fabricmc.classtweaker.api.ClassTweakerReader; +import net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor; +import net.fabricmc.classtweaker.visitors.ClassTweakerRemapperVisitor; +import net.fabricmc.classtweaker.visitors.TransitiveOnlyFilter; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.util.LazyCloseable; import net.fabricmc.loom.util.fmj.FabricModJson; @@ -67,26 +67,26 @@ public record ModAccessWidenerEntry(FabricModJson mod, String path, ModEnvironme } @Override - public void read(AccessWidenerVisitor visitor, LazyCloseable remapper) throws IOException { + public void read(ClassTweakerVisitor visitor, LazyCloseable remapper) throws IOException { if (transitiveOnly) { // Filter for only transitive rules visitor = new TransitiveOnlyFilter(visitor); } final byte[] data = readRaw(); - final AccessWidenerReader.Header header = AccessWidenerReader.readHeader(data); + final ClassTweakerReader.Header header = ClassTweakerReader.readHeader(data); if (!header.getNamespace().equals(MappingsNamespace.NAMED.toString())) { // Remap the AW if needed visitor = getRemapper(visitor, remapper.get()); } - var reader = new AccessWidenerReader(visitor); - reader.read(data); + var reader = ClassTweakerReader.create(visitor); + reader.read(data, mod.getId()); } - private static AccessWidenerRemapper getRemapper(AccessWidenerVisitor visitor, TinyRemapper tinyRemapper) { - return new AccessWidenerRemapper( + private static ClassTweakerRemapperVisitor getRemapper(ClassTweakerVisitor visitor, TinyRemapper tinyRemapper) { + return new ClassTweakerRemapperVisitor( visitor, tinyRemapper.getEnvironment().getRemapper(), MappingsNamespace.INTERMEDIARY.toString(), diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java index e7197b7b..1df5cbc4 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java @@ -31,8 +31,8 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerVisitor; +import net.fabricmc.classtweaker.api.visitor.AccessWidenerVisitor; +import net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.processor.MappingProcessorContext; import net.fabricmc.loom.api.processor.MinecraftJarProcessor; @@ -44,6 +44,8 @@ import net.fabricmc.tinyremapper.TinyRemapper; public final class TransitiveAccessWidenerMappingsProcessor implements MinecraftJarProcessor.MappingsProcessor { public static final TransitiveAccessWidenerMappingsProcessor INSTANCE = new TransitiveAccessWidenerMappingsProcessor(); + private static final Logger LOGGER = LoggerFactory.getLogger(TransitiveAccessWidenerMappingsProcessor.class); + private TransitiveAccessWidenerMappingsProcessor() { } @@ -63,7 +65,7 @@ public final class TransitiveAccessWidenerMappingsProcessor implements Minecraft try (LazyCloseable remapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) { for (AccessWidenerEntry accessWidener : accessWideners) { - var visitor = new MappingCommentVisitor(accessWidener.mappingId(), mappings); + var visitor = new MappingCommentClassTweakerVisitor(accessWidener.mappingId(), mappings); accessWidener.read(visitor, remapper); } } catch (IOException e) { @@ -73,80 +75,91 @@ public final class TransitiveAccessWidenerMappingsProcessor implements Minecraft return true; } - private record MappingCommentVisitor(String modId, MemoryMappingTree mappingTree) implements AccessWidenerVisitor { - private static final Logger LOGGER = LoggerFactory.getLogger(MappingCommentVisitor.class); - + private record MappingCommentClassTweakerVisitor(String modId, MemoryMappingTree mappingTree) implements ClassTweakerVisitor { @Override - public void visitClass(String name, AccessWidenerReader.AccessType access, boolean transitive) { - MappingTree.ClassMapping classMapping = mappingTree.getClass(name); - - if (classMapping == null) { - LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", name, modId()); - return; - } - - classMapping.setComment(appendComment(classMapping.getComment(), access)); + public AccessWidenerVisitor visitAccessWidener(String owner) { + return new MappingCommentAccessWidenerVisitor(owner); } - @Override - public void visitMethod(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { - // Access is also applied to the class, so also add the comment to the class - visitClass(owner, access, transitive); + private class MappingCommentAccessWidenerVisitor implements AccessWidenerVisitor { + private final String className; - MappingTree.ClassMapping classMapping = mappingTree.getClass(owner); - - if (classMapping == null) { - LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", owner, modId()); - return; + private MappingCommentAccessWidenerVisitor(String className) { + this.className = className; } - MappingTree.MethodMapping methodMapping = classMapping.getMethod(name, descriptor); + @Override + public void visitClass(AccessType access, boolean transitive) { + MappingTree.ClassMapping classMapping = mappingTree.getClass(className); - if (methodMapping == null) { - LOGGER.info("Failed to find method ({}) in ({}) to mark access widened by mod ({})", name, owner, modId()); - return; + if (classMapping == null) { + LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", className, modId()); + return; + } + + classMapping.setComment(appendComment(classMapping.getComment(), access)); } - methodMapping.setComment(appendComment(methodMapping.getComment(), access)); - } + @Override + public void visitMethod(String name, String descriptor, AccessType access, boolean transitive) { + // Access is also applied to the class, so also add the comment to the class + visitClass(access, transitive); - @Override - public void visitField(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { - // Access is also applied to the class, so also add the comment to the class - visitClass(owner, access, transitive); + MappingTree.ClassMapping classMapping = mappingTree.getClass(className); - MappingTree.ClassMapping classMapping = mappingTree.getClass(owner); + if (classMapping == null) { + LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", className, modId()); + return; + } - if (classMapping == null) { - LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", name, modId()); - return; + MappingTree.MethodMapping methodMapping = classMapping.getMethod(name, descriptor); + + if (methodMapping == null) { + LOGGER.info("Failed to find method ({}) in ({}) to mark access widened by mod ({})", name, className, modId()); + return; + } + + methodMapping.setComment(appendComment(methodMapping.getComment(), access)); } - MappingTree.FieldMapping fieldMapping = classMapping.getField(name, descriptor); + @Override + public void visitField(String name, String descriptor, AccessType access, boolean transitive) { + // Access is also applied to the class, so also add the comment to the class + visitClass(access, transitive); - if (fieldMapping == null) { - LOGGER.info("Failed to find field ({}) in ({}) to mark access widened by mod ({})", name, owner, modId()); - return; + MappingTree.ClassMapping classMapping = mappingTree.getClass(className); + + if (classMapping == null) { + LOGGER.info("Failed to find class ({}) to mark access widened by mod ({})", name, modId()); + return; + } + + MappingTree.FieldMapping fieldMapping = classMapping.getField(name, descriptor); + + if (fieldMapping == null) { + LOGGER.info("Failed to find field ({}) in ({}) to mark access widened by mod ({})", name, className, modId()); + return; + } + + fieldMapping.setComment(appendComment(fieldMapping.getComment(), access)); } - fieldMapping.setComment(appendComment(fieldMapping.getComment(), access)); - } + private String appendComment(String comment, AccessType access) { + if (comment == null) { + comment = ""; + } else { + comment += "\n"; + } - private String appendComment(String comment, AccessWidenerReader.AccessType access) { - if (comment == null) { - comment = ""; - } else { - comment += "\n"; + String awComment = "Access widened by %s to %s".formatted(modId(), access); + + if (!comment.contains(awComment)) { + // Ensure we don't comment the same thing twice. A bit of a cheap way to do this, but should work ok. + comment += awComment; + } + + return comment; } - - String awComment = "Access widened by %s to %s".formatted(modId(), access); - - if (!comment.contains(awComment)) { - // Ensure we don't comment the same thing twice. A bit of a cheap way to do this, but should work ok. - comment += awComment; - } - - return comment; } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerAnalyzeVisitorProvider.java b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerAnalyzeVisitorProvider.java index b59373d6..9b218417 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerAnalyzeVisitorProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerAnalyzeVisitorProvider.java @@ -29,16 +29,15 @@ import java.util.List; import org.objectweb.asm.ClassVisitor; -import net.fabricmc.accesswidener.AccessWidener; -import net.fabricmc.accesswidener.AccessWidenerClassVisitor; -import net.fabricmc.accesswidener.AccessWidenerReader; +import net.fabricmc.classtweaker.api.ClassTweaker; +import net.fabricmc.classtweaker.api.ClassTweakerReader; import net.fabricmc.loom.configuration.mods.dependency.ModDependency; import net.fabricmc.loom.util.Constants; import net.fabricmc.tinyremapper.TinyRemapper; -public record AccessWidenerAnalyzeVisitorProvider(AccessWidener accessWidener) implements TinyRemapper.AnalyzeVisitorProvider { +public record AccessWidenerAnalyzeVisitorProvider(ClassTweaker accessWidener) implements TinyRemapper.AnalyzeVisitorProvider { static AccessWidenerAnalyzeVisitorProvider createFromMods(String namespace, List mods) throws IOException { - AccessWidener accessWidener = new AccessWidener(); + ClassTweaker accessWidener = ClassTweaker.newInstance(); accessWidener.visitHeader(namespace); for (ModDependency mod : mods) { @@ -48,8 +47,8 @@ public record AccessWidenerAnalyzeVisitorProvider(AccessWidener accessWidener) i continue; } - final var reader = new AccessWidenerReader(accessWidener); - reader.read(accessWidenerData.content()); + final var reader = ClassTweakerReader.create(accessWidener); + reader.read(accessWidenerData.content(), null); // TODO pass mod id } return new AccessWidenerAnalyzeVisitorProvider(accessWidener); @@ -57,6 +56,6 @@ public record AccessWidenerAnalyzeVisitorProvider(AccessWidener accessWidener) i @Override public ClassVisitor insertAnalyzeVisitor(int mrjVersion, String className, ClassVisitor next) { - return AccessWidenerClassVisitor.createClassVisitor(Constants.ASM_VERSION, next, accessWidener); + return accessWidener.createClassVisitor(Constants.ASM_VERSION, next, null); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java index 725e4fb1..8b2cb86d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java @@ -30,9 +30,9 @@ import java.util.List; import org.objectweb.asm.commons.Remapper; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerRemapper; -import net.fabricmc.accesswidener.AccessWidenerWriter; +import net.fabricmc.classtweaker.api.ClassTweakerReader; +import net.fabricmc.classtweaker.api.ClassTweakerWriter; +import net.fabricmc.classtweaker.visitors.ClassTweakerRemapperVisitor; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.util.fmj.FabricModJson; import net.fabricmc.loom.util.fmj.FabricModJsonFactory; @@ -42,18 +42,18 @@ public class AccessWidenerUtils { * Remap a mods access widener from intermediary to named, so that loader can apply it in our dev-env. */ public static byte[] remapAccessWidener(byte[] input, Remapper remapper) { - int version = AccessWidenerReader.readVersion(input); + int version = ClassTweakerReader.readVersion(input); - AccessWidenerWriter writer = new AccessWidenerWriter(version); - AccessWidenerRemapper awRemapper = new AccessWidenerRemapper( + ClassTweakerWriter writer = ClassTweakerWriter.create(version); + ClassTweakerRemapperVisitor awRemapper = new ClassTweakerRemapperVisitor( writer, remapper, MappingsNamespace.INTERMEDIARY.toString(), MappingsNamespace.NAMED.toString() ); - AccessWidenerReader reader = new AccessWidenerReader(awRemapper); - reader.read(input); - return writer.write(); + ClassTweakerReader reader = ClassTweakerReader.create(awRemapper); + reader.read(input, null); // TODO pass modid + return writer.getOutput(); } public static AccessWidenerData readAccessWidenerData(Path inputJar) throws IOException { @@ -74,11 +74,11 @@ public class AccessWidenerUtils { final String accessWidenerPath = classTweakers.get(0); final byte[] accessWidener = fabricModJson.getSource().read(accessWidenerPath); - final AccessWidenerReader.Header header = AccessWidenerReader.readHeader(accessWidener); + final ClassTweakerReader.Header header = ClassTweakerReader.readHeader(accessWidener); return new AccessWidenerData(accessWidenerPath, header, accessWidener); } - public record AccessWidenerData(String path, AccessWidenerReader.Header header, byte[] content) { + public record AccessWidenerData(String path, ClassTweakerReader.Header header, byte[] content) { } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 3a51a33e..745da380 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -52,9 +52,9 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerRemapper; -import net.fabricmc.accesswidener.AccessWidenerWriter; +import net.fabricmc.classtweaker.api.ClassTweakerReader; +import net.fabricmc.classtweaker.api.ClassTweakerWriter; +import net.fabricmc.classtweaker.visitors.ClassTweakerRemapperVisitor; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.build.nesting.JarNester; import net.fabricmc.loom.build.nesting.NestableJarGenerationTask; @@ -268,19 +268,19 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { private byte[] remapAccessWidener(byte[] input) { Objects.requireNonNull(tinyRemapper, "tinyRemapper"); - int version = AccessWidenerReader.readVersion(input); + int version = ClassTweakerReader.readVersion(input); - AccessWidenerWriter writer = new AccessWidenerWriter(version); - AccessWidenerRemapper remapper = new AccessWidenerRemapper( + ClassTweakerWriter writer = ClassTweakerWriter.create(version); + ClassTweakerRemapperVisitor remapper = new ClassTweakerRemapperVisitor( writer, tinyRemapper.getEnvironment().getRemapper(), getParameters().getSourceNamespace().get(), getParameters().getTargetNamespace().get() ); - AccessWidenerReader reader = new AccessWidenerReader(remapper); - reader.read(input); + ClassTweakerReader reader = ClassTweakerReader.create(remapper); + reader.read(input, null); // TODO pass mod id - return writer.write(); + return writer.getOutput(); } private void addNestedJars() { diff --git a/src/main/java/net/fabricmc/loom/task/ValidateAccessWidenerTask.java b/src/main/java/net/fabricmc/loom/task/ValidateAccessWidenerTask.java index c47f8b0b..33383175 100644 --- a/src/main/java/net/fabricmc/loom/task/ValidateAccessWidenerTask.java +++ b/src/main/java/net/fabricmc/loom/task/ValidateAccessWidenerTask.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.concurrent.atomic.AtomicBoolean; import javax.inject.Inject; @@ -41,14 +42,12 @@ import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.SkipWhenEmpty; import org.gradle.api.tasks.TaskAction; -import net.fabricmc.accesswidener.AccessWidenerFormatException; -import net.fabricmc.accesswidener.AccessWidenerReader; -import net.fabricmc.accesswidener.AccessWidenerVisitor; +import net.fabricmc.classtweaker.api.ClassTweakerReader; +import net.fabricmc.classtweaker.validator.ClassTweakerValidatingVisitor; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.util.TinyRemapperLoggerAdapter; import net.fabricmc.tinyremapper.TinyRemapper; -import net.fabricmc.tinyremapper.api.TrEnvironment; public abstract class ValidateAccessWidenerTask extends DefaultTask { @SkipWhenEmpty @@ -77,44 +76,26 @@ public abstract class ValidateAccessWidenerTask extends DefaultTask { tinyRemapper.readClassPath(file.toPath()); } - final AccessWidenerValidator validator = new AccessWidenerValidator(tinyRemapper.getEnvironment()); - final AccessWidenerReader accessWidenerReader = new AccessWidenerReader(validator); + AtomicBoolean hasProblem = new AtomicBoolean(false); + + final ClassTweakerValidatingVisitor validator = new ClassTweakerValidatingVisitor(tinyRemapper.getEnvironment(), (lineNumber, message) -> { + hasProblem.set(true); + getLogger().error("{} on line {}", message, lineNumber); + }); + + final ClassTweakerReader accessWidenerReader = ClassTweakerReader.create(validator); try (BufferedReader reader = Files.newBufferedReader(getAccessWidener().get().getAsFile().toPath(), StandardCharsets.UTF_8)) { accessWidenerReader.read(reader, "named"); - } catch (AccessWidenerFormatException e) { - getLogger().error("Failed to validate access-widener file {} on line {}: {}", getAccessWidener().get().getAsFile().getName(), e.getLineNumber(), e.getMessage()); - throw e; } catch (IOException e) { throw new UncheckedIOException("Failed to read access widener", e); } finally { tinyRemapper.finish(); } - } - /** - * Validates that all entries in an access-widner file relate to a class/method/field in the mc jar. - */ - private record AccessWidenerValidator(TrEnvironment environment) implements AccessWidenerVisitor { - @Override - public void visitClass(String name, AccessWidenerReader.AccessType access, boolean transitive) { - if (environment().getClass(name) == null) { - throw new RuntimeException("Could not find class (%s)".formatted(name)); - } - } - - @Override - public void visitMethod(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { - if (environment().getMethod(owner, name, descriptor) == null) { - throw new RuntimeException("Could not find method (%s%s) in class (%s)".formatted(name, descriptor, owner)); - } - } - - @Override - public void visitField(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { - if (environment().getField(owner, name, descriptor) == null) { - throw new RuntimeException("Could not find field (%s%s) in class (%s)".formatted(name, descriptor, owner)); - } + if (hasProblem.get()) { + getLogger().error("access-widener validation failed for {}", getAccessWidener().get().getAsFile().getName()); + throw new RuntimeException("access-widener validation failed for %s".formatted(getAccessWidener().get().getAsFile().getName())); } } } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy index a405f602..a0754717 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy @@ -72,18 +72,17 @@ class AccessWidenerTest extends Specification implements GradleProjectTestTrait setup: def gradle = gradleProject(project: "accesswidener", version: version) new File(gradle.projectDir, "src/main/resources/modid.accesswidener").append(awLine) - def errorPrefix = "Failed to validate access-widener file modid.accesswidener on line 10: java.lang.RuntimeException: " when: def result = gradle.run(task: "check", expectFailure: true) then: - result.output.contains(errorPrefix + error) + result.output.contains(error) where: - awLine | error | version - 'accessible\tclass\tnet/minecraft/DoesntExists' | "Could not find class (net/minecraft/DoesntExists)" | DEFAULT_GRADLE - 'accessible\tfield\tnet/minecraft/screen/slot/Slot\tabc\tI' | "Could not find field (abcI) in class (net/minecraft/screen/slot/Slot)" | DEFAULT_GRADLE - 'accessible\tmethod\tnet/minecraft/client/main/Main\tmain\t([Ljava/lang/NotAString;)V' | "Could not find method (main([Ljava/lang/NotAString;)V) in class (net/minecraft/client/main/Main)" | DEFAULT_GRADLE + awLine | error | version + 'accessible\tclass\tnet/minecraft/DoesntExists' | "Could not find class (net/minecraft/DoesntExists) on line 10" | DEFAULT_GRADLE + 'accessible\tfield\tnet/minecraft/screen/slot/Slot\tabc\tI' | "Could not find field (abc:I) in class (net/minecraft/screen/slot/Slot) on line 10" | DEFAULT_GRADLE + 'accessible\tmethod\tnet/minecraft/client/main/Main\tmain\t([Ljava/lang/NotAString;)V' | "Could not find method (main([Ljava/lang/NotAString;)V) in class (net/minecraft/client/main/Main) on line 10" | DEFAULT_GRADLE } }