mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-28 04:07:01 -05:00
Direct port to class tweaker (#1398)
* Direct port to class tweaker * Debugging help * Checkstyle * Update CT
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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<TinyRemapper> remapper) throws IOException;
|
||||
void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper) throws IOException;
|
||||
}
|
||||
|
||||
@@ -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<AccessWi
|
||||
public void processJar(Path jar, AccessWidenerJarProcessor.Spec spec, ProcessorContext context) throws IOException {
|
||||
final List<AccessWidenerEntry> accessWideners = spec.accessWidenersForContext(context);
|
||||
|
||||
final var accessWidener = new AccessWidener();
|
||||
final var accessWidener = ClassTweaker.newInstance();
|
||||
|
||||
try (LazyCloseable<TinyRemapper> remapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) {
|
||||
for (AccessWidenerEntry widener : accessWideners) {
|
||||
|
||||
@@ -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<String> 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<Pair<String, ZipUtils.UnsafeUnaryOperator<byte[]>>> getTransformers(Set<String> 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<byte[]> 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();
|
||||
|
||||
@@ -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<TinyRemapper> remapper) throws IOException {
|
||||
var reader = new AccessWidenerReader(visitor);
|
||||
reader.read(Files.readAllBytes(path));
|
||||
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper) throws IOException {
|
||||
var reader = ClassTweakerReader.create(visitor);
|
||||
reader.read(Files.readAllBytes(path), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<TinyRemapper> remapper) throws IOException {
|
||||
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> 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(),
|
||||
|
||||
@@ -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<AccessWidenerJarProcessor.Spec> {
|
||||
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<TinyRemapper> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ModDependency> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user