Allow applying kapt and using mixins in other source sets (#211)
* Fix kapt and source sets * cleanup * cleanup 2
This commit is contained in:
		
							parent
							
								
									5d468efc48
								
							
						
					
					
						commit
						cf13e4aa02
					
				
					 7 changed files with 373 additions and 64 deletions
				
			
		|  | @ -62,6 +62,9 @@ dependencies { | |||
| 	// source code remapping | ||||
| 	implementation ('org.cadixdev:mercury:0.1.0.fabric-SNAPSHOT') | ||||
| 
 | ||||
| 	// Kapt integration | ||||
| 	compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72") | ||||
| 
 | ||||
| 	// Testing | ||||
| 	testImplementation(gradleTestKit()) | ||||
| 	testImplementation("org.spockframework:spock-core:1.3-groovy-2.4") | ||||
|  |  | |||
|  | @ -24,8 +24,6 @@ | |||
| 
 | ||||
| package net.fabricmc.loom; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.HashSet; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
|  | @ -47,9 +45,7 @@ import org.gradle.api.publish.PublishingExtension; | |||
| import org.gradle.api.publish.maven.MavenPublication; | ||||
| import org.gradle.api.tasks.SourceSet; | ||||
| import org.gradle.api.tasks.bundling.AbstractArchiveTask; | ||||
| import org.gradle.api.tasks.compile.JavaCompile; | ||||
| import org.gradle.api.tasks.javadoc.Javadoc; | ||||
| import org.gradle.api.tasks.scala.ScalaCompile; | ||||
| import org.gradle.plugins.ide.idea.model.IdeaModel; | ||||
| 
 | ||||
| import net.fabricmc.loom.providers.LaunchProvider; | ||||
|  | @ -63,6 +59,9 @@ import net.fabricmc.loom.util.LoomDependencyManager; | |||
| import net.fabricmc.loom.util.NestedJars; | ||||
| import net.fabricmc.loom.util.RemappedConfigurationEntry; | ||||
| import net.fabricmc.loom.util.SetupIntelijRunConfigs; | ||||
| import net.fabricmc.loom.util.mixin.JavaApInvoker; | ||||
| import net.fabricmc.loom.util.mixin.KaptApInvoker; | ||||
| import net.fabricmc.loom.util.mixin.ScalaApInvoker; | ||||
| 
 | ||||
| public class AbstractPlugin implements Plugin<Project> { | ||||
| 	protected Project project; | ||||
|  | @ -88,7 +87,6 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 
 | ||||
| 		project.getExtensions().create("minecraft", LoomGradleExtension.class, project); | ||||
| 
 | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		// Force add Mojang repository | ||||
| 		addMavenRepo(target, "Mojang", "https://libraries.minecraft.net/"); | ||||
| 
 | ||||
|  | @ -127,74 +125,43 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 		extendsFrom("compileClasspath", Constants.MINECRAFT_NAMED); | ||||
| 		extendsFrom("runtimeClasspath", Constants.MINECRAFT_NAMED); | ||||
| 
 | ||||
| 		if (!extension.ideSync()) { | ||||
| 			extendsFrom("annotationProcessor", Constants.MINECRAFT_NAMED); | ||||
| 			extendsFrom("annotationProcessor", Constants.MOD_COMPILE_CLASSPATH_MAPPED); | ||||
| 		} | ||||
| 
 | ||||
| 		extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES); | ||||
| 
 | ||||
| 		extendsFrom("compile", Constants.MAPPINGS_FINAL); | ||||
| 
 | ||||
| 		if (!extension.ideSync()) { | ||||
| 			extendsFrom("annotationProcessor", Constants.MAPPINGS_FINAL); | ||||
| 		} | ||||
| 
 | ||||
| 		configureIDEs(); | ||||
| 		configureCompile(); | ||||
| 		configureScala(); | ||||
| 		configureMixin(); | ||||
| 		configureMaven(); | ||||
| 	} | ||||
| 
 | ||||
| 		Map<Project, Set<Task>> taskMap = project.getAllTasks(true); | ||||
| 
 | ||||
| 		for (Map.Entry<Project, Set<Task>> entry : taskMap.entrySet()) { | ||||
| 			Project project = entry.getKey(); | ||||
| 			Set<Task> taskSet = entry.getValue(); | ||||
| 
 | ||||
| 			for (Task task : taskSet) { | ||||
| 				if (task instanceof JavaCompile && !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { | ||||
| 					JavaCompile javaCompileTask = (JavaCompile) task; | ||||
| 					javaCompileTask.doFirst(task1 -> { | ||||
| 						project.getLogger().lifecycle(":setting java compiler args"); | ||||
| 
 | ||||
| 						try { | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath()); | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath()); | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(javaCompileTask.getDestinationDir(), extension.getRefmapName()).getCanonicalPath()); | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary"); | ||||
| 						} catch (IOException e) { | ||||
| 							e.printStackTrace(); | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
| 	private void configureMixin() { | ||||
| 		if (project.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { | ||||
| 			// If loom is applied after kapt, then kapt will use the AP arguments too early for loom to pass the arguments we need for mixin. | ||||
| 			throw new IllegalArgumentException("fabric-loom must be applied BEFORE kapt in the plugins { } block."); | ||||
| 		} | ||||
| 
 | ||||
| 		configureMaven(); | ||||
| 		// Full plugin and mappings information is only available after evaluation | ||||
| 		project.afterEvaluate((project) -> { | ||||
| 			project.getLogger().lifecycle("Configuring mixins for Java plugin"); | ||||
| 			new JavaApInvoker(project).configureMixin(); | ||||
| 
 | ||||
| 			if (project.getPluginManager().hasPlugin("scala")) { | ||||
| 				project.getLogger().lifecycle("Configuring mixins for Scala plugin"); | ||||
| 				new ScalaApInvoker(project).configureMixin(); | ||||
| 			} | ||||
| 
 | ||||
| 			if (project.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { | ||||
| 				project.getLogger().lifecycle("Configuring mixins for Kapt plugin"); | ||||
| 				new KaptApInvoker(project).configureMixin(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	public Project getProject() { | ||||
| 		return project; | ||||
| 	} | ||||
| 
 | ||||
| 	protected void configureScala() { | ||||
| 		project.afterEvaluate(proj -> { | ||||
| 			if (project.getPluginManager().hasPlugin("scala")) { | ||||
| 				ScalaCompile task = (ScalaCompile) project.getTasks().getByName("compileScala"); | ||||
| 				LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 				project.getLogger().warn(":configuring scala compilation processing"); | ||||
| 
 | ||||
| 				try { | ||||
| 					task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath()); | ||||
| 					task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath()); | ||||
| 					task.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath()); | ||||
| 					task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary"); | ||||
| 				} catch (IOException e) { | ||||
| 					e.printStackTrace(); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Permit to add a Maven repository to a target project. | ||||
| 	 * | ||||
|  | @ -234,11 +201,6 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 		Javadoc javadoc = (Javadoc) project.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); | ||||
| 		javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); | ||||
| 
 | ||||
| 		if (!project.getExtensions().getByType(LoomGradleExtension.class).ideSync()) { | ||||
| 			// Add Mixin dependencies | ||||
| 			project.getDependencies().add(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, "net.fabricmc:fabric-mixin-compile-extensions:" + Constants.MIXIN_COMPILE_EXTENSIONS_VERSION); | ||||
| 		} | ||||
| 
 | ||||
| 		project.afterEvaluate(project1 -> { | ||||
| 			LoomGradleExtension extension = project1.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 
 | ||||
|  |  | |||
|  | @ -311,7 +311,7 @@ public class LoomGradleExtension { | |||
| 	public String getRefmapName() { | ||||
| 		if (refmapName == null || refmapName.isEmpty()) { | ||||
| 			String defaultRefmapName = project.getConvention().getPlugin(BasePluginConvention.class).getArchivesBaseName() + "-refmap.json"; | ||||
| 			project.getLogger().warn("Could not find refmap definition, will be using default name: " + defaultRefmapName); | ||||
| 			project.getLogger().info("Could not find refmap definition, will be using default name: " + defaultRefmapName); | ||||
| 			refmapName = defaultRefmapName; | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,118 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 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.mixin; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Stream; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.Task; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.artifacts.ConfigurationContainer; | ||||
| import org.gradle.api.plugins.JavaPluginConvention; | ||||
| import org.gradle.api.tasks.SourceSet; | ||||
| import org.gradle.api.tasks.TaskCollection; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| 
 | ||||
| /** | ||||
|  * Normally javac invokes annotation processors, but when the scala or kapt plugin are installed they will want to invoke | ||||
|  * the annotation processor themselves. | ||||
|  * See Java and Kapt implementations for a more deep understanding of the things passed by the children. | ||||
|  */ | ||||
| public abstract class AnnotationProcessorInvoker<T extends Task> { | ||||
| 	protected final Project project; | ||||
| 	private final Collection<Configuration> annotationProcessorConfigurations; | ||||
| 	protected final TaskCollection<T> invokerTasks; | ||||
| 
 | ||||
| 	protected AnnotationProcessorInvoker(Project project, | ||||
| 										Collection<Configuration> annotationProcessorConfigurations, | ||||
| 										TaskCollection<T> invokerTasks) { | ||||
| 		this.project = project; | ||||
| 		this.annotationProcessorConfigurations = annotationProcessorConfigurations; | ||||
| 		this.invokerTasks = invokerTasks; | ||||
| 	} | ||||
| 
 | ||||
| 	protected abstract void passArgument(T compileTask, String key, String value); | ||||
| 
 | ||||
| 	protected abstract File getDestinationDir(T task); | ||||
| 
 | ||||
| 	protected final String getRefmapDestination(T task, LoomGradleExtension extension) throws IOException { | ||||
| 		return new File(getDestinationDir(task), extension.getRefmapName()).getCanonicalPath(); | ||||
| 	} | ||||
| 
 | ||||
| 	private void passMixinArguments(T task) { | ||||
| 		try { | ||||
| 			LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 			Map<String, String> args = new HashMap<String, String>() {{ | ||||
| 					put("inMapFileNamedIntermediary", extension.getMappingsProvider().tinyMappings.getCanonicalPath()); | ||||
| 					put("outMapFileNamedIntermediary", extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath()); | ||||
| 					put("outRefMapFile", getRefmapDestination(task, extension)); | ||||
| 					put("defaultObfuscationEnv", "named:intermediary"); | ||||
| 				}}; | ||||
| 
 | ||||
| 			project.getLogger().info("Outputting refmap to dir: " + getDestinationDir(task) + " for compile task: " + task); | ||||
| 			args.forEach((k, v) -> passArgument(task, k, v)); | ||||
| 		} catch (IOException e) { | ||||
| 			project.getLogger().error("Could not configure mixin annotation processors", e); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void configureMixin() { | ||||
| 		ConfigurationContainer configs = project.getConfigurations(); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 
 | ||||
| 		if (!extension.ideSync()) { | ||||
| 			for (Configuration processorConfig : annotationProcessorConfigurations) { | ||||
| 				project.getLogger().info("Adding mixin to classpath of AP config: " + processorConfig.getName()); | ||||
| 				// Pass named MC classpath to mixin AP classpath | ||||
| 				processorConfig.extendsFrom( | ||||
| 								configs.getByName(Constants.MINECRAFT_NAMED), | ||||
| 								configs.getByName(Constants.MOD_COMPILE_CLASSPATH_MAPPED), | ||||
| 								configs.getByName(Constants.MAPPINGS_FINAL) | ||||
| 				); | ||||
| 
 | ||||
| 				// Add Mixin and mixin extensions (fabric-mixin-compile-extensions pulls mixin itself too) | ||||
| 				project.getDependencies().add(processorConfig.getName(), | ||||
| 								"net.fabricmc:fabric-mixin-compile-extensions:" + Constants.MIXIN_COMPILE_EXTENSIONS_VERSION); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for (T task : invokerTasks) { | ||||
| 			passMixinArguments(task); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	static Stream<SourceSet> getNonTestSourceSets(Project project) { | ||||
| 		return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets() | ||||
| 						.stream() | ||||
| 						.filter(sourceSet -> !sourceSet.getName().equals("test")); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,63 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 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.mixin; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.plugins.JavaPlugin; | ||||
| import org.gradle.api.tasks.compile.JavaCompile; | ||||
| 
 | ||||
| public class JavaApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||
| 	public JavaApInvoker(Project project) { | ||||
| 		super(project, getConfigurations(project), project.getTasks().withType(JavaCompile.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void passArgument(JavaCompile compileTask, String key, String value) { | ||||
| 		compileTask.getOptions().getCompilerArgs().add("-A" + key + "=" + value); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected File getDestinationDir(JavaCompile task) { | ||||
| 		return task.getDestinationDir(); | ||||
| 	} | ||||
| 
 | ||||
| 	private static List<Configuration> getConfigurations(Project project) { | ||||
| 		// java plugin generates an AP configuration for every source set based off of the getAptConfigurationName method. | ||||
| 		return AnnotationProcessorInvoker.getNonTestSourceSets(project) | ||||
| 						.map(sourceSet -> project.getConfigurations() | ||||
| 										.getByName(getAptConfigurationName(sourceSet.getName())) | ||||
| 						).collect(Collectors.toList()); | ||||
| 	} | ||||
| 
 | ||||
| 	private static String getAptConfigurationName(String sourceSet) { | ||||
| 		// This is documented by the gradle 4.6 release notes https://docs.gradle.org/4.6/release-notes.html#potential-breaking-changes | ||||
| 		return sourceSet.equals("main") ? JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME : sourceSet + "AnnotationProcessor"; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										113
									
								
								src/main/java/net/fabricmc/loom/util/mixin/KaptApInvoker.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/main/java/net/fabricmc/loom/util/mixin/KaptApInvoker.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,113 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 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.mixin; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.tasks.compile.JavaCompile; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin; | ||||
| import org.jetbrains.kotlin.gradle.plugin.KaptExtension; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| 
 | ||||
| public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||
| 	private final KaptExtension kaptExtension = project.getExtensions().getByType(KaptExtension.class); | ||||
| 	// Refmap will be written to here with mixin, then moved after JavaCompile to the correct place | ||||
| 	private final File dummyRefmapDirectory; | ||||
| 
 | ||||
| 	public KaptApInvoker(Project project) { | ||||
| 		super(project, getConfigurations(project), project.getTasks().withType(JavaCompile.class)); | ||||
| 
 | ||||
| 		try { | ||||
| 			dummyRefmapDirectory = Files.createTempDirectory("temp_refmap").toFile(); | ||||
| 		} catch (IOException e) { | ||||
| 			throw new RuntimeException(e); | ||||
| 		} | ||||
| 
 | ||||
| 		dummyRefmapDirectory.deleteOnExit(); | ||||
| 
 | ||||
| 		// Needed for mixin AP to run | ||||
| 		kaptExtension.setIncludeCompileClasspath(false); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void configureMixin() { | ||||
| 		super.configureMixin(); | ||||
| 
 | ||||
| 		for (JavaCompile task : invokerTasks) { | ||||
| 			// Kapt only allows specifying javac args to all annotation processors at once. So we need to specify some dummy | ||||
| 			// target location for the refmap and then move it to the correct place for each sourceset | ||||
| 			task.doLast(t -> { | ||||
| 				try { | ||||
| 					LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 					Path src = Paths.get(getRefmapDestination(task, extension)); | ||||
| 					Path dest = Paths.get(task.getDestinationDir().toString(), extension.getRefmapName()); | ||||
| 
 | ||||
| 					// Possible that no mixin annotations exist | ||||
| 					if (Files.exists(src)) { | ||||
| 						project.getLogger().info("Copying refmap from " + src + " to " + dest); | ||||
| 						Files.move(src, dest); | ||||
| 					} | ||||
| 				} catch (IOException e) { | ||||
| 					project.getLogger().warn("Could not move refmap generated by kapt for task " + task, e); | ||||
| 				} | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@NotNull | ||||
| 	private static List<Configuration> getConfigurations(Project project) { | ||||
| 		// Kapt generates an AP configuration for every source set based off of the getKaptConfigurationName method. | ||||
| 		return AnnotationProcessorInvoker.getNonTestSourceSets(project) | ||||
| 						.map(sourceSet -> project.getConfigurations() | ||||
| 										.getByName(Kapt3KotlinGradleSubplugin.Companion.getKaptConfigurationName(sourceSet.getName())) | ||||
| 						).collect(Collectors.toList()); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void passArgument(JavaCompile compileTask, String key, String value) { | ||||
| 		// Note: this MUST be run early on, before kapt uses this data, and there is only a point to setting the value once since | ||||
| 		// kapt shares the options with all java compilers | ||||
| 		kaptExtension.arguments(args -> { | ||||
| 			args.arg(key, value); | ||||
| 			return Unit.INSTANCE; | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected File getDestinationDir(JavaCompile task) { | ||||
| 		return dummyRefmapDirectory; | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,50 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 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.mixin; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| import com.google.common.collect.ImmutableList; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.tasks.scala.ScalaCompile; | ||||
| 
 | ||||
| public class ScalaApInvoker extends AnnotationProcessorInvoker<ScalaCompile> { | ||||
| 	public ScalaApInvoker(Project project) { | ||||
| 		super(project, | ||||
| 						// Scala just uses the java AP configuration afaik. This of course assumes the java AP also gets configured. | ||||
| 						ImmutableList.of(), | ||||
| 						project.getTasks().withType(ScalaCompile.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void passArgument(ScalaCompile compileTask, String key, String value) { | ||||
| 		compileTask.getOptions().getCompilerArgs().add("-A" + key + "=" + value); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected File getDestinationDir(ScalaCompile task) { | ||||
| 		return task.getDestinationDir(); | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in a new issue