aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-09-17 02:23:45 +0800
committershedaniel <daniel@shedaniel.me>2021-09-17 02:23:45 +0800
commiteff1f8ba523a777b4e0ad660458dd04abf363f36 (patch)
treeecaef55f557d9fba0941561fa50169c0a151314a
parent848a6a548f59161bbb7037965c366d167ce9be30 (diff)
parent2a040d03d7a8b7b67989a8ef986e374cffb72332 (diff)
downloadarchitectury-loom-eff1f8ba523a777b4e0ad660458dd04abf363f36.tar.gz
architectury-loom-eff1f8ba523a777b4e0ad660458dd04abf363f36.tar.bz2
architectury-loom-eff1f8ba523a777b4e0ad660458dd04abf363f36.zip
Merge remote-tracking branch 'FabricMC/dev/0.10' into dev/0.10.0
# Conflicts: # build.gradle # src/main/java/net/fabricmc/loom/LoomGradleExtension.java # src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java # src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java # src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java # src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilderImpl.java # src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java # src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java # src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java # src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java # src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java # src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java # src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java # src/main/java/net/fabricmc/loom/task/RemapJarTask.java # src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java # src/main/java/net/fabricmc/loom/util/SourceRemapper.java # src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java # src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy
-rw-r--r--build.gradle7
-rw-r--r--src/main/java/net/fabricmc/loom/LoomGradleExtension.java6
-rw-r--r--src/main/java/net/fabricmc/loom/LoomGradlePlugin.java2
-rw-r--r--src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java9
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/MappingContext.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java)14
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/MappingLayer.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java)13
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java56
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java79
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/spec/LayeredMappingSpecBuilder.java50
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/spec/MappingsSpec.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java)15
-rw-r--r--src/main/java/net/fabricmc/loom/api/mappings/layered/spec/ParchmentMappingsSpecBuilder.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java)20
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerFile.java66
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java162
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java82
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java202
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java147
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java47
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java18
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java2
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilderImpl.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java)24
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java6
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java10
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsCache.java69
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java43
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java10
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java4
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java33
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java4
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java12
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java9
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilderImpl.java (renamed from src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java)18
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/DependencyFileSpec.java69
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/LocalFileSpec.java63
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/MavenFileSpec.java37
-rw-r--r--src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java12
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java4
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/TinyJavadocProvider.java96
-rw-r--r--src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java14
-rw-r--r--src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java14
-rw-r--r--src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java8
-rw-r--r--src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java36
-rw-r--r--src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java33
-rw-r--r--src/main/java/net/fabricmc/loom/task/RemapJarTask.java19
-rw-r--r--src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java3
-rw-r--r--src/main/java/net/fabricmc/loom/util/Constants.java2
-rw-r--r--src/main/java/net/fabricmc/loom/util/SourceRemapper.java5
-rw-r--r--src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java108
-rw-r--r--src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java72
-rw-r--r--src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy17
-rw-r--r--src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy15
-rw-r--r--src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy27
-rw-r--r--src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy5
-rw-r--r--src/test/resources/accesswidener/expected.accesswidener7
-rw-r--r--src/test/resources/projects/transitiveAccesswidener/build.gradle18
-rw-r--r--src/test/resources/projects/transitiveAccesswidener/dummyDependency/dummy.accesswidener3
-rw-r--r--src/test/resources/projects/transitiveAccesswidener/dummyDependency/fabric.mod.json7
-rw-r--r--src/test/resources/projects/transitiveAccesswidener/src/main/java/ExampleMod.java13
57 files changed, 1441 insertions, 505 deletions
diff --git a/build.gradle b/build.gradle
index 33c5bc40..c67fd507 100644
--- a/build.gradle
+++ b/build.gradle
@@ -94,15 +94,12 @@ dependencies {
// tinyfile management
implementation ('dev.architectury:tiny-remapper:1.3.11')
implementation ('dev.architectury:mappings-layers-core:1.4.9')
- implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17')
-
- implementation 'net.fabricmc:access-widener:1.1.0'
+ implementation 'net.fabricmc:access-widener:2.0.0'
implementation 'net.fabricmc:mapping-io:0.2.1'
- implementation ('net.fabricmc:lorenz-tiny:3.0.0') {
+ implementation ('net.fabricmc:lorenz-tiny:4.0.0') {
transitive = false
}
- implementation ('org.cadixdev:lorenz-io-proguard:0.5.7')
implementation "dev.architectury:refmap-remapper:1.0.5"
// decompilers
diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java
index 9c1a4047..d94aeffa 100644
--- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java
+++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java
@@ -25,6 +25,7 @@
package net.fabricmc.loom;
import java.io.File;
+import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
@@ -38,6 +39,7 @@ import org.gradle.api.file.ConfigurableFileCollection;
import net.fabricmc.loom.api.LoomGradleExtensionAPI;
import net.fabricmc.loom.configuration.InstallerData;
import net.fabricmc.loom.configuration.LoomDependencyManager;
+import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
import net.fabricmc.loom.configuration.providers.forge.FieldMigratedMappingsProvider;
@@ -111,6 +113,10 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
@Override
MixinExtension getMixin();
+ List<AccessWidenerFile> getTransitiveAccessWideners();
+
+ void addTransitiveAccessWideners(List<AccessWidenerFile> accessWidenerFiles);
+
// ===================
// Architectury Loom
// ===================
diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java
index be8a5f24..cf0b5424 100644
--- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java
+++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java
@@ -43,7 +43,6 @@ import net.fabricmc.loom.configuration.CompileConfiguration;
import net.fabricmc.loom.configuration.FabricApiExtension;
import net.fabricmc.loom.configuration.MavenPublication;
import net.fabricmc.loom.configuration.ide.IdeConfiguration;
-import net.fabricmc.loom.configuration.providers.mappings.MappingsCache;
import net.fabricmc.loom.decompilers.DecompilerConfiguration;
import net.fabricmc.loom.extension.LoomFiles;
import net.fabricmc.loom.extension.LoomGradleExtensionImpl;
@@ -78,7 +77,6 @@ public class LoomGradlePlugin implements BootstrappedPlugin {
refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies() || "true".equals(System.getProperty("loom.refresh"));
if (refreshDeps) {
- MappingsCache.INSTANCE.invalidate();
project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower.");
}
diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java
index eea65bf5..e8d724be 100644
--- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java
+++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java
@@ -43,11 +43,11 @@ import org.gradle.api.publish.maven.MavenPublication;
import org.jetbrains.annotations.ApiStatus;
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
+import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
import net.fabricmc.loom.configuration.ide.RunConfig;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
import net.fabricmc.loom.configuration.launch.LaunchProviderSettings;
import net.fabricmc.loom.configuration.processors.JarProcessor;
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
import net.fabricmc.loom.util.DeprecationHelper;
import net.fabricmc.loom.util.ModPlatform;
@@ -213,6 +213,13 @@ public interface LoomGradleExtensionAPI {
*/
String getModVersion();
+ /**
+ * When true loom will apply transitive access wideners from compile dependencies.
+ *
+ * @return the property controlling the transitive access wideners
+ */
+ Property<Boolean> getEnableTransitiveAccessWideners();
+
// ===================
// Architectury Loom
// ===================
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingContext.java
index 3fbfb655..cbc7d3ab 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingContext.java
@@ -22,16 +22,22 @@
* SOFTWARE.
*/
-package net.fabricmc.loom.configuration.providers.mappings;
+package net.fabricmc.loom.api.mappings.layered;
-import java.io.File;
+import java.nio.file.Path;
+import org.gradle.api.artifacts.Dependency;
import org.gradle.api.logging.Logger;
+import org.jetbrains.annotations.ApiStatus;
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
+import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
+@ApiStatus.Experimental /* Very Experimental and not cleanly separated from the impl atm */
public interface MappingContext {
- File mavenFile(String mavenNotation);
+ Path resolveDependency(Dependency dependency);
+
+ Path resolveMavenDependency(String mavenNotation);
MappingsProvider mappingsProvider();
@@ -44,7 +50,7 @@ public interface MappingContext {
/**
* Creates a temporary working dir to be used to store working files.
*/
- File workingDirectory(String name);
+ Path workingDirectory(String name);
Logger getLogger();
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingLayer.java
index f3717894..1f28d65a 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingLayer.java
@@ -22,21 +22,28 @@
* SOFTWARE.
*/
-package net.fabricmc.loom.configuration.providers.mappings;
+package net.fabricmc.loom.api.mappings.layered;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
+import org.jetbrains.annotations.ApiStatus;
+
import net.fabricmc.mappingio.MappingVisitor;
+@ApiStatus.Experimental
public interface MappingLayer {
void visit(MappingVisitor mappingVisitor) throws IOException;
- default MappingNamespace getSourceNamespace() {
- return MappingNamespace.NAMED;
+ default MappingsNamespace getSourceNamespace() {
+ return MappingsNamespace.NAMED;
}
+ /**
+ * Provides a list of layer classes that this mapping layer depends on. If such a layer is not present an Exception will be thrown when trying to resolve the layer.
+ * @return A list of MappingLayer classes to depend on.
+ */
default List<Class<? extends MappingLayer>> dependsOn() {
return Collections.emptyList();
}
diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java
new file mode 100644
index 00000000..ae32f7f9
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2016-2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.api.mappings.layered;
+
+import java.util.Locale;
+
+/**
+ * The standard namespaces used by loom.
+ */
+public enum MappingsNamespace {
+ /**
+ * Official mappings are the names that are used in the vanilla Minecraft game jars, these are usually obfuscated.
+ */
+ OFFICIAL,
+
+ /**
+ * Intermediary mappings have been generated to provide a stable set of names across minecraft versions.
+ *
+ * <p>Intermediary is used in a production runtime (outside a dev env) allowing mods to run across multiple versions of the game. Mods are remapped from "named" at build time.
+ *
+ * @see <a href="https://github.com/FabricMC/intermediary/">github.com/FabricMC/intermediary/</a>
+ */
+ INTERMEDIARY,
+
+ /**
+ * Named mappings are the developer friendly names used to develop mods against.
+ */
+ NAMED;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ROOT);
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java
new file mode 100644
index 00000000..19129e5d
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.api.mappings.layered.spec;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.file.RegularFileProperty;
+import org.jetbrains.annotations.ApiStatus;
+
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.configuration.providers.mappings.utils.DependencyFileSpec;
+import net.fabricmc.loom.configuration.providers.mappings.utils.LocalFileSpec;
+import net.fabricmc.loom.configuration.providers.mappings.utils.MavenFileSpec;
+
+/**
+ * FileSpec should be used in MappingsSpec's that take an input file. The input file can either be a local file or a gradle dep.
+ */
+@ApiStatus.Experimental
+public interface FileSpec {
+ static FileSpec create(Object o) {
+ Objects.requireNonNull(o, "Object cannot be null");
+
+ if (o instanceof String s) {
+ return createFromMavenDependency(s);
+ } else if (o instanceof Dependency d) {
+ return createFromDependency(d);
+ } else if (o instanceof File f) {
+ return createFromFile(f);
+ } else if (o instanceof RegularFileProperty rfp) {
+ return createFromFile(rfp);
+ }
+
+ throw new UnsupportedOperationException("Cannot create FileSpec from object of type:" + o.getClass().getCanonicalName());
+ }
+
+ static FileSpec createFromMavenDependency(String dependencyNotation) {
+ return new MavenFileSpec(dependencyNotation);
+ }
+
+ static FileSpec createFromDependency(Dependency dependency) {
+ return new DependencyFileSpec(dependency);
+ }
+
+ static FileSpec createFromFile(File file) {
+ return new LocalFileSpec(file);
+ }
+
+ // Note resolved instantly, this is not lazy
+ static FileSpec createFromFile(RegularFileProperty regularFileProperty) {
+ return createFromFile(regularFileProperty.getAsFile().get());
+ }
+
+ Path get(MappingContext context);
+}
diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/LayeredMappingSpecBuilder.java
new file mode 100644
index 00000000..05180172
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/LayeredMappingSpecBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.api.mappings.layered.spec;
+
+import org.gradle.api.Action;
+import org.jetbrains.annotations.ApiStatus;
+
+/**
+ * Used to configure a layered mapping spec.
+ */
+@ApiStatus.Experimental
+public interface LayeredMappingSpecBuilder {
+ /**
+ * Add a MappingsSpec layer.
+ */
+ LayeredMappingSpecBuilder addLayer(MappingsSpec<?> mappingSpec);
+
+ /**
+ * Add a layer that uses the official mappings provided by Mojang.
+ */
+ LayeredMappingSpecBuilder officialMojangMappings();
+
+ default LayeredMappingSpecBuilder parchment(Object object) {
+ return parchment(object, parchmentMappingsSpecBuilder -> parchmentMappingsSpecBuilder.setRemovePrefix(true));
+ }
+
+ LayeredMappingSpecBuilder parchment(Object object, Action<ParchmentMappingsSpecBuilder> action);
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/MappingsSpec.java
index 8b6adcea..8511614e 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/MappingsSpec.java
@@ -22,8 +22,21 @@
* SOFTWARE.
*/
-package net.fabricmc.loom.configuration.providers.mappings;
+package net.fabricmc.loom.api.mappings.layered.spec;
+import org.jetbrains.annotations.ApiStatus;
+
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.MappingLayer;
+
+/**
+ * A MappingsSpec is an immutable set of data used to create the MappingLayer.
+ *
+ * <p>The hashCode is used to generate a hash of the full layered mapping spec, used to cache.
+ *
+ * <p>Commonly implemented as a record
+ */
+@ApiStatus.Experimental
public interface MappingsSpec<L extends MappingLayer> {
L createLayer(MappingContext context);
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/ParchmentMappingsSpecBuilder.java
index 991cdc79..ee3e07a0 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java
+++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/ParchmentMappingsSpecBuilder.java
@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
- * Copyright (c) 2016-2021 FabricMC
+ * Copyright (c) 2021 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
@@ -22,16 +22,14 @@
* SOFTWARE.
*/
-package net.fabricmc.loom.configuration.providers.mappings;
+package net.fabricmc.loom.api.mappings.layered.spec;
-import java.util.Locale;
+import org.jetbrains.annotations.ApiStatus;
-public enum MappingNamespace {
- OFFICIAL,
- INTERMEDIARY,
- NAMED;
-
- public String stringValue() {
- return name().toLowerCase(Locale.ROOT);
- }
+@ApiStatus.Experimental
+public interface ParchmentMappingsSpecBuilder {
+ /**
+ * When enabled the "p" prefix will be stripped from parameter names.
+ */
+ ParchmentMappingsSpecBuilder setRemovePrefix(boolean removePrefix);
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerFile.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerFile.java
new file mode 100644
index 00000000..680aae92
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerFile.java
@@ -0,0 +1,66 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.accesswidener;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import org.zeroturnaround.zip.ZipUtil;
+
+public record AccessWidenerFile(
+ String name,
+ String modId,
+ byte[] content
+) {
+ /**
+ * Reads the access-widener contained in a mod jar, or returns null if there is none.
+ */
+ public static AccessWidenerFile fromModJar(Path modJarPath) {
+ byte[] modJsonBytes = ZipUtil.unpackEntry(modJarPath.toFile(), "fabric.mod.json");
+
+ if (modJsonBytes == null) {
+ return null;
+ }
+
+ JsonObject jsonObject = new Gson().fromJson(new String(modJsonBytes, StandardCharsets.UTF_8), JsonObject.class);
+
+ if (!jsonObject.has("accessWidener")) {
+ return null;
+ }
+
+ String awPath = jsonObject.get("accessWidener").getAsString();
+ String modId = jsonObject.get("id").getAsString();
+
+ byte[] content = ZipUtil.unpackEntry(modJarPath.toFile(), awPath);
+
+ return new AccessWidenerFile(
+ awPath,
+ modId,
+ content
+ );
+ }
+}
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 cecf4d34..bb7717bd 100644
--- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java
+++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java
@@ -24,46 +24,38 @@
package net.fabricmc.loom.configuration.accesswidener;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileReader;
import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
+import com.google.common.hash.Hashing;
import dev.architectury.tinyremapper.TinyRemapper;
import org.gradle.api.Project;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.Remapper;
import org.zeroturnaround.zip.ZipUtil;
-import org.zeroturnaround.zip.transform.ByteArrayZipEntryTransformer;
-import org.zeroturnaround.zip.transform.ZipEntryTransformer;
-import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
import net.fabricmc.accesswidener.AccessWidener;
import net.fabricmc.accesswidener.AccessWidenerReader;
import net.fabricmc.accesswidener.AccessWidenerRemapper;
-import net.fabricmc.accesswidener.AccessWidenerVisitor;
import net.fabricmc.accesswidener.AccessWidenerWriter;
import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.processors.JarProcessor;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
import net.fabricmc.loom.util.Checksum;
import net.fabricmc.loom.util.Constants;
public class AccessWidenerJarProcessor implements JarProcessor {
- private AccessWidener accessWidener = new AccessWidener();
- private AccessWidenerReader accessWidenerReader = new AccessWidenerReader(accessWidener);
+ // Filename used to store hash of input access widener in processed jar file
+ private static final String HASH_FILENAME = "aw.sha256";
+ // The mod's own access widener file
+ private byte[] modAccessWidener;
+ private final AccessWidener accessWidener = new AccessWidener();
private final Project project;
+ // This is a SHA256 hash across the mod's and all transitive AWs
private byte[] inputHash;
public AccessWidenerJarProcessor(Project project) {
@@ -77,121 +69,53 @@ public class AccessWidenerJarProcessor implements JarProcessor {
@Override
public void setup() {
- LoomGradleExtension loomGradleExtension = LoomGradleExtension.get(project);
- File awPath = loomGradleExtension.getAccessWidenerPath().get().getAsFile();
-
- if (!awPath.exists()) {
- throw new RuntimeException("Could not find access widener file @ " + awPath.getAbsolutePath());
- }
-
- inputHash = Checksum.sha256(awPath);
-
- try (BufferedReader reader = new BufferedReader(new FileReader(awPath))) {
- accessWidenerReader.read(reader);
+ LoomGradleExtension extension = LoomGradleExtension.get(project);
+ Path awPath = extension.getAccessWidenerPath().get().getAsFile().toPath();
+
+ // Read our own mod's access widener, used later for producing a version remapped to intermediary
+ try {
+ modAccessWidener = Files.readAllBytes(awPath);
+ } catch (NoSuchFileException e) {
+ throw new RuntimeException("Could not find access widener file @ " + awPath.toAbsolutePath());
} catch (IOException e) {
- throw new RuntimeException("Failed to read project access widener file");
+ throw new RuntimeException("Failed to read access widener: " + awPath);
}
- //Remap accessWidener if its not named, allows for AE's to be written in intermediary
- if (!accessWidener.getNamespace().equals("named")) {
- try {
- List<String> validNamespaces = loomGradleExtension.getMappingsProvider().getMappings().getMetadata().getNamespaces();
+ AccessWidenerReader reader = new AccessWidenerReader(accessWidener);
+ reader.read(modAccessWidener);
- if (!validNamespaces.contains(accessWidener.getNamespace())) {
- throw new UnsupportedOperationException(String.format("Access Widener namespace '%s' is not a valid namespace, it must be one of: '%s'", accessWidener.getNamespace(), String.join(", ", validNamespaces)));
- }
-
- TinyRemapper tinyRemapper = loomGradleExtension.getMinecraftMappedProvider().getTinyRemapper();
- tinyRemapper.replaceMappings(loomGradleExtension.getMinecraftMappedProvider().getMappings(null, "official", "named"));
- loomGradleExtension.getMinecraftMappedProvider();
- tinyRemapper.readClassPath(MinecraftMappedProvider.getRemapClasspath(project));
-
- AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, tinyRemapper.getRemapper(), "named");
- accessWidener = remapper.remap();
-
- tinyRemapper.finish();
- } catch (IOException e) {
- throw new RuntimeException("Failed to remap access widener", e);
- }
- }
+ inputHash = Hashing.sha256().hashBytes(modAccessWidener).asBytes();
}
@Override
public void process(File file) {
- project.getLogger().lifecycle("Processing file: " + file.getName());
- ZipUtil.transformEntries(file, getTransformers(accessWidener.getTargets()));
- ZipUtil.addEntry(file, "aw.sha256", inputHash);
- }
-
- private ZipEntryTransformerEntry[] getTransformers(Set<String> classes) {
- return classes.stream()
- .map(string -> new ZipEntryTransformerEntry(string.replaceAll("\\.", "/") + ".class", getTransformer(string)))
- .toArray(ZipEntryTransformerEntry[]::new);
- }
-
- private ZipEntryTransformer getTransformer(String className) {
- return new ByteArrayZipEntryTransformer() {
- @Override
- protected byte[] transform(ZipEntry zipEntry, byte[] input) {
- ClassReader reader = new ClassReader(input);
- ClassWriter writer = new ClassWriter(0);
- ClassVisitor classVisitor = AccessWidenerVisitor.createClassVisitor(Constants.ASM_VERSION, writer, accessWidener);
-
- project.getLogger().lifecycle("Applying access widener to " + className);
-
- reader.accept(classVisitor, 0);
- return writer.toByteArray();
- }
- };
- }
-
- //Called when remapping the mod
- public void remapAccessWidener(Path modJarPath, Remapper asmRemapper) throws IOException {
- byte[] bytes = getRemappedAccessWidener(asmRemapper);
-
- String path = getAccessWidenerPath(modJarPath);
-
- if (path == null) {
- throw new RuntimeException("Failed to find accessWidener in fabric.mod.json");
- }
-
- boolean replaced = ZipUtil.replaceEntry(modJarPath.toFile(), path, bytes);
-
- if (!replaced) {
- project.getLogger().warn("Failed to replace access widener file at " + path);
- }
- }
-
- public byte[] getRemappedAccessWidener(Remapper asmRemapper) throws IOException {
- AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary");
- AccessWidener remapped = remapper.remap();
- AccessWidenerWriter accessWidenerWriter = new AccessWidenerWriter(remapped);
-
- try (StringWriter writer = new StringWriter()) {
- accessWidenerWriter.write(writer);
- return writer.toString().getBytes();
- }
+ AccessWidenerTransformer applier = new AccessWidenerTransformer(project.getLogger(), accessWidener);
+ applier.apply(file);
+ ZipUtil.addEntry(file, HASH_FILENAME, inputHash);
}
- public String getAccessWidenerPath(Path modJarPath) {
- byte[] modJsonBytes = ZipUtil.unpackEntry(modJarPath.toFile(), "fabric.mod.json");
-
- if (modJsonBytes == null) {
- return null;
- }
-
- JsonObject jsonObject = new Gson().fromJson(new String(modJsonBytes, StandardCharsets.UTF_8), JsonObject.class);
-
- if (!jsonObject.has("accessWidener")) {
- return null;
- }
-
- return jsonObject.get("accessWidener").getAsString();
+ /**
+ * Get this mods access widener remapped to the intermediary namespace.
+ */
+ public byte[] getRemappedAccessWidener(Remapper asmRemapper, String targetNamespace) throws IOException {
+ int version = AccessWidenerReader.readVersion(modAccessWidener);
+
+ AccessWidenerWriter writer = new AccessWidenerWriter(version);
+ AccessWidenerRemapper remapper = new AccessWidenerRemapper(
+ writer,
+ asmRemapper,
+ MappingsNamespace.NAMED.toString(),
+ targetNamespace
+ );
+ AccessWidenerReader reader = new AccessWidenerReader(remapper);
+ reader.read(modAccessWidener);
+
+ return writer.write();
}
@Override
public boolean isInvalid(File file) {
- byte[] hash = ZipUtil.unpackEntry(file, "aw.sha256");
+ byte[] hash = ZipUtil.unpackEntry(file, HASH_FILENAME);
if (hash == null) {
return true;
diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java
new file mode 100644
index 00000000..bdde7403
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerTransformer.java
@@ -0,0 +1,82 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.accesswidener;
+
+import java.io.File;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+
+import org.gradle.api.logging.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.zeroturnaround.zip.ZipUtil;
+import org.zeroturnaround.zip.transform.ByteArrayZipEntryTransformer;
+import org.zeroturnaround.zip.transform.ZipEntryTransformer;
+import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
+
+import net.fabricmc.accesswidener.AccessWidener;
+import net.fabricmc.accesswidener.AccessWidenerClassVisitor;
+import net.fabricmc.loom.util.Constants;
+
+final class AccessWidenerTransformer {
+ private final Logger logger;
+ private final AccessWidener accessWidener;
+
+ AccessWidenerTransformer(Logger logger, AccessWidener accessWidener) {
+ this.logger = logger;
+ this.accessWidener = accessWidener;
+ }
+
+ /**
+ * Apply the rules from an access-widener to the given jar or zip file.
+ */
+ void apply(File jarFile) {
+ logger.lifecycle("Processing file: " + jarFile.getName());
+ ZipUtil.transformEntries(jarFile, getTransformers(accessWidener.getTargets()));
+ }
+
+ private ZipEntryTransformerEntry[] getTransformers(Set<String> classes) {
+ return classes.stream()
+ .map(string -> new ZipEntryTransformerEntry(string.replaceAll("\\.", "/") + ".class", getTransformer(string)))
+ .toArray(ZipEntryTransformerEntry[]::new);
+ }
+
+ private ZipEntryTransformer getTransformer(String className) {
+ return new ByteArrayZipEntryTransformer() {
+ @Override
+ protected byte[] transform(ZipEntry zipEntry, byte[] input) {
+ ClassReader reader = new ClassReader(input);
+ ClassWriter writer = new ClassWriter(0);
+ ClassVisitor classVisitor = AccessWidenerClassVisitor.createClassVisitor(Constants.ASM_VERSION, writer, accessWidener);
+
+ logger.info("Applying access widener to " + className);
+
+ reader.accept(classVisitor, 0);
+ return writer.toByteArray();
+ }
+ };
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java
new file mode 100644
index 00000000..8ae99383
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java
@@ -0,0 +1,202 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2020-2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.accesswidener;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.base.Preconditions;
+import org.gradle.api.Project;
+
+import net.fabricmc.accesswidener.AccessWidener;
+import net.fabricmc.accesswidener.AccessWidenerReader;
+import net.fabricmc.accesswidener.AccessWidenerRemapper;
+import net.fabricmc.accesswidener.AccessWidenerVisitor;
+import net.fabricmc.accesswidener.TransitiveOnlyFilter;
+import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
+import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
+import net.fabricmc.loom.configuration.processors.JarProcessor;
+import net.fabricmc.loom.util.Constants;
+import net.fabricmc.loom.util.TinyRemapperHelper;
+import net.fabricmc.tinyremapper.TinyRemapper;
+
+/**
+ * Applies transitive access wideners that are inherited from mod and api dependencies.
+ */
+public class TransitiveAccessWidenerJarProcessor implements JarProcessor {
+ private final Project project;
+ private final LoomGradleExtension extension;
+
+ private final List<AccessWidenerFile> transitiveAccessWideners;
+
+ public TransitiveAccessWidenerJarProcessor(Project project) {
+ this.project = project;
+ this.extension = LoomGradleExtension.get(project);
+
+ transitiveAccessWideners = getTransitiveAccessWideners();
+
+ extension.addTransitiveAccessWideners(transitiveAccessWideners);
+ }
+
+ @Override
+ public void setup() {
+ }
+
+ public boolean isEmpty() {
+ return transitiveAccessWideners.isEmpty();
+ }
+
+ @Override
+ public String getId() {
+ Preconditions.checkArgument(!isEmpty());
+
+ return "loom:transitive_access_wideners:" + transitiveAccessWideners.hashCode();
+ }
+
+ private List<AccessWidenerFile> getTransitiveAccessWideners() {
+ List<AccessWidenerFile> accessWideners = new ArrayList<>();
+
+ for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) {
+ // Only apply global AWs from mods that are part of the compile classpath
+ if (!entry.compileClasspath()) {
+ continue;
+ }
+
+ Set<File> artifacts = extension.getLazyConfigurationProvider(entry.sourceConfiguration())
+ .get()
+ .resolve();
+
+ for (File artifact : artifacts) {
+ AccessWidenerFile accessWidener = AccessWidenerFile.fromModJar(artifact.toPath());
+
+ if (accessWidener == null) {
+ continue;
+ }
+
+ if (!TransitiveDetectorVisitor.isTransitive(accessWidener.content())) {
+ // AW does not contain anything transitive, skip over it
+ continue;
+ }
+
+ accessWideners.add(accessWidener);
+ }
+ }
+
+ return accessWideners;
+ }
+
+ @Override
+ public void process(File file) {
+ Preconditions.checkArgument(!isEmpty());
+
+ AccessWidener accessWidener = createAccessWidener();
+ AccessWidenerTransformer transformer = new AccessWidenerTransformer(project.getLogger(), accessWidener);
+ transformer.apply(file);
+ }
+
+ private AccessWidener createAccessWidener() {
+ AccessWidener accessWidener = new AccessWidener();
+ // For other mods, only consider transitive AWs and remap from intermediary->named
+ TinyRemapper tinyRemapper = createTinyRemapper();
+
+ try {
+ AccessWidenerRemapper remappingVisitor = new AccessWidenerRemapper(
+ accessWidener,
+ tinyRemapper.getRemapper(),
+ MappingsNamespace.INTERMEDIARY.toString(),
+ MappingsNamespace.NAMED.toString()
+ );
+ AccessWidenerReader transitiveReader = new AccessWidenerReader(new TransitiveOnlyFilter(remappingVisitor));
+
+ for (AccessWidenerFile accessWidenerFile : transitiveAccessWideners) {
+ project.getLogger().info("Reading transitive access widener from {}", accessWidenerFile.modId());
+ transitiveReader.read(accessWidenerFile.content());
+ }
+ } finally {
+ tinyRemapper.finish();
+ }
+
+ return accessWidener;
+ }
+
+ private TinyRemapper createTinyRemapper() {
+ try {
+ TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, "intermediary", "named");
+
+ tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project));
+ tinyRemapper.readClassPath(extension.getMinecraftMappedProvider().getIntermediaryJar().toPath());
+
+ return tinyRemapper;
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create tiny remapper for intermediary->named", e);
+ }
+ }
+
+ @Override
+ public boolean isInvalid(File file) {
+ // The hash is handled by getId()
+ return false;
+ }
+
+ private static class TransitiveDetectorVisitor implements AccessWidenerVisitor {
+ private boolean transitive = false;
+
+ @Override
+ public void visitClass(String name, AccessWidenerReader.AccessType access, boolean transitive) {
+ if (transitive) {
+ this.transitive = true;
+ }
+ }
+
+ @Override
+ public void visitMethod(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) {
+ if (transitive) {
+ this.transitive = true;
+ }
+ }
+
+ @Override
+ public void visitField(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) {
+ if (transitive) {
+ this.transitive = true;
+ }
+ }
+
+ public static boolean isTransitive(byte[] content) {
+ if (AccessWidenerReader.readVersion(content) < 2) {
+ // Transitive AWs are only in v2 or higher, so we can save parsing the file to find out...
+ return false;
+ }
+
+ TransitiveDetectorVisitor transitiveDetector = new TransitiveDetectorVisitor();
+ new AccessWidenerReader(transitiveDetector).read(content);
+ return transitiveDetector.transitive;
+ }
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java
new file mode 100644
index 00000000..c96e8141
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerMappingsProcessor.java
@@ -0,0 +1,147 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.accesswidener;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+import org.gradle.api.logging.Logger;
+
+import net.fabricmc.accesswidener.AccessWidenerReader;
+import net.fabricmc.accesswidener.AccessWidenerVisitor;
+import net.fabricmc.accesswidener.TransitiveOnlyFilter;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
+import net.fabricmc.mappingio.MappingReader;
+import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
+import net.fabricmc.mappingio.format.Tiny2Writer;
+import net.fabricmc.mappingio.tree.MappingTree;
+import net.fabricmc.mappingio.tree.MemoryMappingTree;
+
+public final class TransitiveAccessWidenerMappingsProcessor {
+ private TransitiveAccessWidenerMappingsProcessor() {
+ }
+
+ public static void process(Path inputMappings, Path outputMappings, List<AccessWidenerFile> accessWideners, Logger logger) {
+ MemoryMappingTree mappingTree = new MemoryMappingTree();
+
+ try (Reader reader = Files.newBufferedReader(inputMappings, StandardCharsets.UTF_8)) {
+ MappingReader.read(reader, new MappingSourceNsSwitch(mappingTree, MappingsNamespace.INTERMEDIARY.toString()));
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to read mappings", e);
+ }
+
+ if (!MappingsNamespace.INTERMEDIARY.toString().equals(mappingTree.getSrcNamespace())) {
+ throw new IllegalStateException("Mapping tree must have intermediary src mappings not " + mappingTree.getSrcNamespace());
+ }
+
+ for (AccessWidenerFile accessWidener : accessWideners) {
+ MappingCommentVisitor mappingCommentVisitor = new MappingCommentVisitor(accessWidener.modId(), mappingTree, logger);
+ AccessWidenerReader accessWidenerReader = new AccessWidenerReader(new TransitiveOnlyFilter(mappingCommentVisitor));
+ accessWidenerReader.read(accessWidener.content());
+ }
+
+ try (Writer writer = Files.newBufferedWriter(outputMappings, StandardCharsets.UTF_8)) {
+ Tiny2Writer tiny2Writer = new Tiny2Writer(writer, false);
+ mappingTree.accept(new MappingSourceNsSwitch(tiny2Writer, MappingsNamespace.NAMED.toString()));
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write mappings", e);
+ }
+ }
+
+ private static record MappingCommentVisitor(String modId, MemoryMappingTree mappingTree, Logger logger) implements AccessWidenerVisitor {
+ @Override
+ public void visitClass(String name, AccessWidenerReader.AccessType access, boolean transitive) {
+ MappingTree.ClassMapping classMapping = mappingTree.getClass(name);
+
+ if (classMapping == null) {
+ logger.warn("Failed to find class ({}) to mark access widened by mod ({})", name, modId());
+ return;
+ }
+
+ classMapping.setComment(appendComment(classMapping.getComment(), access));
+ }
+
+ @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);
+
+ MappingTree.ClassMapping classMapping = mappingTree.getClass(owner);
+
+ if (classMapping == null) {
+ logger.warn("Failed to find class ({}) to mark access widened by mod ({})", owner, modId());
+ return;
+ }
+
+ MappingTree.MethodMapping methodMapping = classMapping.getMethod(name, descriptor);
+
+ if (methodMapping == null) {
+ logger.warn("Failed to find method ({}) in ({}) to mark access widened by mod ({})", name, owner, modId());
+ return;
+ }
+
+ methodMapping.setComment(appendComment(methodMapping.getComment(), access));
+ }
+
+ @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(owner);
+
+ if (classMapping == null) {
+ logger.warn("Failed to find class ({}) to mark access widened by mod ({})", name, modId());
+ return;
+ }
+
+ MappingTree.FieldMapping fieldMapping = classMapping.getField(name, descriptor);
+
+ if (fieldMapping == null) {
+ logger.warn("Failed to find field ({}) in ({}) to mark access widened by mod ({})", name, owner, modId());
+ return;
+ }
+
+ fieldMapping.setComment(appendComment(fieldMapping.getComment(), access));
+ }
+
+ private String appendComment(String comment, AccessWidenerReader.AccessType access) {
+ if (comment == null) {
+ comment = "";
+ } else {
+ comment += "\n";
+ }
+
+ comment += "Access widened by %s to %s".formatted(modId(), access);
+
+ return comment;
+ }
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java
index 46d2e2ae..54a7903f 100644
--- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java
+++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java
@@ -24,13 +24,9 @@
package net.fabricmc.loom.configuration.mods;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -56,19 +52,19 @@ import org.zeroturnaround.zip.ZipUtil;
import org.zeroturnaround.zip.transform.StringZipEntryTransformer;
import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
-import net.fabricmc.accesswidener.AccessWidener;
import net.fabricmc.accesswidener.AccessWidenerReader;
import net.fabricmc.accesswidener.AccessWidenerRemapper;
import net.fabricmc.accesswidener.AccessWidenerWriter;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.LoggerFilter;
-import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
+import net.fabricmc.loom.util.TinyRemapperHelper;
import net.fabricmc.loom.util.srg.AtRemapper;
import net.fabricmc.loom.util.srg.CoreModClassRemapper;
import net.fabricmc.mapping.tree.TinyTree;
@@ -107,7 +103,7 @@ public class ModProcessor {
private static void stripNestedJars(File file) {
if (!ZipUtil.containsEntry(file, "fabric.mod.json")) return;
// Strip out all contained jar info as we dont want loader to try and load the jars contained in dev.
- ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[] {(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
+ ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[]{(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
@Override
protected String transform(ZipEntry zipEntry, String input) {
JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class);
@@ -117,29 +113,28 @@ public class ModProcessor {
}))});
}
+ /**
+ * Remap another mod's access widener from intermediary to named, so that loader can apply it in our dev-env.
+ */
private static byte[] remapAccessWidener(byte[] input, Remapper remapper) {
- try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(input), StandardCharsets.UTF_8))) {
- AccessWidener accessWidener = new AccessWidener();
- AccessWidenerReader accessWidenerReader = new AccessWidenerReader(accessWidener);
- accessWidenerReader.read(bufferedReader);
-
- AccessWidenerRemapper accessWidenerRemapper = new AccessWidenerRemapper(accessWidener, remapper, "named");
- AccessWidener remapped = accessWidenerRemapper.remap();
- AccessWidenerWriter accessWidenerWriter = new AccessWidenerWriter(remapped);
-
- try (StringWriter writer = new StringWriter()) {
- accessWidenerWriter.write(writer);
- return writer.toString().getBytes(StandardCharsets.UTF_8);
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ int version = AccessWidenerReader.readVersion(input);
+
+ AccessWidenerWriter writer = new AccessWidenerWriter(version);
+ AccessWidenerRemapper awRemapper = new AccessWidenerRemapper(
+ writer,
+ remapper,
+ MappingsNamespace.INTERMEDIARY.toString(),
+ MappingsNamespace.NAMED.toString()
+ );
+ AccessWidenerReader reader = new AccessWidenerReader(awRemapper);
+ reader.read(input);
+ return writer.write();
}
private static void remapJars(Project project, List<ModDependencyInfo> processList) throws IOException {
LoomGradleExtension extension = LoomGradleExtension.get(project);
- String fromM = extension.isForge() ? "srg" : "intermediary";
- String toM = "named";
+ String fromM = extension.isForge() ? MappingsNamespace.SRG.toString() : MappingsNamespace.INTERMEDIARY.toString();
+ String toM = MappingsNamespace.NAMED.toString();
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
@@ -158,7 +153,7 @@ public class ModProcessor {
TinyRemapper remapper = TinyRemapper.newRemapper()
.logger(project.getLogger()::lifecycle)
.logUnknownInvokeDynamic(false)
- .withMappings(TinyRemapperMappingsHelper.create(mappings, fromM, toM, false))
+ .withMappings(TinyRemapperHelper.create(mappings, fromM, toM, false))
.renameInvalidLocals(false)
.build();
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java
index e62e9e91..0d780f16 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java
@@ -25,12 +25,15 @@
package net.fabricmc.loom.configuration.providers.mappings;
import java.io.File;
+import java.nio.file.Path;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
+import org.gradle.api.artifacts.Dependency;
import org.gradle.api.logging.Logger;
import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
public class GradleMappingContext implements MappingContext {
@@ -45,9 +48,14 @@ public class GradleMappingContext implements MappingContext {
}
@Override
- public File mavenFile(String mavenNotation) {
- Configuration configuration = project.getConfigurations().detachedConfiguration(project.getDependencies().create(mavenNotation));
- return configuration.getSingleFile();
+ public Path resolveDependency(Dependency dependency) {
+ Configuration configuration = project.getConfigurations().detachedConfiguration(dependency);
+ return configuration.getSingleFile().toPath();
+ }
+
+ @Override
+ public Path resolveMavenDependency(String mavenNotation) {
+ return resolveDependency(project.getDependencies().create(mavenNotation));
}
@Override
@@ -61,8 +69,8 @@ public class GradleMappingContext implements MappingContext {
}
@Override
- public File workingDirectory(String name) {
- return new File(minecraftProvider().dir("layered/working_dir/" + workingDirName), name);
+ public Path workingDirectory(String name) {
+ return new File(minecraftProvider().dir("layered/working_dir/" + workingDirName), name).toPath();
}
@Override
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java
index 2e47af39..cb09d71f 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java
@@ -26,6 +26,8 @@ package net.fabricmc.loom.configuration.providers.mappings;
import java.util.List;
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
+
public record LayeredMappingSpec(List<MappingsSpec<?>> layers) {
public String getVersion() {
// TODO something better?
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilderImpl.java
index 3524b7e6..fdd14127 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilderImpl.java
@@ -31,13 +31,17 @@ import java.util.List;
import org.gradle.api.Action;
import org.jetbrains.annotations.Nullable;
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
+import net.fabricmc.loom.api.mappings.layered.spec.ParchmentMappingsSpecBuilder;
import net.fabricmc.loom.api.LoomGradleExtensionAPI;
import net.fabricmc.loom.configuration.providers.mappings.crane.CraneMappingsSpec;
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec;
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec;
-import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilder;
+import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilderImpl;
-public class LayeredMappingSpecBuilder {
+public class LayeredMappingSpecBuilderImpl implements LayeredMappingSpecBuilder {
private final List<MappingsSpec<?>> layers = new LinkedList<>();
@Nullable
private final LoomGradleExtensionAPI extension;
@@ -46,6 +50,9 @@ public class LayeredMappingSpecBuilder {
this.extension = extension;
}
+ @Override
+ public LayeredMappingSpecBuilder addLayer(MappingsSpec<?> mappingSpec) {
+ layers.add(mappingSpec);
public LayeredMappingSpecBuilder officialMojangMappings() {
layers.add(new MojangMappingsSpec(() -> extension != null && extension.isSilentMojangMappingsLicenseEnabled()));
return this;
@@ -56,11 +63,16 @@ public class LayeredMappingSpecBuilder {
return this;
}
- public LayeredMappingSpecBuilder parchment(String mavenNotation, Action<ParchmentMappingsSpecBuilder> action) {
- ParchmentMappingsSpecBuilder builder = ParchmentMappingsSpecBuilder.builder(mavenNotation);
+ @Override
+ public LayeredMappingSpecBuilder officialMojangMappings() {
+ return addLayer(new MojangMappingsSpec());
+ }
+
+ @Override
+ public LayeredMappingSpecBuilder parchment(Object object, Action<ParchmentMappingsSpecBuilder> action) {
+ ParchmentMappingsSpecBuilderImpl builder = ParchmentMappingsSpecBuilderImpl.builder(FileSpec.create(object));
action.execute(builder);
- layers.add(builder.build());
- return this;
+ return addLayer(builder.build());
}
public LayeredMappingSpecBuilder crane(String mavenNotation) {
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java
index ff48a5cf..84c9370d 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java
@@ -54,6 +54,8 @@ import org.zeroturnaround.zip.ZipEntrySource;
import org.zeroturnaround.zip.ZipUtil;
import net.fabricmc.loom.LoomGradlePlugin;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.mappingio.adapter.MappingDstNsReorder;
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
import net.fabricmc.mappingio.format.Tiny2Writer;
@@ -87,8 +89,8 @@ public class LayeredMappingsDependency extends AbstractModuleDependency implemen
try (Writer writer = new StringWriter()) {
Tiny2Writer tiny2Writer = new Tiny2Writer(writer, false);
- MappingDstNsReorder nsReorder = new MappingDstNsReorder(tiny2Writer, Collections.singletonList(MappingNamespace.NAMED.stringValue()));
- MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingNamespace.INTERMEDIARY.stringValue(), true);
+ MappingDstNsReorder nsReorder = new MappingDstNsReorder(tiny2Writer, Collections.singletonList(MappingsNamespace.NAMED.toString()));
+ MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true);
mappings.accept(nsSwitch);
Files.deleteIfExists(mappingsFile);
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java
index a3fa5294..b14902c5 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java
@@ -28,6 +28,10 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.MappingLayer;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
@@ -55,7 +59,7 @@ public class LayeredMappingsProcessor {
visitedLayers.add(layer.getClass());
// We have to rebuild a new tree to work on when a layer doesnt merge into layered
- boolean rebuild = layer.getSourceNamespace() != MappingNamespace.NAMED;
+ boolean rebuild = layer.getSourceNamespace() != MappingsNamespace.NAMED;
MemoryMappingTree workingTree;
if (rebuild) {
@@ -63,7 +67,7 @@ public class LayeredMappingsProcessor {
// This can be null on the first layer
if (mappingTree.getSrcNamespace() != null) {
- var sourceNsSwitch = new MappingSourceNsSwitch(tempTree, layer.getSourceNamespace().stringValue());
+ var sourceNsSwitch = new MappingSourceNsSwitch(tempTree, layer.getSourceNamespace().toString());
mappingTree.accept(sourceNsSwitch);
}
@@ -80,7 +84,7 @@ public class LayeredMappingsProcessor {
if (rebuild) {
mappingTree = new MemoryMappingTree();
- workingTree.accept(new MappingSourceNsSwitch(mappingTree, MappingNamespace.NAMED.stringValue()));
+ workingTree.accept(new MappingSourceNsSwitch(mappingTree, MappingsNamespace.NAMED.toString()));
}
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsCache.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsCache.java
deleted file mode 100644
index 29eb5949..00000000
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsCache.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2016-2020 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
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.configuration.providers.mappings;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.lang.ref.SoftReference;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.fabricmc.loom.util.StaticPathWatcher;
-import net.fabricmc.mapping.tree.TinyMappingFactory;
-import net.fabricmc.mapping.tree.TinyTree;
-
-public final class MappingsCache {
- public static final MappingsCache INSTANCE = new MappingsCache();
-
- private final Map<Path, SoftReference<TinyTree>> mappingsCache = new HashMap<>();
-
- // TODO: loom doesn't actually use new mappings when the mappings change until the gradle daemons are stopped
- public TinyTree get(Path mappingsPath) throws IOException {
- mappingsPath = mappingsPath.toAbsolutePath();
-
- if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) {
- mappingsCache.remove(mappingsPath);
- }
-
- SoftReference<TinyTree> ref = mappingsCache.get(mappingsPath);
-
- if (ref != null && ref.get() != null) {
- return ref.get();
- } else {
- try (BufferedReader reader = Files.newBufferedReader(mappingsPath)) {
- TinyTree mappings = TinyMappingFactory.loadWithDetection(reader);
- ref = new SoftReference<>(mappings);
- mappingsCache.put(mappingsPath, ref);
- return mappings;
- }
- }
- }
-
- public void invalidate() {
- mappingsCache.clear();
- }
-}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java
index 902b4cff..f08bf774 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java
@@ -40,6 +40,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.function.Consumer;
import com.google.common.base.Stopwatch;
@@ -54,8 +55,10 @@ import org.zeroturnaround.zip.ZipUtil;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.DependencyProvider;
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
+import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerJarProcessor;
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider;
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
@@ -69,10 +72,10 @@ import net.fabricmc.loom.util.srg.MCPReader;
import net.fabricmc.loom.util.srg.SrgMerger;
import net.fabricmc.loom.util.srg.SrgNamedWriter;
import net.fabricmc.mapping.reader.v2.TinyMetadata;
-import net.fabricmc.mapping.reader.v2.TinyV2Factory;
-import net.fabricmc.mapping.tree.TinyTree;
+import net.fabricmc.mappingio.MappingReader;
import net.fabricmc.mappingio.adapter.MappingNsCompleter;
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
+import net.fabricmc.mappingio.format.MappingFormat;
import net.fabricmc.mappingio.format.Tiny2Reader;
import net.fabricmc.mappingio.format.Tiny2Writer;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
@@ -103,13 +106,14 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
private Path unpickDefinitions;
private boolean hasUnpickDefinitions;
private UnpickMetadata unpickMetadata;
+ private MemoryMappingTree mappingTree;
public MappingsProviderImpl(Project project) {
super(project);
}
- public TinyTree getMappings() throws IOException {
- return MappingsCache.INSTANCE.get(tinyMappings);
+ public MemoryMappingTree getMappings() throws IOException {
+ return Objects.requireNonNull(mappingTree, "Cannot get mappings before they have been read");
}
public TinyTree getMappingsWithSrg() throws IOException {
@@ -148,6 +152,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
patchedProvider.provide(dependency, postPopulationScheduler);
}
+ mappingTree = readMappings();
manipulateMappings(mappingsJar.toPath());
if (getExtension().shouldGenerateSrgTiny()) {
@@ -197,6 +202,14 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
extension.getGameJarProcessors().add(new AccessWidenerJarProcessor(getProject()));
}
+ if (extension.getEnableTransitiveAccessWideners().get()) {
+ TransitiveAccessWidenerJarProcessor transitiveAccessWidenerJarProcessor = new TransitiveAccessWidenerJarProcessor(getProject());
+
+ if (!transitiveAccessWidenerJarProcessor.isEmpty()) {
+ extension.getGameJarProcessors().add(transitiveAccessWidenerJarProcessor);
+ }
+ }
+
extension.getAccessWidenerPath().finalizeValue();
extension.getGameJarProcessors().finalizeValue();
JarProcessorManager processorManager = new JarProcessorManager(extension.getGameJarProcessors().get());
@@ -305,6 +318,12 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
}
}
+ private MemoryMappingTree readMappings() throws IOException {
+ MemoryMappingTree mappingTree = new MemoryMappingTree();
+ MappingReader.read(tinyMappings, mappingTree);
+ return mappingTree;
+ }
+
private void readAndMergeMCP(Path mcpJar, Consumer<Runnable> postPopulationScheduler) throws Exception {
Path intermediaryTinyPath = getIntermediaryTiny();
SrgProvider provider = getExtension().getSrgProvider();
@@ -334,9 +353,8 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
private static boolean areMappingsV2(Path path) throws IOException {
try (BufferedReader reader = Files.newBufferedReader(path)) {
- TinyV2Factory.readMetadata(reader);
- return true;
- } catch (IllegalArgumentException | NoSuchFileException e) {
+ return MappingReader.detectFormat(reader) == MappingFormat.TINY_2;
+ } catch (NoSuchFileException e) {
// TODO: just check the mappings version when Parser supports V1 in readMetadata()
return false;
}
@@ -354,10 +372,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
private static boolean doesJarContainV2Mappings(Path path) throws IOException {
try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) {
try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) {
- TinyV2Factory.readMetadata(reader);
- return true;
- } catch (IllegalArgumentException e) {
- return false;
+ return MappingReader.detectFormat(reader) == MappingFormat.TINY_2;
}
}
}
@@ -411,7 +426,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
project.getLogger().info(":merging mappings");
MemoryMappingTree tree = new MemoryMappingTree();
- MappingSourceNsSwitch sourceNsSwitch = new MappingSourceNsSwitch(tree, MappingNamespace.OFFICIAL.stringValue());
+ MappingSourceNsSwitch sourceNsSwitch = new MappingSourceNsSwitch(tree, MappingsNamespace.OFFICIAL.toString());
readIntermediaryTree().accept(sourceNsSwitch);
try (BufferedReader reader = Files.newBufferedReader(from, StandardCharsets.UTF_8)) {
@@ -427,7 +442,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
private MemoryMappingTree readIntermediaryTree() throws IOException {
MemoryMappingTree tree = new MemoryMappingTree();
- MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true);
+ MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingsNamespace.NAMED.toString(), MappingsNamespace.INTERMEDIARY.toString()), true);
try (BufferedReader reader = Files.newBufferedReader(getIntermediaryTiny(), StandardCharsets.UTF_8)) {
Tiny2Reader.read(reader, nsCompleter);
@@ -451,7 +466,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
runCommand(command, intermediaryMappings.toAbsolutePath().toString(),
yarnMappings.toAbsolutePath().toString(),
newMergedMappings.toAbsolutePath().toString(),
- "intermediary", "official");
+ MappingsNamespace.INTERMEDIARY.toString(), MappingsNamespace.OFFICIAL.toString());
} catch (Exception e) {
throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString()
+ " with mappings from " + yarnMappings, e);
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java
index abfc3685..83b3c5da 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java
@@ -32,22 +32,22 @@ import java.nio.file.Files;
import java.util.Collections;
import java.util.function.Supplier;
-import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
-import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
+import net.fabricmc.loom.api.mappings.layered.MappingLayer;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.mappingio.MappingVisitor;
import net.fabricmc.mappingio.adapter.MappingNsCompleter;
import net.fabricmc.mappingio.format.Tiny2Reader;
public record IntermediaryMappingLayer(Supplier<File> tinyFile) implements MappingLayer {
@Override
- public MappingNamespace getSourceNamespace() {
- return MappingNamespace.OFFICIAL;
+ public MappingsNamespace getSourceNamespace() {
+ return MappingsNamespace.OFFICIAL;
}
@Override
public void visit(MappingVisitor mappingVisitor) throws IOException {
// Populate named with intermediary and add Add a "named" namespace
- MappingNsCompleter nsCompleter = new MappingNsCompleter(mappingVisitor, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true);
+ MappingNsCompleter nsCompleter = new MappingNsCompleter(mappingVisitor, Collections.singletonMap(MappingsNamespace.NAMED.toString(), MappingsNamespace.INTERMEDIARY.toString()), true);
try (BufferedReader reader = Files.newBufferedReader(tinyFile().get().toPath(), StandardCharsets.UTF_8)) {
Tiny2Reader.read(reader, nsCompleter);
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java
index 4daf64f5..95277f52 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java
@@ -24,8 +24,8 @@
package net.fabricmc.loom.configuration.providers.mappings.intermediary;
-import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
-import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
public record IntermediaryMappingsSpec() implements MappingsSpec<IntermediaryMappingLayer> {
@Override
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java
index 4b4d407b..ebf5d063 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java
@@ -25,7 +25,6 @@
package net.fabricmc.loom.configuration.providers.mappings.mojmap;
import java.io.BufferedReader;
-import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@@ -35,8 +34,8 @@ import java.util.List;
import org.gradle.api.logging.Logger;
-import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
-import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
+import net.fabricmc.loom.api.mappings.layered.MappingLayer;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingLayer;
import net.fabricmc.loom.util.HashedDownloadUtil;
@@ -47,33 +46,33 @@ import net.fabricmc.mappingio.format.ProGuardReader;
public record MojangMappingLayer(String minecraftVersion,
MinecraftVersionMeta.Download clientDownload,
MinecraftVersionMeta.Download serverDownload,
- File workingDir,
+ Path workingDir,
Logger logger,
MojangMappingsSpec.SilenceLicenseOption silenceLicense) implements MappingLayer {
@Override
public void visit(MappingVisitor mappingVisitor) throws IOException {
- var clientMappings = new File(workingDir(), "%s.client.txt".formatted(minecraftVersion));
- var serverMappings = new File(workingDir(), "%s.server.txt".formatted(minecraftVersion));
+ Path clientMappings = workingDir().resolve("%s.client.txt".formatted(minecraftVersion));
+ Path serverMappings = workingDir().resolve("%s.server.txt".formatted(minecraftVersion));
download(clientMappings, serverMappings);
if (!silenceLicense.isSilent()) {
- printMappingsLicense(clientMappings.toPath());
+ printMappingsLicense(clientMappings);
}
// Make official the source namespace
- MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingVisitor, MappingNamespace.OFFICIAL.stringValue());
+ MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingVisitor, MappingsNamespace.OFFICIAL.toString());
- try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings.toPath(), StandardCharsets.UTF_8);
- BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings.toPath(), StandardCharsets.UTF_8)) {
- ProGuardReader.read(clientBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch);
- ProGuardReader.read(serverBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch);
+ try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8);
+ BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings, StandardCharsets.UTF_8)) {
+ ProGuardReader.read(clientBufferedReader, MappingsNamespace.NAMED.toString(), MappingsNamespace.OFFICIAL.toString(), nsSwitch);
+ ProGuardReader.read(serverBufferedReader, MappingsNamespace.NAMED.toString(), MappingsNamespace.OFFICIAL.toString(), nsSwitch);
}
}
- private void download(File clientMappings, File serverMappings) throws IOException {
- HashedDownloadUtil.downloadIfInvalid(new URL(clientDownload().url()), clientMappings, clientDownload().sha1(), logger(), false);
- HashedDownloadUtil.downloadIfInvalid(new URL(serverDownload().url()), serverMappings, serverDownload().sha1(), logger(), false);
+ private void download(Path clientMappings, Path serverMappings) throws IOException {
+ HashedDownloadUtil.downloadIfInvalid(new URL(clientDownload().url()), clientMappings.toFile(), clientDownload().sha1(), logger(), false);
+ HashedDownloadUtil.downloadIfInvalid(new URL(serverDownload().url()), serverMappings.toFile(), serverDownload().sha1(), logger(), false);
}
private void printMappingsLicense(Path clientMappings) {
@@ -95,8 +94,8 @@ public record MojangMappingLayer(String minecraftVersion,
}
@Override
- public MappingNamespace getSourceNamespace() {
- return MappingNamespace.OFFICIAL;
+ public MappingsNamespace getSourceNamespace() {
+ return MappingsNamespace.OFFICIAL;
}
@Override
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java
index f304530f..9654ddca 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java
@@ -24,8 +24,8 @@
package net.fabricmc.loom.configuration.providers.mappings.mojmap;
-import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
-import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
+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;
public record MojangMappingsSpec(SilenceLicenseOption silenceLicense) implements MappingsSpec<MojangMappingLayer> {
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java
index 448a33a1..f6b602e8 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java
@@ -24,19 +24,19 @@
package net.fabricmc.loom.configuration.providers.mappings.parchment;
-import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.nio.file.Path;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import net.fabricmc.loom.LoomGradlePlugin;
-import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
-import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
+import net.fabricmc.loom.api.mappings.layered.MappingLayer;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.mappingio.MappingVisitor;
-public record ParchmentMappingLayer(File parchmentFile, boolean removePrefix) implements MappingLayer {
+public record ParchmentMappingLayer(Path parchmentFile, boolean removePrefix) implements MappingLayer {
private static final String PARCHMENT_DATA_FILE_NAME = "parchment.json";
@Override
@@ -47,11 +47,11 @@ public record ParchmentMappingLayer(File parchmentFile, boolean removePrefix) im
mappingVisitor = new ParchmentPrefixStripingMappingVisitor(mappingVisitor);
}
- parchmentData.visit(mappingVisitor, MappingNamespace.NAMED.stringValue());
+ parchmentData.visit(mappingVisitor, MappingsNamespace.NAMED.toString());
}
private ParchmentTreeV1 getParchmentData() throws IOException {
- try (var zipFile = new ZipFile(parchmentFile())) {
+ try (var zipFile = new ZipFile(parchmentFile().toFile())) {
ZipEntry zipFileEntry = zipFile.getEntry(PARCHMENT_DATA_FILE_NAME);
Objects.requireNonNull(zipFileEntry, "Could not find %s in parchment data file".formatted(PARCHMENT_DATA_FILE_NAME));
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java
index 2b3f48b2..5af9503f 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java
@@ -24,12 +24,13 @@
package net.fabricmc.loom.configuration.providers.mappings.parchment;
-import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
-import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec;
-public record ParchmentMappingsSpec(String mavenNotation, boolean removePrefix) implements MappingsSpec<ParchmentMappingLayer> {
+public record ParchmentMappingsSpec(FileSpec fileSpec, boolean removePrefix) implements MappingsSpec<ParchmentMappingLayer> {
@Override
public ParchmentMappingLayer createLayer(MappingContext context) {
- return new ParchmentMappingLayer(context.mavenFile(mavenNotation()), removePrefix());
+ return new ParchmentMappingLayer(fileSpec.get(context), removePrefix());
}
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilderImpl.java
index 1fff3195..4830cad7 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilderImpl.java
@@ -24,25 +24,29 @@
package net.fabricmc.loom.configuration.providers.mappings.parchment;
-public class ParchmentMappingsSpecBuilder {
- private final String mavenNotation;
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+import net.fabricmc.loom.api.mappings.layered.spec.ParchmentMappingsSpecBuilder;
+
+public class ParchmentMappingsSpecBuilderImpl implements ParchmentMappingsSpecBuilder {
+ private final FileSpec fileSpec;
private boolean removePrefix;
- private ParchmentMappingsSpecBuilder(String mavenNotation) {
- this.mavenNotation = mavenNotation;
+ private ParchmentMappingsSpecBuilderImpl(FileSpec fileSpec) {
+ this.fileSpec = fileSpec;
}
- public static ParchmentMappingsSpecBuilder builder(String depNotation) {
- return new ParchmentMappingsSpecBuilder(depNotation);
+ public static ParchmentMappingsSpecBuilderImpl builder(FileSpec fileSpec) {
+ return new ParchmentMappingsSpecBuilderImpl(fileSpec);
}
+ @Override
public ParchmentMappingsSpecBuilder setRemovePrefix(boolean removePrefix) {
this.removePrefix = removePrefix;
return this;
}
public ParchmentMappingsSpec build() {
- return new ParchmentMappingsSpec(mavenNotation, removePrefix);
+ return new ParchmentMappingsSpec(fileSpec, removePrefix);
}
}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/DependencyFileSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/DependencyFileSpec.java
new file mode 100644
index 00000000..99c9d7d3
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/DependencyFileSpec.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.providers.mappings.utils;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Set;
+
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.SelfResolvingDependency;
+
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+
+public record DependencyFileSpec(Dependency dependency) implements FileSpec {
+ @Override
+ public Path get(MappingContext context) {
+ if (dependency instanceof SelfResolvingDependency selfResolvingDependency) {
+ Set<File> files = selfResolvingDependency.resolve();
+
+ if (files.size() == 0) {
+ throw new RuntimeException("SelfResolvingDependency (%s) resolved no files".formatted(selfResolvingDependency.toString()));
+ } else if (files.size() > 1) {
+ throw new RuntimeException("SelfResolvingDependency (%s) resolved too many files (%d) only 1 is expected".formatted(selfResolvingDependency.toString(), files.size()));
+ }
+
+ return files.iterator().next().toPath();
+ }
+
+ return context.resolveDependency(dependency);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(dependency.getGroup(), dependency.getName(), dependency.getVersion());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DependencyFileSpec other) {
+ return other.dependency().contentEquals(this.dependency());
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/LocalFileSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/LocalFileSpec.java
new file mode 100644
index 00000000..d870d691
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/LocalFileSpec.java
@@ -0,0 +1,63 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.providers.mappings.utils;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Objects;
+
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+import net.fabricmc.loom.util.Checksum;
+
+public class LocalFileSpec implements FileSpec {
+ private final File file;
+ private final int hash;
+
+ public LocalFileSpec(File file) {
+ this.file = file;
+ this.hash = calculateHashCode();
+ }
+
+ private int calculateHashCode() {
+ if (!file.exists()) {
+ throw new RuntimeException("Could not find %s, it must be present at spec creation time to calculate mappings hash".formatted(file.getAbsolutePath()));
+ }
+
+ // Use the file hash as part of the spec, this means if the input file changes the mappings will be re-generated.
+ return Objects.hash(Arrays.hashCode(Checksum.sha256(file)), file.getAbsolutePath());
+ }
+
+ @Override
+ public Path get(MappingContext context) {
+ return file.toPath();
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/MavenFileSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/MavenFileSpec.java
new file mode 100644
index 00000000..f833fe15
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/MavenFileSpec.java
@@ -0,0 +1,37 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.configuration.providers.mappings.utils;
+
+import java.nio.file.Path;
+
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec;
+import net.fabricmc.loom.api.mappings.layered.MappingContext;
+
+public record MavenFileSpec(String dependencyNotation) implements FileSpec {
+ @Override
+ public Path get(MappingContext context) {
+ return context.resolveMavenDependency(dependencyNotation);
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java
index f80e10f7..757d0355 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java
@@ -46,6 +46,7 @@ import dev.architectury.tinyremapper.TinyRemapper;
import org.gradle.api.Project;
import org.jetbrains.annotations.Nullable;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.DependencyProvider;
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
@@ -56,7 +57,7 @@ import net.fabricmc.loom.util.DownloadUtil;
import net.fabricmc.loom.util.FileSystemUtil;
import net.fabricmc.loom.util.OperatingSystem;
import net.fabricmc.loom.util.ThreadingUtils;
-import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
+import net.fabricmc.loom.util.TinyRemapperHelper;
import net.fabricmc.loom.util.srg.AtRemapper;
import net.fabricmc.loom.util.srg.CoreModClassRemapper;
import net.fabricmc.loom.util.srg.InnerClassRemapper;
@@ -251,7 +252,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
assetsOut(inputForge, forgeAssets);
}
- remap(remapper, vanilla, forge, "official");
+ remap(remapper, vanilla, forge, MappingsNamespace.OFFICIAL.toString());
}
public static class Info {
@@ -273,9 +274,9 @@ public class MinecraftMappedProvider extends DependencyProvider {
public void remap(TinyRemapper remapper, Info vanilla, @Nullable Info forge, String fromM) throws IOException {
Set<String> classNames = getExtension().isForge() ? InnerClassRemapper.readClassNames(vanilla.input) : null;
- for (String toM : getExtension().isForge() ? Arrays.asList("intermediary", "srg", "named") : Arrays.asList("intermediary", "named")) {
- Path output = "named".equals(toM) ? vanilla.outputMapped : "srg".equals(toM) ? vanilla.outputSrg : vanilla.outputIntermediary;
- Path outputForge = forge == null ? null : "named".equals(toM) ? forge.outputMapped : "srg".equals(toM) ? forge.outputSrg : forge.outputIntermediary;
+ for (String toM : getExtension().isForge() ? Arrays.asList(MappingsNamespace.INTERMEDIARY.toString(), MappingsNamespace.SRG.toString(), MappingsNamespace.NAMED.toString()) : Arrays.asList(MappingsNamespace.INTERMEDIARY.toString(), MappingsNamespace.NAMED.toString())) {
+ Path output = MappingsNamespace.NAMED.toString().equals(toM) ? vanilla.outputMapped : MappingsNamespace.SRG.toString().equals(toM) ? vanilla.outputSrg : vanilla.outputIntermediary;
+ Path outputForge = forge == null ? null : MappingsNamespace.NAMED.toString().equals(toM) ? forge.outputMapped : MappingsNamespace.SRG.toString().equals(toM) ? forge.outputSrg : forge.outputIntermediary;
InputTag vanillaTag = remapper.createInputTag();
InputTag forgeTag = remapper.createInputTag();
Stopwatch stopwatch = Stopwatch.createStarted();
@@ -294,6 +295,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
OutputRemappingHandler.remap(remapper, forge.assets, outputForge, null, forgeTag);
}
+ // TODO TinyRemapperHelper
getProject().getLogger().lifecycle(":remapped minecraft (TinyRemapper, " + fromM + " -> " + toM + ") in " + stopwatch);
remapper.removeInput();
diff --git a/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java b/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java
index c2cb4d06..7e500301 100644
--- a/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java
+++ b/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java
@@ -126,12 +126,12 @@ public class LineNumberRemapper {
reader.accept(new LineNumberVisitor(Constants.ASM_VERSION, writer, lineMap.get(idx)), 0);
Files.write(dst, writer.toByteArray());
+ return FileVisitResult.CONTINUE;
}
}
- } else {
- Files.copy(file, dst, StandardCopyOption.REPLACE_EXISTING);
}
+ Files.copy(file, dst, StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
});
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/TinyJavadocProvider.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/TinyJavadocProvider.java
index dee4820e..f6f01e1f 100644
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/TinyJavadocProvider.java
+++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/TinyJavadocProvider.java
@@ -29,9 +29,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructField;
@@ -40,48 +38,29 @@ import org.jetbrains.java.decompiler.struct.StructRecordComponent;
import org.objectweb.asm.Opcodes;
import net.fabricmc.fernflower.api.IFabricJavadocProvider;
-import net.fabricmc.mapping.tree.ClassDef;
-import net.fabricmc.mapping.tree.FieldDef;
-import net.fabricmc.mapping.tree.MethodDef;
-import net.fabricmc.mapping.tree.ParameterDef;
-import net.fabricmc.mapping.tree.TinyMappingFactory;
-import net.fabricmc.mapping.tree.TinyTree;
-import net.fabricmc.mappings.EntryTriple;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
+import net.fabricmc.mappingio.MappingReader;
+import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
+import net.fabricmc.mappingio.tree.MappingTree;
+import net.fabricmc.mappingio.tree.MemoryMappingTree;
public class TinyJavadocProvider implements IFabricJavadocProvider {
- private final Map<String, ClassDef> classes = new HashMap<>();
- private final Map<EntryTriple, FieldDef> fields = new HashMap<>();
- private final Map<EntryTriple, MethodDef> methods = new HashMap<>();
-
- private final String namespace = "named";
+ private final MappingTree mappingTree;
public TinyJavadocProvider(File tinyFile) {
- final TinyTree mappings = readMappings(tinyFile);
-
- for (ClassDef classDef : mappings.getClasses()) {
- final String className = classDef.getName(namespace);
- classes.put(className, classDef);
-
- for (FieldDef fieldDef : classDef.getFields()) {
- fields.put(new EntryTriple(className, fieldDef.getName(namespace), fieldDef.getDescriptor(namespace)), fieldDef);
- }
-
- for (MethodDef methodDef : classDef.getMethods()) {
- methods.put(new EntryTriple(className, methodDef.getName(namespace), methodDef.getDescriptor(namespace)), methodDef);
- }
- }
+ mappingTree = readMappings(tinyFile);
}
@Override
public String getClassDoc(StructClass structClass) {
- ClassDef classDef = classes.get(structClass.qualifiedName);
+ MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName);
- if (classDef == null) {
+ if (classMapping == null) {
return null;
}
if (!isRecord(structClass)) {
- return classDef.getComment();
+ return classMapping.getComment();
}
/**
@@ -91,30 +70,30 @@ public class TinyJavadocProvider implements IFabricJavadocProvider {
*/
List<String> parts = new ArrayList<>();
- if (classDef.getComment() != null) {
- parts.add(classDef.getComment());
+ if (classMapping.getComment() != null) {
+ parts.add(classMapping.getComment());
}
boolean addedParam = false;
for (StructRecordComponent component : structClass.getRecordComponents()) {
// The component will always match the field name and descriptor
- FieldDef fieldDef = fields.get(new EntryTriple(structClass.qualifiedName, component.getName(), component.getDescriptor()));
+ MappingTree.FieldMapping fieldMapping = classMapping.getField(component.getName(), component.getDescriptor());
- if (fieldDef == null) {
+ if (fieldMapping == null) {
continue;
}
- String comment = fieldDef.getComment();
+ String comment = fieldMapping.getComment();
if (comment != null) {
- if (!addedParam && classDef.getComment() != null) {
+ if (!addedParam && classMapping.getComment() != null) {
//Add a blank line before components when the class has a comment
parts.add("");
addedParam = true;
}
- parts.add(String.format("@param %s %s", fieldDef.getName(namespace), comment));
+ parts.add(String.format("@param %s %s", fieldMapping.getName(MappingsNamespace.NAMED.toString()), comment));
}
}
@@ -132,34 +111,47 @@ public class TinyJavadocProvider implements IFabricJavadocProvider {
return null;
}
- FieldDef fieldDef = fields.get(new EntryTriple(structClass.qualifiedName, structField.getName(), structField.getDescriptor()));
- return fieldDef != null ? fieldDef.getComment() : null;
+ MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName);
+
+ if (classMapping == null) {
+ return null;
+ }
+
+ MappingTree.FieldMapping fieldMapping = classMapping.getField(structField.getName(), structField.getDescriptor());
+
+ return fieldMapping != null ? fieldMapping.getComment() : null;
}
@Override
public String getMethodDoc(StructClass structClass, StructMethod structMethod) {
- MethodDef methodDef = methods.get(new EntryTriple(structClass.qualifiedName, structMethod.getName(), structMethod.getDescriptor()));
+ MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName);
+
+ if (classMapping == null) {
+ return null;
+ }
- if (methodDef != null) {
+ MappingTree.MethodMapping methodMapping = classMapping.getMethod(structMethod.getName(), structMethod.getDescriptor());
+
+ if (methodMapping != null) {
List<String> parts = new ArrayList<>();
- if (methodDef.getComment() != null) {
- parts.add(methodDef.getComment());
+ if (methodMapping.getComment() != null) {
+ parts.add(methodMapping.getComment());
}
boolean addedParam = false;
- for (ParameterDef param : methodDef.getParameters()) {
- String comment = param.getComment();
+ for (MappingTree.MethodArgMapping argMapping : methodMapping.getArgs()) {
+ String comment = argMapping.getComment();
if (comment != null) {
- if (!addedParam && methodDef.getComment() != null) {
+ if (!addedParam && methodMapping.getComment() != null) {
//Add a blank line before params when the method has a comment
parts.add("");
addedParam = true;
}
- parts.add(String.format("@param %s %s", param.getName(namespace), comment));
+ parts.add(String.format("@param %s %s", methodMapping.getName(MappingsNamespace.NAMED.toString()), comment));
}
}
@@ -173,9 +165,13 @@ public class TinyJavadocProvider implements IFabricJavadocProvider {
return null;
}
- private static TinyTree readMappings(File input) {
+ private static MappingTree readMappings(File input) {
try (BufferedReader reader = Files.newBufferedReader(input.toPath())) {
- return TinyMappingFactory.loadWithDetection(reader);
+ MemoryMappingTree mappingTree = new MemoryMappingTree();
+ MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingTree, MappingsNamespace.NAMED.toString());
+ MappingReader.read(reader, nsSwitch);
+
+ return mappingTree;
} catch (IOException e) {
throw new RuntimeException("Failed to read mappings", e);
}
diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java
index 4cbf8d23..4abb717b 100644
--- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java
+++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java
@@ -53,6 +53,7 @@ import org.gradle.api.tasks.SourceSet;
import net.fabricmc.loom.api.LoomGradleExtensionAPI;
import net.fabricmc.loom.api.MixinExtensionAPI;
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
+import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
import net.fabricmc.loom.api.ForgeExtensionAPI;
import net.fabricmc.loom.configuration.ide.RunConfig;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
@@ -61,7 +62,7 @@ import net.fabricmc.loom.configuration.launch.LaunchProviderSettings;
import net.fabricmc.loom.configuration.processors.JarProcessor;
import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext;
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec;
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
+import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl;
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency;
import net.fabricmc.loom.util.DeprecationHelper;
import net.fabricmc.loom.util.ModPlatform;
@@ -84,6 +85,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
protected final Property<Boolean> remapArchives;
protected final Property<String> customManifest;
protected final Property<Boolean> setupRemappedVariants;
+ protected final Property<Boolean> transitiveAccessWideners;
private final ModVersionParser versionParser;
@@ -122,6 +124,9 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
this.customManifest = project.getObjects().property(String.class);
this.setupRemappedVariants = project.getObjects().property(Boolean.class)
.convention(true);
+ this.transitiveAccessWideners = project.getObjects().property(Boolean.class)
+ .convention(true);
+ this.transitiveAccessWideners.finalizeValueOnRead();
this.versionParser = new ModVersionParser(project);
@@ -174,7 +179,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
@Override
public Dependency layered(Action<LayeredMappingSpecBuilder> action) {
- LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(this);
+ LayeredMappingSpecBuilderImpl builder = new LayeredMappingSpecBuilderImpl(this);
action.execute(builder);
LayeredMappingSpec builtSpec = builder.build();
return new LayeredMappingsDependency(new GradleMappingContext(getProject(), builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion());
@@ -222,6 +227,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
return versionParser.getModVersion();
}
+ @Override
+ public Property<Boolean> getEnableTransitiveAccessWideners() {
+ return transitiveAccessWideners;
+ }
+
protected abstract Project getProject();
protected abstract LoomFiles getFiles();
diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java
index ec1c5351..7728bde6 100644
--- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java
+++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java
@@ -25,9 +25,11 @@
package net.fabricmc.loom.extension;
import java.io.File;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -45,6 +47,7 @@ import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.ForgeExtensionAPI;
import net.fabricmc.loom.configuration.InstallerData;
import net.fabricmc.loom.configuration.LoomDependencyManager;
+import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
import net.fabricmc.loom.util.ModPlatform;
@@ -59,6 +62,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
private final MappingSet[] srcMappingCache = new MappingSet[2];
private final Mercury[] srcMercuryCache = new Mercury[2];
private final Map<String, NamedDomainObjectProvider<Configuration>> lazyConfigurations = new HashMap<>();
+ private final List<AccessWidenerFile> transitiveAccessWideners = new ArrayList<>();
private LoomDependencyManager dependencyManager;
private JarProcessorManager jarProcessorManager;
@@ -177,6 +181,16 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
}
@Override
+ public List<AccessWidenerFile> getTransitiveAccessWideners() {
+ return transitiveAccessWideners;
+ }
+
+ @Override
+ public void addTransitiveAccessWideners(List<AccessWidenerFile> accessWidenerFiles) {
+ transitiveAccessWideners.addAll(accessWidenerFiles);
+ }
+
+ @Override
protected String getMinecraftVersion() {
return getMinecraftProvider().minecraftVersion();
}
diff --git a/src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java b/src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java
index 9397e17c..a525bbf8 100644
--- a/src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java
+++ b/src/main/java/net/fabricmc/loom/extension/MinecraftGradleExtension.java
@@ -45,11 +45,11 @@ import net.fabricmc.loom.api.ForgeExtensionAPI;
import net.fabricmc.loom.api.LoomGradleExtensionAPI;
import net.fabricmc.loom.api.MixinExtensionAPI;
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
+import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
import net.fabricmc.loom.configuration.ide.RunConfig;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
import net.fabricmc.loom.configuration.launch.LaunchProviderSettings;
import net.fabricmc.loom.configuration.processors.JarProcessor;
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
import net.fabricmc.loom.util.DeprecationHelper;
import net.fabricmc.loom.util.ModPlatform;
@@ -164,6 +164,12 @@ public class MinecraftGradleExtension implements LoomGradleExtensionAPI {
}
@Override
+ public Property<Boolean> getEnableTransitiveAccessWideners() {
+ reportDeprecation();
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void silentMojangMappingsLicense() {
reportDeprecation();
parent.silentMojangMappingsLicense();
diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java
index c8dbb0ef..e644cb31 100644
--- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java
+++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java
@@ -30,6 +30,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Collection;
+import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
@@ -42,6 +43,8 @@ import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.decompilers.DecompilationMetadata;
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
+import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
+import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerMappingsProcessor;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.decompilers.LineNumberRemapper;
import net.fabricmc.loom.util.Constants;
@@ -63,11 +66,10 @@ public class GenerateSourcesTask extends AbstractLoomTask {
@TaskAction
public void doTask() throws Throwable {
int threads = Runtime.getRuntime().availableProcessors();
- Path javaDocs = getExtension().getMappingsProvider().tinyMappings;
Collection<Path> libraries = getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).getFiles()
- .stream().map(File::toPath).collect(Collectors.toSet());
+ .stream().map(File::toPath).collect(Collectors.toSet());
- DecompilationMetadata metadata = new DecompilationMetadata(threads, javaDocs, libraries);
+ DecompilationMetadata metadata = new DecompilationMetadata(threads, getMappings(), libraries);
Path runtimeJar = getExtension().getMappingsProvider().mappedProvider.getMappedJar().toPath();
Path sourcesDestination = getMappedJarFileWithSuffix("-sources.jar").toPath();
Path linemap = getMappedJarFileWithSuffix("-sources.lmap").toPath();
@@ -93,7 +95,7 @@ public class GenerateSourcesTask extends AbstractLoomTask {
progressLogger.start("Adjusting line numbers", "linemap");
try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(oldCompiledJar.toFile(), true);
- StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(linemappedJarDestination.toFile(), true)) {
+ StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(linemappedJarDestination.toFile(), true)) {
remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/"));
}
@@ -121,6 +123,32 @@ public class GenerateSourcesTask extends AbstractLoomTask {
return new File(path.substring(0, path.length() - 4) + suffix);
}
+ private Path getMappings() {
+ Path baseMappings = getExtension().getMappingsProvider().tinyMappings;
+
+ if (getExtension().getEnableTransitiveAccessWideners().get()) {
+ List<AccessWidenerFile> accessWideners = getExtension().getTransitiveAccessWideners();
+
+ if (accessWideners.isEmpty()) {
+ return baseMappings;
+ }
+
+ Path outputMappings;
+
+ try {
+ outputMappings = Files.createTempFile("loom-transitive-mappings", ".tiny");
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create temp file", e);
+ }
+
+ TransitiveAccessWidenerMappingsProcessor.process(baseMappings, outputMappings, accessWideners, getProject().getLogger());
+
+ return outputMappings;
+ }
+
+ return baseMappings;
+ }
+
@InputFile
public File getInputJar() {
return inputJar;
diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
index 84cee1c9..f7181637 100644
--- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
+++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
@@ -24,14 +24,12 @@
package net.fabricmc.loom.task;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
@@ -49,14 +47,15 @@ import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
+import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
+import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency;
import net.fabricmc.loom.util.SourceRemapper;
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
-import net.fabricmc.mapping.tree.TinyMappingFactory;
-import net.fabricmc.mapping.tree.TinyTree;
+import net.fabricmc.mappingio.MappingReader;
+import net.fabricmc.mappingio.tree.MemoryMappingTree;
public class MigrateMappingsTask extends AbstractLoomTask {
private Path inputDir;
@@ -100,8 +99,8 @@ public class MigrateMappingsTask extends AbstractLoomTask {
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
try {
- TinyTree currentMappings = mappingsProvider.getMappings();
- TinyTree targetMappings = getMappings(mappings);
+ MemoryMappingTree currentMappings = mappingsProvider.getMappings();
+ MemoryMappingTree targetMappings = getMappings(mappings);
migrateMappings(project, extension, extension.getMinecraftMappedProvider(), inputDir, outputDir, currentMappings, targetMappings);
project.getLogger().lifecycle(":remapped project written to " + outputDir.toAbsolutePath());
} catch (IOException e) {
@@ -148,27 +147,25 @@ public class MigrateMappingsTask extends AbstractLoomTask {
return Iterables.getOnlyElement(files);
}
- private static TinyTree getMappings(File mappings) throws IOException {
- Path temp = Files.createTempFile("mappings", ".tiny");
+ private static MemoryMappingTree getMappings(File mappings) throws IOException {
+ MemoryMappingTree mappingTree = new MemoryMappingTree();
try (FileSystem fileSystem = FileSystems.newFileSystem(mappings.toPath(), (ClassLoader) null)) {
- Files.copy(fileSystem.getPath("mappings/mappings.tiny"), temp, StandardCopyOption.REPLACE_EXISTING);
+ MappingReader.read(fileSystem.getPath("mappings/mappings.tiny"), mappingTree);
}
- try (BufferedReader reader = Files.newBufferedReader(temp)) {
- return TinyMappingFactory.loadWithDetection(reader);
- }
+ return mappingTree;
}
private static void migrateMappings(Project project, LoomGradleExtension extension, MinecraftMappedProvider minecraftMappedProvider,
- Path inputDir, Path outputDir, TinyTree currentMappings, TinyTree targetMappings
+ Path inputDir, Path outputDir, MemoryMappingTree currentMappings, MemoryMappingTree targetMappings
) throws IOException {
project.getLogger().info(":joining mappings");
MappingSet mappingSet = new TinyMappingsJoiner(
- currentMappings, "named",
- targetMappings, "named",
- "intermediary"
+ currentMappings, MappingsNamespace.NAMED.toString(),
+ targetMappings, MappingsNamespace.NAMED.toString(),
+ MappingsNamespace.INTERMEDIARY.toString()
).read();
project.getLogger().lifecycle(":remapping");
diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
index 48b9e9bd..5e395a02 100644
--- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
+++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
@@ -86,6 +86,7 @@ import org.zeroturnaround.zip.transform.StreamZipEntryTransformer;
import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.build.JarRemapper;
import net.fabricmc.loom.build.MixinRefmapHelper;
import net.fabricmc.loom.build.nesting.EmptyNestedJarProvider;
@@ -95,12 +96,13 @@ import net.fabricmc.loom.build.nesting.NestedDependencyProvider;
import net.fabricmc.loom.build.nesting.NestedJarPathProvider;
import net.fabricmc.loom.build.nesting.NestedJarProvider;
import net.fabricmc.loom.configuration.JarManifestConfiguration;
+import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.FileSystemUtil;
import net.fabricmc.loom.util.SourceRemapper;
-import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
+import net.fabricmc.loom.util.TinyRemapperHelper;
import net.fabricmc.loom.util.ZipReprocessorUtil;
import net.fabricmc.loom.util.aw2at.Aw2At;
import net.fabricmc.lorenztiny.TinyMappingsReader;
@@ -247,7 +249,7 @@ public class RemapJarTask extends Jar {
if (isMainRemapTask) {
jarRemapper.addToClasspath(getRemapClasspath());
- jarRemapper.addMappings(TinyRemapperMappingsHelper.create(extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
+ jarRemapper.addMappings(TinyRemapperHelper.create(extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
}
for (File mixinMapFile : extension.getAllMixinMappings()) {
@@ -272,15 +274,15 @@ public class RemapJarTask extends Jar {
byte[] data;
try {
- data = accessWidenerJarProcessor.getRemappedAccessWidener(remapper);
+ data = accessWidenerJarProcessor.getRemappedAccessWidener(remapper, toM);
} catch (IOException e) {
- throw new RuntimeException("Failed to remap access widener");
+ throw new RuntimeException("Failed to remap access widener", e);
}
- String awPath = accessWidenerJarProcessor.getAccessWidenerPath(remapData.input);
- Preconditions.checkNotNull(awPath, "Failed to find accessWidener in fabric.mod.json: " + remapData.input);
+ AccessWidenerFile awFile = AccessWidenerFile.fromModJar(remapData.input);
+ Preconditions.checkNotNull(awFile, "Failed to find accessWidener in fabric.mod.json: " + remapData.input);
- return Pair.of(awPath, data);
+ return Pair.of(awFile.name(), data);
}
return null;
@@ -559,7 +561,8 @@ public class RemapJarTask extends Jar {
return this;
}
- @ApiStatus.Experimental // This only allows mod jars, proceed with care when trying to pass in configurations with projects, or something that depends on a task.
+ @ApiStatus.Experimental
+ // This only allows mod jars, proceed with care when trying to pass in configurations with projects, or something that depends on a task.
public RemapJarTask include(Object... paths) {
Collections.addAll(nestedPaths, paths);
this.addNestedDependencies.set(true);
diff --git a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java
index d8cb2e13..97556c13 100644
--- a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java
+++ b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java
@@ -32,6 +32,7 @@ import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.util.SourceRemapper;
public class RemapSourcesJarTask extends AbstractLoomTask {
@@ -53,7 +54,7 @@ public class RemapSourcesJarTask extends AbstractLoomTask {
if (sourceRemapper == null) {
if (sourceNamespace.get().equals(targetNamespace.get())) {
SourceRemapper.remapSources(getProject(), getInput().get().getAsFile(), getOutput().get().getAsFile(),
- targetNamespace.get().equals("named") ? SourceRemapper.intermediary(getProject()) : "named", targetNamespace.get(), reproducibleFileOrder.get(), preserveFileTimestamps.get());
+ targetNamespace.get().equals(MappingsNamespace.NAMED.toString()) ? SourceRemapper.intermediary(getProject()) : "named", targetNamespace.get(), reproducibleFileOrder.get(), preserveFileTimestamps.get());
} else {
SourceRemapper.remapSources(getProject(), getInput().get().getAsFile(), getOutput().get().getAsFile(), sourceNamespace.get(), targetNamespace.get(), reproducibleFileOrder.get(), preserveFileTimestamps.get());
}
diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java
index d38cadae..b5ab3798 100644
--- a/src/main/java/net/fabricmc/loom/util/Constants.java
+++ b/src/main/java/net/fabricmc/loom/util/Constants.java
@@ -53,8 +53,6 @@ public class Constants {
new RemappedConfigurationEntry("modRuntimeOnly", JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME, false, true, JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME)
);
- public static final String SOFTWARE_COMPONENT_NAME = "loom";
-
private Constants() {
}
diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
index 2b2fa943..145bb82f 100644
--- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
+++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
@@ -40,11 +40,12 @@ import org.gradle.api.Project;
import org.zeroturnaround.zip.ZipUtil;
import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.util.gradle.ProgressLogger;
import net.fabricmc.lorenztiny.TinyMappingsReader;
-import net.fabricmc.mapping.tree.TinyTree;
+import net.fabricmc.mappingio.tree.MemoryMappingTree;
import net.fabricmc.stitch.util.StitchUtil;
public class SourceRemapper {
@@ -184,7 +185,7 @@ public class SourceRemapper {
MappingSet mappings = extension.getOrCreateSrcMappingCache(id, () -> {
try {
- TinyTree m = extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings();
+ MemoryMappingTree m = extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings();
project.getLogger().info(":loading " + from + " -> " + to + " source mappings");
return new TinyMappingsReader(m, from, to).read();
} catch (Exception e) {
diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java
new file mode 100644
index 00000000..aa295f0c
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java
@@ -0,0 +1,108 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.gradle.api.Project;
+
+import net.fabricmc.loom.LoomGradleExtension;
+import net.fabricmc.mappingio.tree.MappingTree;
+import net.fabricmc.tinyremapper.IMappingProvider;
+import net.fabricmc.tinyremapper.TinyRemapper;
+
+/**
+ * Contains shortcuts to create tiny remappers using the mappings accessibly to the project.
+ */
+public final class TinyRemapperHelper {
+ private static final Map<String, String> JSR_TO_JETBRAINS = new ImmutableMap.Builder<String, String>()
+ .put("javax/annotation/Nullable", "org/jetbrains/annotations/Nullable")
+ .put("javax/annotation/Nonnull", "org/jetbrains/annotations/NotNull")
+ .put("javax/annotation/concurrent/Immutable", "org/jetbrains/annotations/Unmodifiable")
+ .build();
+
+ private TinyRemapperHelper() {
+ }
+
+ public static TinyRemapper getTinyRemapper(Project project, String fromM, String toM) throws IOException {
+ LoomGradleExtension extension = LoomGradleExtension.get(project);
+
+ return TinyRemapper.newRemapper()
+ .withMappings(create(extension.getMappingsProvider().getMappings(), fromM, toM, true))
+ .withMappings(out -> JSR_TO_JETBRAINS.forEach(out::acceptClass))
+ .renameInvalidLocals(true)
+ .rebuildSourceFilenames(true)
+ .build();
+ }
+
+ public static Path[] getMinecraftDependencies(Project project) {
+ return project.getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).getFiles()
+ .stream().map(File::toPath).toArray(Path[]::new);
+ }
+
+ private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) {
+ return new IMappingProvider.Member(className, memberName, descriptor);
+ }
+
+ public static IMappingProvider create(MappingTree mappings, String from, String to, boolean remapLocalVariables) {
+ return (acceptor) -> {
+ for (MappingTree.ClassMapping classDef : mappings.getClasses()) {
+ String className = classDef.getName(from);
+ acceptor.acceptClass(className, classDef.getName(to));
+
+ for (MappingTree.FieldMapping field : classDef.getFields()) {
+ acceptor.acceptField(memberOf(className, field.getName(from), field.getDesc(from)), field.getName(to));
+ }
+
+ for (MappingTree.MethodMapping method : classDef.getMethods()) {
+ IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDesc(from));
+ acceptor.acceptMethod(methodIdentifier, method.getName(to));
+
+ if (remapLocalVariables) {
+ for (MappingTree.MethodArgMapping parameter : method.getArgs()) {
+ String name = parameter.getName(to);
+
+ if (name == null) {
+ continue;
+ }
+
+ acceptor.acceptMethodArg(methodIdentifier, parameter.getLvIndex(), name);
+ }
+
+ for (MappingTree.MethodVarMapping localVariable : method.getVars()) {
+ acceptor.acceptMethodVar(methodIdentifier, localVariable.getLvIndex(),
+ localVariable.getStartOpIdx(), localVariable.getLvtRowIndex(),
+ localVariable.getName(to));
+ }
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java
deleted file mode 100644
index f5b9b911..00000000
--- a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2016-2019 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
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.util;
-
-import dev.architectury.tinyremapper.IMappingProvider;
-
-import net.fabricmc.mapping.tree.ClassDef;
-import net.fabricmc.mapping.tree.FieldDef;
-import net.fabricmc.mapping.tree.LocalVariableDef;
-import net.fabricmc.mapping.tree.MethodDef;
-import net.fabricmc.mapping.tree.ParameterDef;
-import net.fabricmc.mapping.tree.TinyTree;
-
-public class TinyRemapperMappingsHelper {
- private TinyRemapperMappingsHelper() { }
-
- private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) {
- return new IMappingProvider.Member(className, memberName, descriptor);
- }
-
- public static IMappingProvider create(TinyTree mappings, String from, String to, boolean remapLocalVariables) {
- return (acceptor) -> {
- for (ClassDef classDef : mappings.getClasses()) {
- String className = classDef.getName(from);
- acceptor.acceptClass(className, classDef.getName(to));
-
- for (FieldDef field : classDef.getFields()) {
- acceptor.acceptField(memberOf(className, field.getName(from), field.getDescriptor(from)), field.getName(to));
- }
-
- for (MethodDef method : classDef.getMethods()) {
- IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDescriptor(from));
- acceptor.acceptMethod(methodIdentifier, method.getName(to));
-
- if (remapLocalVariables) {
- for (ParameterDef parameter : method.getParameters()) {
- acceptor.acceptMethodArg(methodIdentifier, parameter.getLocalVariableIndex(), parameter.getName(to));
- }
-
- for (LocalVariableDef localVariable : method.getLocalVariables()) {
- acceptor.acceptMethodVar(methodIdentifier, localVariable.getLocalVariableIndex(),
- localVariable.getLocalVariableStartOffset(), localVariable.getLocalVariableTableIndex(),
- localVariable.getName(to));
- }
- }
- }
- }
- };
- }
-}
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 8fed624d..43c793cb 100644
--- a/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/test/integration/AccessWidenerTest.groovy
@@ -25,6 +25,7 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
+import org.zeroturnaround.zip.ZipUtil
import spock.lang.Specification
import spock.lang.Unroll
@@ -48,4 +49,20 @@ class AccessWidenerTest extends Specification implements GradleProjectTestTrait
String expected() {
new File("src/test/resources/accesswidener/expected.accesswidener").text
}
+
+ @Unroll
+ def "transitive accesswidener (gradle #version)"() {
+ setup:
+ def gradle = gradleProject(project: "transitiveAccesswidener", version: version)
+ ZipUtil.pack(new File(gradle.projectDir, "dummyDependency"), new File(gradle.projectDir, "dummy.jar"))
+
+ when:
+ def result = gradle.run(task: "build")
+
+ then:
+ result.task(":build").outcome == SUCCESS
+
+ where:
+ version << STANDARD_TEST_VERSIONS
+ }
}
diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy
index cfcb8a2e..0b583071 100644
--- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy
@@ -24,8 +24,9 @@
package net.fabricmc.loom.test.unit.layeredmappings
+import net.fabricmc.loom.configuration.providers.mappings.utils.MavenFileSpec
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec
-import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder
+import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
@@ -60,7 +61,7 @@ class LayeredMappingSpecBuilderTest extends LayeredMappingsSpecification {
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
- parchment.mavenNotation() == "I like cake"
+ (parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == true
}
@@ -80,7 +81,7 @@ class LayeredMappingSpecBuilderTest extends LayeredMappingsSpecification {
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
- parchment.mavenNotation() == "I like cake"
+ (parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == false
}
@@ -100,17 +101,17 @@ class LayeredMappingSpecBuilderTest extends LayeredMappingsSpecification {
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
- parchment.mavenNotation() == "I really like cake"
+ (parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I really like cake"
parchment.removePrefix() == false
}
// Gradle does this big of magic behind the scenes
- LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilder) Closure cl) {
+ LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilderImpl) Closure cl) {
return layeredAction(ConfigureUtil.configureUsing(cl))
}
- LayeredMappingSpec layeredAction(Action<LayeredMappingSpecBuilder> action) {
- LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(null)
+ LayeredMappingSpec layeredAction(Action<LayeredMappingSpecBuilderImpl> action) {
+ LayeredMappingSpecBuilderImpl builder = new LayeredMappingSpecBuilderImpl(null)
action.execute(builder)
return builder.build()
}
diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy
index 10429120..1fba03dc 100644
--- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy
+++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy
@@ -28,18 +28,20 @@ import groovy.transform.CompileStatic
import net.fabricmc.loom.configuration.providers.MinecraftProvider
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor
-import net.fabricmc.loom.configuration.providers.mappings.MappingContext
-import net.fabricmc.loom.configuration.providers.mappings.MappingLayer
-import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace
+import net.fabricmc.loom.api.mappings.layered.MappingContext
+import net.fabricmc.loom.api.mappings.layered.MappingLayer
+import net.fabricmc.loom.api.mappings.layered.MappingsNamespace
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider
-import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec
+import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec
import net.fabricmc.mappingio.adapter.MappingDstNsReorder
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch
import net.fabricmc.mappingio.format.Tiny2Writer
import net.fabricmc.mappingio.tree.MemoryMappingTree
+import org.gradle.api.artifacts.Dependency
import org.gradle.api.logging.Logger
import spock.lang.Specification
+import java.nio.file.Path
import java.util.zip.ZipFile
abstract class LayeredMappingsSpecification extends Specification implements LayeredMappingsTestConstants {
@@ -94,8 +96,8 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
MemoryMappingTree reorder(MemoryMappingTree mappingTree) {
def reorderedMappings = new MemoryMappingTree()
- def nsReorder = new MappingDstNsReorder(reorderedMappings, Collections.singletonList(MappingNamespace.NAMED.stringValue()))
- def nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingNamespace.INTERMEDIARY.stringValue(), true)
+ def nsReorder = new MappingDstNsReorder(reorderedMappings, Collections.singletonList(MappingsNamespace.NAMED.toString()))
+ def nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true)
mappingTree.accept(nsSwitch)
return reorderedMappings
}
@@ -103,9 +105,14 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
@CompileStatic
class TestMappingContext implements MappingContext {
@Override
- File mavenFile(String mavenNotation) {
+ Path resolveDependency(Dependency dependency) {
+ throw new UnsupportedOperationException("TODO")
+ }
+
+ @Override
+ Path resolveMavenDependency(String mavenNotation) {
assert mavenFiles.containsKey(mavenNotation)
- return mavenFiles.get(mavenNotation)
+ return mavenFiles.get(mavenNotation).toPath()
}
@Override
@@ -119,8 +126,8 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
}
@Override
- File workingDirectory(String name) {
- return new File(tempDir, name)
+ Path workingDirectory(String name) {
+ return new File(tempDir, name).toPath()
}
@Override
diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy
index ac9592cf..73e2a259 100644
--- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy
@@ -24,6 +24,7 @@
package net.fabricmc.loom.test.unit.layeredmappings
+import net.fabricmc.loom.api.mappings.layered.spec.FileSpec
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
@@ -38,7 +39,7 @@ class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(),
- new ParchmentMappingsSpec(PARCHMENT_NOTATION, false)
+ new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), false)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
@@ -61,7 +62,7 @@ class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(),
- new ParchmentMappingsSpec(PARCHMENT_NOTATION, true)
+ new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), true)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
diff --git a/src/test/resources/accesswidener/expected.accesswidener b/src/test/resources/accesswidener/expected.accesswidener
index 53bf68a7..66f55429 100644
--- a/src/test/resources/accesswidener/expected.accesswidener
+++ b/src/test/resources/accesswidener/expected.accesswidener
@@ -1,9 +1,6 @@
accessWidener v1 intermediary
-accessible class net/minecraft/class_1928$class_5199
-accessible class net/minecraft/class_1735
-accessible class net/minecraft/class_1928$class_4314
-extendable class net/minecraft/class_1928$class_4314
-accessible class net/minecraft/class_5235$class_5238
accessible method net/minecraft/class_1928$class_4314 <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/class_1928$class_5199;)V
extendable method net/minecraft/class_1928$class_4314 <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/class_1928$class_5199;)V
+accessible class net/minecraft/class_1928$class_5199
+accessible class net/minecraft/class_5235$class_5238
accessible field net/minecraft/class_1735 field_7873 I
diff --git a/src/test/resources/projects/transitiveAccesswidener/build.gradle b/src/test/resources/projects/transitiveAccesswidener/build.gradle
new file mode 100644
index 00000000..52f1fc39
--- /dev/null
+++ b/src/test/resources/projects/transitiveAccesswidener/build.gradle
@@ -0,0 +1,18 @@
+// This is used by a range of tests that append to this file before running the gradle tasks.
+// Can be used for tests that require minimal custom setup
+plugins {
+ id 'fabric-loom'
+ id 'maven-publish'
+}
+
+archivesBaseName = "fabric-example-mod"
+version = "1.0.0"
+group = "com.example"
+
+dependencies {
+ minecraft "com.mojang:minecraft:1.17.1"
+ mappings "net.fabricmc:yarn:1.17.1+build.59:v2"
+ modImplementation "net.fabricmc:fabric-loader:0.11.6"
+
+ modImplementation files("dummy.jar")
+} \ No newline at end of file
diff --git a/src/test/resources/projects/transitiveAccesswidener/dummyDependency/dummy.accesswidener b/src/test/resources/projects/transitiveAccesswidener/dummyDependency/dummy.accesswidener
new file mode 100644
index 00000000..05537ad1
--- /dev/null
+++ b/src/test/resources/projects/transitiveAccesswidener/dummyDependency/dummy.accesswidener
@@ -0,0 +1,3 @@
+accessWidener v2 intermediary
+
+transitive-accessible method net/minecraft/class_1972 method_8775 (Ljava/lang/String;)Lnet/minecraft/class_5321; \ No newline at end of file
diff --git a/src/test/resources/projects/transitiveAccesswidener/dummyDependency/fabric.mod.json b/src/test/resources/projects/transitiveAccesswidener/dummyDependency/fabric.mod.json
new file mode 100644
index 00000000..b89a826e
--- /dev/null
+++ b/src/test/resources/projects/transitiveAccesswidener/dummyDependency/fabric.mod.json
@@ -0,0 +1,7 @@
+{
+ "schemaVersion": 1,
+ "id": "dummy",
+ "version": "1",
+ "name": "Dummy Mod",
+ "accessWidener" : "dummy.accesswidener"
+}
diff --git a/src/test/resources/projects/transitiveAccesswidener/src/main/java/ExampleMod.java b/src/test/resources/projects/transitiveAccesswidener/src/main/java/ExampleMod.java
new file mode 100644
index 00000000..e5442d2d
--- /dev/null
+++ b/src/test/resources/projects/transitiveAccesswidener/src/main/java/ExampleMod.java
@@ -0,0 +1,13 @@
+import net.minecraft.world.biome.BiomeKeys;
+import net.minecraft.world.biome.Biome;
+import net.minecraft.util.registry.RegistryKey;
+
+import net.fabricmc.api.ModInitializer;
+
+public class ExampleMod implements ModInitializer {
+ @Override
+ public void onInitialize() {
+ // BiomeKeys.register has been made public by a transitive AW
+ RegistryKey<Biome> biomeRegistryKey = BiomeKeys.register("dummy");
+ }
+}