Add option to drop non root methods when using Mojang mappings. (#1258)

* Attempt to fix #1209

* More layered mappings tests

* Fix build

* Make opt in

* Rename
This commit is contained in:
modmuss
2025-04-16 22:08:49 +01:00
committed by GitHub
parent 47e001e929
commit e34325f7bc
9 changed files with 214 additions and 66 deletions

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2016-2021 FabricMC
* Copyright (c) 2016-2025 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -46,6 +46,8 @@ public interface MappingContext {
Supplier<MemoryMappingTree> intermediaryTree();
boolean isUsingIntermediateMappings();
MinecraftProvider minecraftProvider();
default String minecraftVersion() {
@@ -62,4 +64,6 @@ public interface MappingContext {
DownloadBuilder download(String url);
boolean refreshDeps();
boolean hasProperty(String property);
}

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2018-2021 FabricMC
* Copyright (c) 2018-2025 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -41,6 +41,7 @@ import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.mappings.layered.MappingContext;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
import net.fabricmc.loom.util.download.DownloadBuilder;
import net.fabricmc.loom.util.gradle.GradleUtils;
import net.fabricmc.loom.util.service.ScopedServiceFactory;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
@@ -85,6 +86,11 @@ public class GradleMappingContext implements MappingContext {
};
}
@Override
public boolean isUsingIntermediateMappings() {
return !(extension.getIntermediateMappingsProvider() instanceof NoOpIntermediateMappingsProvider);
}
@Override
public MinecraftProvider minecraftProvider() {
return extension.getMinecraftProvider();
@@ -110,6 +116,11 @@ public class GradleMappingContext implements MappingContext {
return extension.refreshDeps();
}
@Override
public boolean hasProperty(String property) {
return GradleUtils.getBooleanProperty(project, property);
}
public Project getProject() {
return project;
}

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2021 FabricMC
* Copyright (c) 2021-2025 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,9 +30,11 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import org.gradle.api.logging.Logger;
import org.jetbrains.annotations.Nullable;
import net.fabricmc.loom.api.mappings.layered.MappingLayer;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
@@ -41,21 +43,51 @@ import net.fabricmc.loom.configuration.providers.mappings.utils.DstNameFilterMap
import net.fabricmc.mappingio.MappingVisitor;
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
import net.fabricmc.mappingio.format.proguard.ProGuardFileReader;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
public record MojangMappingLayer(Path clientMappings, Path serverMappings, boolean nameSyntheticMembers,
Logger logger) implements MappingLayer {
public record MojangMappingLayer(Path clientMappings, Path serverMappings, boolean nameSyntheticMembers, boolean dropNoneIntermediaryRoots,
@Nullable Supplier<MemoryMappingTree> intermediarySupplier, Logger logger) implements MappingLayer {
private static final Pattern SYNTHETIC_NAME_PATTERN = Pattern.compile("^(access|this|val\\$this|lambda\\$.*)\\$[0-9]+$");
@Override
public void visit(MappingVisitor mappingVisitor) throws IOException {
printMappingsLicense(clientMappings);
if (!dropNoneIntermediaryRoots) {
logger().debug("Not attempting to drop none intermediary roots");
readMappings(mappingVisitor);
return;
}
logger().info("Attempting to drop none intermediary roots");
if (intermediarySupplier == null) {
// Using no-op intermediary mappings
readMappings(mappingVisitor);
return;
}
// Create a mapping tree with src: official dst: named, intermediary
MemoryMappingTree mappingTree = new MemoryMappingTree();
intermediarySupplier.get().accept(mappingTree);
readMappings(mappingTree);
// The following code first switches the src namespace to intermediary dropping any entries that don't have an intermediary name
// This removes any none root methods before switching it back to official
var officialSwitch = new MappingSourceNsSwitch(mappingVisitor, getSourceNamespace().toString(), false);
var intermediarySwitch = new MappingSourceNsSwitch(officialSwitch, MappingsNamespace.INTERMEDIARY.toString(), true);
mappingTree.accept(intermediarySwitch);
}
private void readMappings(MappingVisitor mappingVisitor) throws IOException {
// Filter out field names matching the pattern
DstNameFilterMappingVisitor nameFilter = new DstNameFilterMappingVisitor(mappingVisitor, SYNTHETIC_NAME_PATTERN);
var nameFilter = new DstNameFilterMappingVisitor(mappingVisitor, SYNTHETIC_NAME_PATTERN);
// Make official the source namespace
MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nameSyntheticMembers() ? mappingVisitor : nameFilter, MappingsNamespace.OFFICIAL.toString());
var nsSwitch = new MappingSourceNsSwitch(nameSyntheticMembers() ? mappingVisitor : nameFilter, MappingsNamespace.OFFICIAL.toString());
// Read both server and client mappings
try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8);
BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings, StandardCharsets.UTF_8)) {
ProGuardFileReader.read(clientBufferedReader, MappingsNamespace.NAMED.toString(), MappingsNamespace.OFFICIAL.toString(), nsSwitch);

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2016-2021 FabricMC
* Copyright (c) 2016-2025 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@ import java.nio.file.Path;
import net.fabricmc.loom.api.mappings.layered.MappingContext;
import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.download.DownloadException;
public record MojangMappingsSpec(boolean nameSyntheticMembers) implements MappingsSpec<MojangMappingLayer> {
@@ -66,6 +67,8 @@ public record MojangMappingsSpec(boolean nameSyntheticMembers) implements Mappin
clientMappings,
serverMappings,
nameSyntheticMembers(),
context.hasProperty(Constants.Properties.DROP_NON_INTERMEDIATE_ROOT_METHODS),
context.isUsingIntermediateMappings() ? context.intermediaryTree() : null,
context.getLogger()
);
}

View File

@@ -153,6 +153,10 @@ public class Constants {
* Skip the signature verification of the Minecraft jar after downloading it.
*/
public static final String DISABLE_MINECRAFT_VERIFICATION = "fabric.loom.disableMinecraftVerification";
/**
* When using the MojangMappingLayer this will remove names for non root methods by using the intermediary mappings.
*/
public static final String DROP_NON_INTERMEDIATE_ROOT_METHODS = "fabric.loom.dropNonIntermediateRootMethods";
}
public static final class Manifest {