Kapt: Support KotlinOptions class in KaptWithoutKotlincTask

This commit is contained in:
Yan Zhulanow
2018-11-06 15:19:38 +09:00
parent 7e4069f114
commit ecc44419b6
3 changed files with 57 additions and 47 deletions
@@ -343,7 +343,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}") pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}") pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
pluginOptions += SubpluginOption("strictMode", "${kaptExtension.strictMode}") pluginOptions += SubpluginOption("strictMode", "${kaptExtension.strictMode}")
pluginOptions += SubpluginOption("detectMemoryLeaks", "${kaptExtension.detectMemoryLeaks}") pluginOptions += SubpluginOption("detectMemoryLeaks", kaptExtension.detectMemoryLeaks)
pluginOptions += SubpluginOption("infoAsWarnings", "${project.isInfoAsWarnings()}") pluginOptions += SubpluginOption("infoAsWarnings", "${project.isInfoAsWarnings()}")
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir())) pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
@@ -55,30 +55,34 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor
compileClasspath.addAll(0, PathUtil.getJdkClassesRootsFromCurrentJre()) compileClasspath.addAll(0, PathUtil.getJdkClassesRootsFromCurrentJre())
} }
val paths = KaptPathsForWorker( val kaptFlagsForWorker = mutableSetOf<String>().apply {
if (isVerbose) add("VERBOSE")
if (mapDiagnosticLocations) add("MAP_DIAGNOSTIC_LOCATIONS")
}
val optionsForWorker = KaptOptionsForWorker(
project.projectDir, project.projectDir,
compileClasspath, compileClasspath,
kaptClasspath.files.toList(),
javaSourceRoots.toList(), javaSourceRoots.toList(),
destinationDir, destinationDir,
classesDir, classesDir,
stubsDir stubsDir,
)
val options = KaptOptionsForWorker( kaptClasspath.files.toList(),
isVerbose,
mapDiagnosticLocations,
annotationProcessorFqNames, annotationProcessorFqNames,
processorOptions, processorOptions,
javacOptions javacOptions,
kaptFlagsForWorker
) )
val kaptClasspath = kaptJars + findKotlinStdlibClasspath(project) val kaptClasspath = kaptJars + findKotlinStdlibClasspath(project)
workerExecutor.submit(KaptExecution::class.java) { config -> workerExecutor.submit(KaptExecution::class.java) { config ->
config.isolationMode = IsolationMode.PROCESS config.isolationMode = IsolationMode.PROCESS
config.params(options, paths, findToolsJar(), kaptClasspath) config.params(optionsForWorker, findToolsJar(), kaptClasspath)
logger.info("Kapt worker classpath: ${config.classpath}") logger.info("Kapt worker classpath: ${config.classpath}")
} }
@@ -87,40 +91,29 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor
} }
private class KaptExecution @Inject constructor( private class KaptExecution @Inject constructor(
val options: KaptOptionsForWorker, val optionsForWorker: KaptOptionsForWorker,
val paths: KaptPathsForWorker,
val toolsJar: File?, val toolsJar: File?,
val kaptClasspath: List<File> val kaptClasspath: List<File>
) : Runnable { ) : Runnable {
private companion object { private companion object {
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context" private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
private fun kaptClass(classLoader: ClassLoader) = Class.forName("org.jetbrains.kotlin.kapt3.base.Kapt", true, classLoader)
} }
override fun run(): Unit = with(options) { override fun run(): Unit = with(optionsForWorker) {
val kaptClasspathUrls = kaptClasspath.map { it.toURI().toURL() }.toTypedArray() val kaptClasspathUrls = kaptClasspath.map { it.toURI().toURL() }.toTypedArray()
val rootClassLoader = findRootClassLoader() val rootClassLoader = findRootClassLoader()
val classLoaderWithToolsJar = if (toolsJar != null && !javacIsAlreadyHere()) { val classLoaderWithToolsJar = if (toolsJar != null && !javacIsAlreadyHere()) {
toolsJar.let { URLClassLoader(arrayOf(it.toURI().toURL()), rootClassLoader) } URLClassLoader(arrayOf(toolsJar.toURI().toURL()), rootClassLoader)
} else { } else {
rootClassLoader rootClassLoader
} }
val kaptClassLoader = URLClassLoader(kaptClasspathUrls, classLoaderWithToolsJar) val kaptClassLoader = URLClassLoader(kaptClasspathUrls, classLoaderWithToolsJar)
val kaptMethod = kaptClass(kaptClassLoader).declaredMethods.single { it.name == "kapt" }
val kaptMethod = Class.forName("org.jetbrains.kotlin.kapt3.base.Kapt", true, kaptClassLoader) kaptMethod.invoke(null, createKaptOptions(kaptClassLoader))
.declaredMethods.single { it.name == "kapt" }
kaptMethod.invoke(
null,
createKaptPaths(kaptClassLoader),
isVerbose,
mapDiagnosticLocations,
annotationProcessorFqNames,
processorOptions,
javacOptions
)
} }
private fun javacIsAlreadyHere(): Boolean { private fun javacIsAlreadyHere(): Boolean {
@@ -131,16 +124,34 @@ private class KaptExecution @Inject constructor(
} }
} }
private fun createKaptPaths(classLoader: ClassLoader) = with(paths) { private fun createKaptOptions(classLoader: ClassLoader) = with (optionsForWorker) {
Class.forName("org.jetbrains.kotlin.kapt3.base.KaptPaths", true, classLoader).constructors.single().newInstance( val flags = kaptClass(classLoader).declaredMethods.single { it.name == "kaptFlags" }.invoke(null, flags)
val mode = Class.forName("org.jetbrains.kotlin.base.kapt3.AptMode", true, classLoader)
.enumConstants.single { (it as Enum<*>).name == "APT_ONLY" }
val detectMemoryLeaksMode = Class.forName("org.jetbrains.kotlin.base.kapt3.DetectMemoryLeaksMode", true, classLoader)
.enumConstants.single { (it as Enum<*>).name == "NONE" }
Class.forName("org.jetbrains.kotlin.base.kapt3.KaptOptions", true, classLoader).constructors.single().newInstance(
projectBaseDir, projectBaseDir,
compileClasspath, compileClasspath,
annotationProcessingClasspath,
javaSourceRoots, javaSourceRoots,
sourcesOutputDir, sourcesOutputDir,
classFilesOutputDir, classesOutputDir,
stubsOutputDir, stubsOutputDir,
stubsOutputDir // sic! stubsOutputDir, // sic!
processingClasspath,
processors,
processingOptions,
javacOptions,
flags,
mode,
detectMemoryLeaksMode
) )
} }
@@ -154,19 +165,19 @@ private class KaptExecution @Inject constructor(
} }
private data class KaptOptionsForWorker( private data class KaptOptionsForWorker(
val isVerbose: Boolean,
val mapDiagnosticLocations: Boolean,
val annotationProcessorFqNames: List<String>,
val processorOptions: Map<String, String>,
val javacOptions: Map<String, String>
) : Serializable
private data class KaptPathsForWorker(
val projectBaseDir: File, val projectBaseDir: File,
val compileClasspath: List<File>, val compileClasspath: List<File>,
val annotationProcessingClasspath: List<File>,
val javaSourceRoots: List<File>, val javaSourceRoots: List<File>,
val sourcesOutputDir: File, val sourcesOutputDir: File,
val classFilesOutputDir: File, val classesOutputDir: File,
val stubsOutputDir: File val stubsOutputDir: File,
val processingClasspath: List<File>,
val processors: List<String>,
val processingOptions: Map<String, String>,
val javacOptions: Map<String, String>,
val flags: Set<String>
) : Serializable ) : Serializable
@@ -21,7 +21,6 @@ import org.gradle.api.Project
import java.util.* import java.util.*
open class KaptExtension { open class KaptExtension {
open var generateStubs: Boolean = false open var generateStubs: Boolean = false
open var inheritedAnnotations: Boolean = true open var inheritedAnnotations: Boolean = true
@@ -34,7 +33,7 @@ open class KaptExtension {
open var strictMode: Boolean = false open var strictMode: Boolean = false
open var detectMemoryLeaks: Boolean = true open var detectMemoryLeaks: String = "default"
@Deprecated("Use `annotationProcessor()` and `annotationProcessors()` instead") @Deprecated("Use `annotationProcessor()` and `annotationProcessors()` instead")
open var processors: String = "" open var processors: String = ""