mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-28 04:07:01 -05:00
Remapper extensions (#984)
* Remapper extension API * Fix build * More work * Fixes, thanks Gradle. * Build fix * Cleanup
This commit is contained in:
@@ -45,6 +45,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMi
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider;
|
||||
import net.fabricmc.loom.extension.LoomFiles;
|
||||
import net.fabricmc.loom.extension.MixinExtension;
|
||||
import net.fabricmc.loom.extension.RemapperExtensionHolder;
|
||||
import net.fabricmc.loom.util.download.DownloadBuilder;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -115,4 +116,6 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
|
||||
boolean multiProjectOptimisation();
|
||||
|
||||
ListProperty<LibraryProcessorManager.LibraryProcessorFactory> getLibraryProcessors();
|
||||
|
||||
ListProperty<RemapperExtensionHolder> getRemapperExtensions();
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions;
|
||||
import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider;
|
||||
import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
|
||||
import net.fabricmc.loom.api.processor.MinecraftJarProcessor;
|
||||
import net.fabricmc.loom.api.remapping.RemapperExtension;
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters;
|
||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||
import net.fabricmc.loom.configuration.processors.JarProcessor;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.NoOpIntermediateMappingsProvider;
|
||||
@@ -221,4 +223,6 @@ public interface LoomGradleExtensionAPI {
|
||||
Property<Boolean> getRuntimeOnlyLog4j();
|
||||
|
||||
Property<Boolean> getSplitModDependencies();
|
||||
|
||||
<T extends RemapperParameters> void addRemapperExtension(Class<RemapperExtension<T>> remapperExtensionClass, Class<T> parametersClass, Action<T> parameterAction);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.remapping;
|
||||
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
/**
|
||||
* Context for a {@link RemapperExtension}.
|
||||
*/
|
||||
public interface RemapperContext {
|
||||
/**
|
||||
* @return The {@link Remapper} instance
|
||||
*/
|
||||
Remapper remapper();
|
||||
|
||||
/**
|
||||
* @return the source namespace
|
||||
*/
|
||||
String sourceNamespace();
|
||||
|
||||
/**
|
||||
* @return the target namespace
|
||||
*/
|
||||
String targetNamespace();
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.remapping;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
|
||||
/**
|
||||
* A remapper extension can be used to add extra processing to the remapping process.
|
||||
*
|
||||
* <p>Implementations of RemapperExtension's must have the following:
|
||||
* A single constructor annotated with {@link Inject}, and taking a single argument of the parameters.
|
||||
* Or a single constructor annotated with {@link Inject} taking no arguments, when the extension does not have any parameters.
|
||||
*
|
||||
* <p>Use {@link net.fabricmc.loom.api.LoomGradleExtensionAPI#addRemapperExtension(Class, Class, Action)} to register a remapper extension.
|
||||
*
|
||||
* @param <T> Parameter type for the extension. Should be {@link RemapperParameters.None} if the action does not have parameters.
|
||||
*/
|
||||
public interface RemapperExtension<T extends RemapperParameters> {
|
||||
/**
|
||||
* Return a {@link ClassVisitor} that will be used when remapping the given class.
|
||||
*
|
||||
* @param className The name of the class being remapped
|
||||
* @param remapperContext The remapper context
|
||||
* @param classVisitor The parent class visitor
|
||||
* @return A {@link ClassVisitor} that will be used when remapping the given class, or the given {@code classVisitor} if no extra processing is required for this class.
|
||||
*/
|
||||
ClassVisitor insertVisitor(String className, RemapperContext remapperContext, ClassVisitor classVisitor);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.remapping;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Marker interface for parameter objects to {@link RemapperExtension}s.
|
||||
*
|
||||
* <p>Design based off of Gradle's {@link org.gradle.workers.WorkParameters}.
|
||||
*/
|
||||
public interface RemapperParameters {
|
||||
final class None implements RemapperParameters {
|
||||
@ApiStatus.Internal
|
||||
public static None INSTANCE = new None();
|
||||
|
||||
private None() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.remapping;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
|
||||
/**
|
||||
* A remapper extension, that has direct access to the TinyRemapper APIs.
|
||||
*
|
||||
* <p>This API is not stable and may change without notice.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public interface TinyRemapperExtension {
|
||||
/**
|
||||
* See: {@link TinyRemapper.Builder#extraAnalyzeVisitor(TinyRemapper.AnalyzeVisitorProvider)}.
|
||||
*
|
||||
* @return A {@link TinyRemapper.AnalyzeVisitorProvider} or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
default TinyRemapper.AnalyzeVisitorProvider getAnalyzeVisitorProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* See: {@link TinyRemapper.Builder#extraPreApplyVisitor(TinyRemapper.ApplyVisitorProvider)}.
|
||||
*
|
||||
* @return A {@link TinyRemapper.ApplyVisitorProvider} or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
default TinyRemapper.ApplyVisitorProvider getPreApplyVisitor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* See: {@link TinyRemapper.Builder#extraPostApplyVisitor(TinyRemapper.ApplyVisitorProvider)}.
|
||||
*
|
||||
* @return A {@link TinyRemapper.ApplyVisitorProvider} or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
default TinyRemapper.ApplyVisitorProvider getPostApplyVisitor() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ import net.fabricmc.loom.api.RemapConfigurationSettings;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.mods.dependency.ModDependency;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.extension.RemapperExtensionHolder;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
@@ -157,6 +158,10 @@ public class ModProcessor {
|
||||
builder.extension(new MixinExtension(remapMixins::contains));
|
||||
}
|
||||
|
||||
for (RemapperExtensionHolder holder : extension.getRemapperExtensions().get()) {
|
||||
holder.apply(builder, fromM, toM, project.getObjects());
|
||||
}
|
||||
|
||||
final TinyRemapper remapper = builder.build();
|
||||
|
||||
for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
@@ -50,6 +51,8 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions;
|
||||
import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider;
|
||||
import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder;
|
||||
import net.fabricmc.loom.api.processor.MinecraftJarProcessor;
|
||||
import net.fabricmc.loom.api.remapping.RemapperExtension;
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters;
|
||||
import net.fabricmc.loom.configuration.RemapConfigurations;
|
||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||
import net.fabricmc.loom.configuration.processors.JarProcessor;
|
||||
@@ -91,6 +94,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
private final NamedDomainObjectContainer<ModSettings> mods;
|
||||
private final NamedDomainObjectList<RemapConfigurationSettings> remapConfigurations;
|
||||
private final ListProperty<MinecraftJarProcessor<?>> minecraftJarProcessors;
|
||||
protected final ListProperty<RemapperExtensionHolder> remapperExtensions;
|
||||
|
||||
// A common mistake with layered mappings is to call the wrong `officialMojangMappings` method, use this to keep track of when we are building a layered mapping spec.
|
||||
protected final ThreadLocal<Boolean> layeredSpecBuilderScope = ThreadLocal.withInitial(() -> false);
|
||||
@@ -150,6 +154,9 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
this.splitEnvironmentalSourceSet = project.getObjects().property(Boolean.class).convention(false);
|
||||
this.splitEnvironmentalSourceSet.finalizeValueOnRead();
|
||||
|
||||
remapperExtensions = project.getObjects().listProperty(RemapperExtensionHolder.class);
|
||||
remapperExtensions.finalizeValueOnRead();
|
||||
|
||||
// Enable dep iface injection by default
|
||||
interfaceInjection(interfaceInjection -> {
|
||||
interfaceInjection.getEnableDependencyInterfaceInjection().convention(true).finalizeValueOnRead();
|
||||
@@ -382,6 +389,23 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
RemapConfigurations.setupForSourceSet(getProject(), sourceSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends RemapperParameters> void addRemapperExtension(Class<RemapperExtension<T>> remapperExtensionClass, Class<T> parametersClass, Action<T> parameterAction) {
|
||||
final ObjectFactory objectFactory = getProject().getObjects();
|
||||
final RemapperExtensionHolder holder;
|
||||
|
||||
if (parametersClass != RemapperParameters.None.class) {
|
||||
T parameters = objectFactory.newInstance(parametersClass);
|
||||
parameterAction.execute(parameters);
|
||||
holder = objectFactory.newInstance(RemapperExtensionHolder.class, parameters);
|
||||
} else {
|
||||
holder = objectFactory.newInstance(RemapperExtensionHolder.class, RemapperParameters.None.INSTANCE);
|
||||
}
|
||||
|
||||
holder.getRemapperExtensionClassName().set(remapperExtensionClass.getName());
|
||||
remapperExtensions.add(holder);
|
||||
}
|
||||
|
||||
// This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods
|
||||
private final class EnsureCompile extends LoomGradleExtensionApiImpl {
|
||||
private EnsureCompile() {
|
||||
|
||||
@@ -247,6 +247,11 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
|
||||
return libraryProcessorFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListProperty<RemapperExtensionHolder> getRemapperExtensions() {
|
||||
return remapperExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends IntermediateMappingsProvider> void configureIntermediateMappingsProviderInternal(T provider) {
|
||||
provider.getMinecraftVersion().set(getProject().provider(() -> getMinecraftProvider().minecraftVersion()));
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.extension;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
import net.fabricmc.loom.api.remapping.RemapperContext;
|
||||
import net.fabricmc.loom.api.remapping.RemapperExtension;
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters;
|
||||
import net.fabricmc.loom.api.remapping.TinyRemapperExtension;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.fabricmc.tinyremapper.api.TrClass;
|
||||
|
||||
public abstract class RemapperExtensionHolder {
|
||||
// Null when RemapperParameters.None.class
|
||||
private final RemapperParameters remapperParameters;
|
||||
|
||||
@Inject
|
||||
public RemapperExtensionHolder(RemapperParameters remapperParameters) {
|
||||
this.remapperParameters = remapperParameters;
|
||||
}
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getRemapperExtensionClassName();
|
||||
|
||||
@Nested
|
||||
@Optional
|
||||
public RemapperParameters getRemapperParameters() {
|
||||
return remapperParameters;
|
||||
}
|
||||
|
||||
public void apply(TinyRemapper.Builder tinyRemapperBuilder, String sourceNamespace, String targetNamespace, ObjectFactory objectFactory) {
|
||||
final RemapperExtension<?> remapperExtension = newInstance(objectFactory);
|
||||
|
||||
tinyRemapperBuilder.extraPostApplyVisitor(new RemapperExtensionImpl(remapperExtension, sourceNamespace, targetNamespace));
|
||||
|
||||
if (remapperExtension instanceof TinyRemapperExtension tinyRemapperExtension) {
|
||||
final TinyRemapper.AnalyzeVisitorProvider analyzeVisitorProvider = tinyRemapperExtension.getAnalyzeVisitorProvider();
|
||||
final TinyRemapper.ApplyVisitorProvider preApplyVisitorProvider = tinyRemapperExtension.getPreApplyVisitor();
|
||||
final TinyRemapper.ApplyVisitorProvider postApplyVisitorProvider = tinyRemapperExtension.getPostApplyVisitor();
|
||||
|
||||
if (analyzeVisitorProvider != null) {
|
||||
tinyRemapperBuilder.extraAnalyzeVisitor(analyzeVisitorProvider);
|
||||
}
|
||||
|
||||
if (preApplyVisitorProvider != null) {
|
||||
tinyRemapperBuilder.extraPreApplyVisitor(preApplyVisitorProvider);
|
||||
}
|
||||
|
||||
if (postApplyVisitorProvider != null) {
|
||||
tinyRemapperBuilder.extraPostApplyVisitor(postApplyVisitorProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RemapperExtension<?> newInstance(ObjectFactory objectFactory) {
|
||||
try {
|
||||
Class<? extends RemapperExtension> remapperExtensionClass = Class.forName(getRemapperExtensionClassName().get())
|
||||
.asSubclass(RemapperExtension.class);
|
||||
|
||||
if (remapperParameters == RemapperParameters.None.INSTANCE) {
|
||||
return objectFactory.newInstance(remapperExtensionClass);
|
||||
}
|
||||
|
||||
return objectFactory.newInstance(remapperExtensionClass, remapperParameters);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to create remapper extension", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RemapperExtensionImpl implements TinyRemapper.ApplyVisitorProvider {
|
||||
private final RemapperExtension<?> remapperExtension;
|
||||
private final String sourceNamespace;
|
||||
private final String targetNamespace;
|
||||
|
||||
@Nullable
|
||||
private RemapperContext context;
|
||||
|
||||
private RemapperExtensionImpl(RemapperExtension<?> remapperExtension, String sourceNamespace, String targetNamespace) {
|
||||
this.remapperExtension = remapperExtension;
|
||||
this.sourceNamespace = sourceNamespace;
|
||||
this.targetNamespace = targetNamespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) {
|
||||
if (context == null) {
|
||||
context = new RemapperContextImpl(cls.getEnvironment().getRemapper(), sourceNamespace, targetNamespace);
|
||||
}
|
||||
|
||||
return remapperExtension.insertVisitor(cls.getName(), context, next);
|
||||
}
|
||||
}
|
||||
|
||||
private record RemapperContextImpl(Remapper remapper, String sourceNamespace, String targetNamespace) implements RemapperContext {
|
||||
}
|
||||
}
|
||||
@@ -39,11 +39,13 @@ import java.util.StringJoiner;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.invocation.Gradle;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.build.mixin.AnnotationProcessorInvoker;
|
||||
import net.fabricmc.loom.extension.RemapperExtensionHolder;
|
||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
@@ -90,7 +92,7 @@ public class TinyRemapperService implements SharedService {
|
||||
mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), extension.getMappingConfiguration().mappingsIdentifier, from, to));
|
||||
}
|
||||
|
||||
return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService, extension.getKnownIndyBsms().get());
|
||||
return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService, extension.getKnownIndyBsms().get(), extension.getRemapperExtensions().get(), from, to, project.getObjects());
|
||||
});
|
||||
|
||||
service.readClasspath(remapJarTask.getClasspath().getFiles().stream().map(File::toPath).filter(Files::exists).toList());
|
||||
@@ -129,7 +131,7 @@ public class TinyRemapperService implements SharedService {
|
||||
// Set to true once remapping has started, once set no inputs can be read.
|
||||
private boolean isRemapping = false;
|
||||
|
||||
public TinyRemapperService(List<IMappingProvider> mappings, boolean useMixinExtension, @Nullable KotlinClasspath kotlinClasspath, Set<String> knownIndyBsms) {
|
||||
private TinyRemapperService(List<IMappingProvider> mappings, boolean useMixinExtension, @Nullable KotlinClasspath kotlinClasspath, Set<String> knownIndyBsms, List<RemapperExtensionHolder> remapperExtensions, String sourceNamespace, String targetNamespace, ObjectFactory objectFactory) {
|
||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper().withKnownIndyBsm(knownIndyBsms);
|
||||
|
||||
for (IMappingProvider provider : mappings) {
|
||||
@@ -145,6 +147,10 @@ public class TinyRemapperService implements SharedService {
|
||||
builder.extension(kotlinRemapperClassloader.getTinyRemapperExtension());
|
||||
}
|
||||
|
||||
for (RemapperExtensionHolder holder : remapperExtensions) {
|
||||
holder.apply(builder, sourceNamespace, targetNamespace, objectFactory);
|
||||
}
|
||||
|
||||
tinyRemapper = builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ class SimpleProjectTest extends Specification implements GradleProjectTestTrait
|
||||
def "build and run (gradle #version)"() {
|
||||
setup:
|
||||
def gradle = gradleProject(project: "simple", version: version)
|
||||
gradle.buildSrc("remapext") // apply the remap extension plugin
|
||||
|
||||
def server = ServerRunner.create(gradle.projectDir, "1.16.5")
|
||||
.withMod(gradle.getOutputFile("fabric-example-mod-1.0.0.jar"))
|
||||
@@ -60,6 +61,7 @@ class SimpleProjectTest extends Specification implements GradleProjectTestTrait
|
||||
|
||||
serverResult.successful()
|
||||
serverResult.output.contains("Hello simple Fabric mod") // A check to ensure our mod init was actually called
|
||||
serverResult.output.contains("Hello Loom!") // Check that the remapper extension worked
|
||||
where:
|
||||
version << STANDARD_TEST_VERSIONS
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.test.integration.buildSrc.remapext
|
||||
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
import org.objectweb.asm.MethodVisitor
|
||||
|
||||
class StringReplacementClassVisitor extends ClassVisitor {
|
||||
final Map<String, String> replacements
|
||||
|
||||
StringReplacementClassVisitor(int api, ClassVisitor classVisitor, Map<String, String> replacements) {
|
||||
super(api, classVisitor)
|
||||
this.replacements = replacements
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
def methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions)
|
||||
return new StringReplacementMethodVisitor(api, methodVisitor)
|
||||
}
|
||||
|
||||
class StringReplacementMethodVisitor extends MethodVisitor {
|
||||
StringReplacementMethodVisitor(int api, MethodVisitor methodVisitor) {
|
||||
super(api, methodVisitor)
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitLdcInsn(Object value) {
|
||||
if (value instanceof String) {
|
||||
String replacement = replacements.get(value)
|
||||
if (replacement != null) {
|
||||
value = replacement
|
||||
}
|
||||
}
|
||||
|
||||
super.visitLdcInsn(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.test.integration.buildSrc.remapext
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters
|
||||
|
||||
class TestPlugin implements Plugin<Project> {
|
||||
@Override
|
||||
void apply(Project project) {
|
||||
def extension = LoomGradleExtension.get(project)
|
||||
extension.addRemapperExtension(TestRemapperExtension.class, TestRemapperExtension.Params.class) { TestRemapperExtension.Params p ->
|
||||
p.replacements.put("Hello World!", "Hello Loom!")
|
||||
}
|
||||
extension.addRemapperExtension(TestTinyRemapperExtension.class, RemapperParameters.None.class) { RemapperParameters.None p ->
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.test.integration.buildSrc.remapext
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
|
||||
import net.fabricmc.loom.api.remapping.RemapperContext
|
||||
import net.fabricmc.loom.api.remapping.RemapperExtension
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters
|
||||
import net.fabricmc.loom.util.Constants
|
||||
|
||||
abstract class TestRemapperExtension implements RemapperExtension<Params> {
|
||||
final Params parameters
|
||||
|
||||
@Inject
|
||||
TestRemapperExtension(Params parameters) {
|
||||
this.parameters = parameters
|
||||
}
|
||||
|
||||
@Override
|
||||
ClassVisitor insertVisitor(String className, RemapperContext remapperContext, ClassVisitor classVisitor) {
|
||||
def replacements = parameters.replacements.get()
|
||||
return new StringReplacementClassVisitor(Constants.ASM_VERSION, classVisitor, replacements)
|
||||
}
|
||||
|
||||
interface Params extends RemapperParameters {
|
||||
MapProperty<String, String> getReplacements()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2023 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.test.integration.buildSrc.remapext
|
||||
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
|
||||
import net.fabricmc.loom.api.remapping.RemapperContext
|
||||
import net.fabricmc.loom.api.remapping.RemapperExtension
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters
|
||||
import net.fabricmc.loom.api.remapping.TinyRemapperExtension
|
||||
import net.fabricmc.tinyremapper.TinyRemapper
|
||||
|
||||
class TestTinyRemapperExtension implements RemapperExtension<RemapperParameters.None>, TinyRemapperExtension {
|
||||
@Override
|
||||
ClassVisitor insertVisitor(String className, RemapperContext remapperContext, ClassVisitor classVisitor) {
|
||||
return classVisitor
|
||||
}
|
||||
|
||||
TinyRemapper.AnalyzeVisitorProvider analyzeVisitorProvider = null
|
||||
TinyRemapper.ApplyVisitorProvider preApplyVisitor = null
|
||||
TinyRemapper.ApplyVisitorProvider PostApplyVisitor = null
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package net.fabricmc.example;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class ExampleMod implements ModInitializer {
|
||||
public static final Logger LOGGER = LogManager.getLogger("modid");
|
||||
|
||||
@@ -13,5 +14,6 @@ public class ExampleMod implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Hello simple Fabric mod!");
|
||||
LOGGER.info("Hello World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user