Kapt: Allow running kapt using Workers API in Gradle
This commit is contained in:
+1
-6
@@ -46,12 +46,7 @@ class AndroidExtensionsSubpluginIndicator : Plugin<Project> {
|
||||
}
|
||||
|
||||
private fun addAndroidExtensionsRuntimeIfNeeded(project: Project) {
|
||||
val kotlinPluginWrapper = project.plugins.findPlugin(KotlinAndroidPluginWrapper::class.java) ?: run {
|
||||
project.logger.error("'kotlin-android' plugin should be enabled before 'kotlin-android-extensions'")
|
||||
return
|
||||
}
|
||||
|
||||
val kotlinPluginVersion = kotlinPluginWrapper.kotlinPluginVersion
|
||||
val kotlinPluginVersion = project.getKotlinPluginVersion() ?: return
|
||||
|
||||
project.configurations.all { configuration ->
|
||||
val name = configuration.name
|
||||
|
||||
+59
-21
@@ -21,6 +21,7 @@ import org.gradle.process.CommandLineArgumentProvider
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
|
||||
import org.jetbrains.kotlin.gradle.tasks.isWorkerAPISupported
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
@@ -71,6 +72,11 @@ abstract class KaptVariantData<T>(val variantData: T) {
|
||||
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
companion object {
|
||||
private val VERBOSE_OPTION_NAME = "kapt.verbose"
|
||||
private val USE_WORKER_API = "kapt.use.worker.api"
|
||||
|
||||
const val KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME = "kotlinKaptWorkerDependencies"
|
||||
|
||||
private val KAPT_KOTLIN_GENERATED = "kapt.kotlin.generated"
|
||||
|
||||
val MAIN_KAPT_CONFIGURATION_NAME = "kapt"
|
||||
|
||||
@@ -88,6 +94,14 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
return project.configurations.findByName(getKaptConfigurationName(sourceSetName))
|
||||
}
|
||||
|
||||
fun Project.isKaptVerbose(): Boolean {
|
||||
return hasProperty(VERBOSE_OPTION_NAME) && property(VERBOSE_OPTION_NAME) == "true"
|
||||
}
|
||||
|
||||
fun Project.isUseWorkerApi(): Boolean {
|
||||
return isWorkerAPISupported() && hasProperty(USE_WORKER_API) && property(USE_WORKER_API) == "true"
|
||||
}
|
||||
|
||||
fun findMainKaptConfiguration(project: Project) = project.findKaptConfiguration(MAIN_KAPT_CONFIGURATION_NAME)
|
||||
|
||||
fun createAptConfigurationIfNeeded(project: Project, sourceSetName: String): Configuration {
|
||||
@@ -183,7 +197,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
)
|
||||
|
||||
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
||||
val kaptTask = context.createKaptKotlinTask()
|
||||
val kaptTask = context.createKaptKotlinTask(useWorkerApi = project.isUseWorkerApi())
|
||||
|
||||
kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray())
|
||||
|
||||
@@ -224,14 +238,26 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
||||
}
|
||||
|
||||
kotlinSourcesOutputDir.mkdirs()
|
||||
|
||||
val apOptions = getAPOptions()
|
||||
|
||||
pluginOptions += CompositeSubpluginOption("apoptions", encodeList(apOptions.associate { it.key to it.value }), apOptions)
|
||||
|
||||
pluginOptions += SubpluginOption("javacArguments", encodeList(kaptExtension.getJavacOptions()))
|
||||
|
||||
addMiscOptions(pluginOptions)
|
||||
|
||||
return pluginOptions
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.getAPOptions(): List<SubpluginOption> {
|
||||
val androidPlugin = kaptVariantData?.let {
|
||||
project.extensions.findByName("android") as? BaseExtension
|
||||
}
|
||||
|
||||
val androidOptions = kaptVariantData?.annotationProcessorOptions ?: emptyMap()
|
||||
|
||||
kotlinSourcesOutputDir.mkdirs()
|
||||
|
||||
val apOptionsFromProviders =
|
||||
if (isGradleVersionAtLeast(4, 6))
|
||||
kaptVariantData?.annotationProcessorOptionProviders
|
||||
@@ -245,16 +271,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
androidOptions.toList() +
|
||||
apOptionsFromProviders
|
||||
|
||||
val apOptions = apOptionsPairsList.map { SubpluginOption(it.first, it.second) } +
|
||||
FilesSubpluginOption("kapt.kotlin.generated", listOf(kotlinSourcesOutputDir))
|
||||
|
||||
pluginOptions += CompositeSubpluginOption("apoptions", encodeList(apOptions.associate { it.key to it.value }), apOptions)
|
||||
|
||||
pluginOptions += SubpluginOption("javacArguments", encodeList(kaptExtension.getJavacOptions()))
|
||||
|
||||
addMiscOptions(pluginOptions)
|
||||
|
||||
return pluginOptions
|
||||
return apOptionsPairsList.map { SubpluginOption(it.first, it.second) } +
|
||||
FilesSubpluginOption(KAPT_KOTLIN_GENERATED, listOf(kotlinSourcesOutputDir))
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
|
||||
@@ -298,15 +316,14 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
|
||||
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
|
||||
|
||||
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
|
||||
if (project.isKaptVerbose()) {
|
||||
pluginOptions += SubpluginOption("verbose", "true")
|
||||
}
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(): KaptTask {
|
||||
val kaptTask = project.tasks.create(
|
||||
getKaptTaskName("kapt"),
|
||||
KaptTask::class.java)
|
||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean): KaptTask {
|
||||
val taskClass = if (useWorkerApi) KaptWithoutKotlincTask::class.java else KaptWithKotlincTask::class.java
|
||||
val kaptTask = project.tasks.create(getKaptTaskName("kapt"), taskClass)
|
||||
|
||||
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
||||
|
||||
@@ -333,11 +350,32 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations
|
||||
|
||||
kaptVariantData?.annotationProcessorOptionProviders?.let {
|
||||
kaptTask.annotationProcessorOptionProviders.add(it)
|
||||
if (kaptTask is KaptWithKotlincTask) {
|
||||
kaptVariantData?.annotationProcessorOptionProviders?.let {
|
||||
kaptTask.annotationProcessorOptionProviders.add(it)
|
||||
}
|
||||
|
||||
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt")
|
||||
}
|
||||
|
||||
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt")
|
||||
if (kaptTask is KaptWithoutKotlincTask) {
|
||||
project.configurations.create(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).apply {
|
||||
project.getKotlinPluginVersion()?.let { kotlinPluginVersion ->
|
||||
val kaptDependency = getPluginArtifact().run { "$groupId:$artifactId:$kotlinPluginVersion" }
|
||||
dependencies.add(project.dependencies.create(kaptDependency))
|
||||
} ?: project.logger.error("Kotlin plugin should be enabled before 'kotlin-kapt'")
|
||||
}
|
||||
|
||||
with(kaptTask) {
|
||||
projectDir = project.projectDir
|
||||
|
||||
isVerbose = project.isKaptVerbose()
|
||||
mapDiagnosticLocations = kaptExtension.mapDiagnosticLocations
|
||||
annotationProcessorFqNames = kaptExtension.processors.split(',').filter { it.isNotEmpty() }
|
||||
processorOptions = getAPOptions().map { it.key to it.value }.toMap()
|
||||
javacOptions = kaptExtension.getJavacOptions()
|
||||
}
|
||||
}
|
||||
|
||||
return kaptTask
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.ConventionTask
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.compareVersionNumbers
|
||||
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.isJavaFile
|
||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
||||
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
||||
import java.io.File
|
||||
|
||||
@CacheableTask
|
||||
open class KaptTask : ConventionTask() {
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
|
||||
if (isBuildCacheSupported()) {
|
||||
val reason = "Caching is disabled by default for kapt because of arbitrary behavior of external " +
|
||||
"annotation processors. You can enable it by adding 'kapt.useBuildCache = true' to the build script."
|
||||
outputs.cacheIf(reason) { useBuildCache }
|
||||
}
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var stubsDir: File
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val kaptClasspath: FileCollection
|
||||
get() = project.files(*kaptClasspathConfigurations.toTypedArray())
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val compilerClasspath: List<File> get() = kotlinCompileTask.computedCompilerClasspath
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kaptClasspathConfigurations: List<Configuration>
|
||||
|
||||
@get:OutputDirectory
|
||||
internal lateinit var classesDir: File
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var destinationDir: File
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var kotlinSourcesDestinationDir: File
|
||||
|
||||
@get:Nested
|
||||
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val classpath: FileCollection
|
||||
get() = kotlinCompileTask.classpath
|
||||
|
||||
@get:Internal
|
||||
var useBuildCache: Boolean = false
|
||||
|
||||
@get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
val source: Collection<File>
|
||||
get() {
|
||||
val result = HashSet<File>()
|
||||
for (root in javaSourceRoots) {
|
||||
root.walk().filterTo(result) { it.isJavaFile() }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
protected val javaSourceRoots: Set<File>
|
||||
get() = (kotlinCompileTask.sourceRootsContainer.sourceRoots + stubsDir)
|
||||
.filterTo(HashSet(), ::isRootAllowed)
|
||||
|
||||
private fun isRootAllowed(file: File): Boolean =
|
||||
!FileUtil.isAncestor(destinationDir, file, /* strict = */ false) &&
|
||||
!FileUtil.isAncestor(classesDir, file, /* strict = */ false)
|
||||
}
|
||||
+26
-77
@@ -1,65 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.ConventionTask
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.Classpath
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.compareVersionNumbers
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
|
||||
import org.jetbrains.kotlin.gradle.tasks.clearOutputDirectories
|
||||
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
|
||||
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.isJavaFile
|
||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
||||
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
||||
import java.io.File
|
||||
|
||||
@CacheableTask
|
||||
open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
|
||||
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
|
||||
if (isBuildCacheSupported()) {
|
||||
val reason = "Caching is disabled by default for kapt because of arbitrary behavior of external " +
|
||||
"annotation processors. You can enable it by adding 'kapt.useBuildCache = true' to the build script."
|
||||
outputs.cacheIf(reason) { useBuildCache }
|
||||
}
|
||||
}
|
||||
|
||||
open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
|
||||
@get:Internal
|
||||
internal val pluginOptions = CompilerPluginOptions()
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||
@get:Classpath
|
||||
@get:InputFiles
|
||||
@Suppress("unused")
|
||||
internal val kotlinTaskPluginClasspaths get() = kotlinCompileTask.pluginClasspath
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var stubsDir: File
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val kaptClasspath: FileCollection
|
||||
get() = project.files(*kaptClasspathConfigurations.toTypedArray())
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val compilerClasspath: List<File> get() = kotlinCompileTask.computedCompilerClasspath
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kaptClasspathConfigurations: List<Configuration>
|
||||
|
||||
@get:OutputDirectory
|
||||
internal lateinit var classesDir: File
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var destinationDir: File
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var kotlinSourcesDestinationDir: File
|
||||
|
||||
@get:Nested
|
||||
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
@get:Classpath
|
||||
@get:InputFiles
|
||||
val pluginClasspath: FileCollection
|
||||
get() = project.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
|
||||
|
||||
override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
|
||||
|
||||
@@ -74,37 +50,10 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
|
||||
args.verbose = project.hasProperty("kapt.verbose") && project.property("kapt.verbose").toString().toBoolean() == true
|
||||
}
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
val classpath: FileCollection
|
||||
get() = kotlinCompileTask.classpath
|
||||
|
||||
@get:Internal
|
||||
var useBuildCache: Boolean = false
|
||||
|
||||
@get:Classpath
|
||||
@get:InputFiles
|
||||
val pluginClasspath: FileCollection
|
||||
get() = project.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
|
||||
|
||||
@get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
val source: Collection<File>
|
||||
get() {
|
||||
val result = HashSet<File>()
|
||||
for (root in javaSourceRoots) {
|
||||
root.walk().filterTo(result) { it.isJavaFile() }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private val javaSourceRoots: Set<File>
|
||||
get() = (kotlinCompileTask.sourceRootsContainer.sourceRoots + stubsDir)
|
||||
.filterTo(HashSet(), ::isRootAllowed)
|
||||
|
||||
private fun isRootAllowed(file: File): Boolean =
|
||||
!destinationDir.isParentOf(file) && !classesDir.isParentOf(file)
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
logger.debug("Running kapt annotation processing using the Kotlin compiler")
|
||||
|
||||
/** Delete everything inside generated sources and classes output directory
|
||||
* (annotation processing is not incremental) */
|
||||
clearOutputDirectories()
|
||||
@@ -130,7 +79,7 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
|
||||
}
|
||||
|
||||
private val isAtLeastJava9: Boolean
|
||||
get() = compareVersionNumbers(getJavaRuntimeVersion(), "9") >= 0
|
||||
get() = StringUtil.compareVersionNumbers(getJavaRuntimeVersion(), "9") >= 0
|
||||
|
||||
private fun getJavaRuntimeVersion(): String {
|
||||
val rtVersion = System.getProperty("java.runtime.version")
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.workers.IsolationMode
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.clearOutputDirectories
|
||||
import org.jetbrains.kotlin.gradle.tasks.findKotlinStdlibClasspath
|
||||
import org.jetbrains.kotlin.gradle.tasks.findToolsJar
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.net.URLClassLoader
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor: WorkerExecutor) : KaptTask() {
|
||||
@get:InputFiles
|
||||
@get:Classpath
|
||||
@Suppress("unused")
|
||||
val kaptJars: Collection<File>
|
||||
get() = project.configurations.getByName(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).resolve()
|
||||
|
||||
@get:InputFile
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
lateinit var projectDir: File
|
||||
|
||||
@get:Input
|
||||
var isVerbose: Boolean = false
|
||||
|
||||
@get:Input
|
||||
var mapDiagnosticLocations: Boolean = false
|
||||
|
||||
@get:Input
|
||||
lateinit var annotationProcessorFqNames: List<String>
|
||||
|
||||
@get:Input
|
||||
lateinit var processorOptions: Map<String, String>
|
||||
|
||||
@get:Input
|
||||
lateinit var javacOptions: Map<String, String>
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
logger.info("Running kapt annotation processing using the Gradle Worker API")
|
||||
|
||||
clearOutputDirectories()
|
||||
|
||||
val paths = KaptPathsForWorker(
|
||||
projectDir,
|
||||
classpath.files.toList(),
|
||||
kaptClasspath.files.toList(),
|
||||
javaSourceRoots.toList(),
|
||||
destinationDir,
|
||||
classesDir,
|
||||
stubsDir
|
||||
)
|
||||
|
||||
val options = KaptOptionsForWorker(
|
||||
isVerbose,
|
||||
mapDiagnosticLocations,
|
||||
annotationProcessorFqNames,
|
||||
processorOptions,
|
||||
javacOptions
|
||||
)
|
||||
|
||||
val kaptClasspath = kaptJars + findKotlinStdlibClasspath(project)
|
||||
|
||||
workerExecutor.submit(KaptExecution::class.java) { config ->
|
||||
config.isolationMode = IsolationMode.PROCESS
|
||||
config.params(options, paths, findToolsJar(), kaptClasspath)
|
||||
|
||||
logger.info("Kapt worker classpath: ${config.classpath}")
|
||||
}
|
||||
|
||||
workerExecutor.await()
|
||||
}
|
||||
}
|
||||
|
||||
private class KaptExecution @Inject constructor(
|
||||
val options: KaptOptionsForWorker,
|
||||
val paths: KaptPathsForWorker,
|
||||
val toolsJar: File?,
|
||||
val kaptClasspath: List<File>
|
||||
) : Runnable {
|
||||
private companion object {
|
||||
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
|
||||
}
|
||||
|
||||
override fun run(): Unit = with(options) {
|
||||
val kaptClasspathUrls = kaptClasspath.map { it.toURI().toURL() }.toTypedArray()
|
||||
|
||||
val rootClassLoader = findRootClassLoader()
|
||||
|
||||
val classLoaderWithToolsJar = if (toolsJar != null && !javacIsAlreadyHere()) {
|
||||
toolsJar.let { URLClassLoader(arrayOf(it.toURI().toURL()), rootClassLoader) }
|
||||
} else {
|
||||
rootClassLoader
|
||||
}
|
||||
|
||||
val kaptClassLoader = URLClassLoader(kaptClasspathUrls, classLoaderWithToolsJar)
|
||||
|
||||
val kaptMethod = Class.forName("org.jetbrains.kotlin.kapt3.base.Kapt", true, kaptClassLoader)
|
||||
.declaredMethods.single { it.name == "kapt" }
|
||||
|
||||
kaptMethod.invoke(
|
||||
null,
|
||||
createKaptPaths(kaptClassLoader),
|
||||
isVerbose,
|
||||
mapDiagnosticLocations,
|
||||
annotationProcessorFqNames,
|
||||
processorOptions,
|
||||
javacOptions
|
||||
)
|
||||
}
|
||||
|
||||
private fun javacIsAlreadyHere(): Boolean {
|
||||
return try {
|
||||
Class.forName(JAVAC_CONTEXT_CLASS, false, KaptExecution::class.java.classLoader) != null
|
||||
} catch (e: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKaptPaths(classLoader: ClassLoader) = with(paths) {
|
||||
Class.forName("org.jetbrains.kotlin.kapt3.base.KaptPaths", true, classLoader).constructors.single().newInstance(
|
||||
projectBaseDir,
|
||||
compileClasspath,
|
||||
annotationProcessingClasspath,
|
||||
javaSourceRoots,
|
||||
sourcesOutputDir,
|
||||
classFilesOutputDir,
|
||||
stubsOutputDir,
|
||||
stubsOutputDir // sic!
|
||||
)
|
||||
}
|
||||
|
||||
private fun findRootClassLoader(): ClassLoader {
|
||||
tailrec fun parentOrSelf(classLoader: ClassLoader): ClassLoader {
|
||||
val parent = classLoader.parent ?: return classLoader
|
||||
return parentOrSelf(parent)
|
||||
}
|
||||
return parentOrSelf(KaptExecution::class.java.classLoader)
|
||||
}
|
||||
}
|
||||
|
||||
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 compileClasspath: List<File>,
|
||||
val annotationProcessingClasspath: List<File>,
|
||||
val javaSourceRoots: List<File>,
|
||||
val sourcesOutputDir: File,
|
||||
val classFilesOutputDir: File,
|
||||
val stubsOutputDir: File
|
||||
) : Serializable
|
||||
+9
@@ -82,6 +82,15 @@ open class Kotlin2JsPluginWrapper @Inject constructor(fileResolver: FileResolver
|
||||
Kotlin2JsPlugin(Kotlin2JsTasksProvider(), KotlinSourceSetProviderImpl(fileResolver), kotlinPluginVersion)
|
||||
}
|
||||
|
||||
fun Project.getKotlinPluginVersion(): String? {
|
||||
val kotlinPluginWrapper = plugins.findPlugin(KotlinAndroidPluginWrapper::class.java) ?: run {
|
||||
project.logger.error("'kotlin-android' plugin should be enabled before 'kotlin-android-extensions'")
|
||||
return null
|
||||
}
|
||||
|
||||
return kotlinPluginWrapper.kotlinPluginVersion
|
||||
}
|
||||
|
||||
private fun Any.loadKotlinVersionFromResource(log: Logger): String {
|
||||
log.kotlinDebug("Loading version information")
|
||||
val props = Properties()
|
||||
|
||||
+3
@@ -23,6 +23,9 @@ import org.jetbrains.kotlin.gradle.utils.outputsCompatible
|
||||
internal fun isBuildCacheSupported(): Boolean =
|
||||
gradleVersion >= GradleVersion.version("4.3")
|
||||
|
||||
internal fun isWorkerAPISupported(): Boolean =
|
||||
gradleVersion >= GradleVersion.version("4.3")
|
||||
|
||||
internal fun isBuildCacheEnabledForKotlin(): Boolean =
|
||||
isBuildCacheSupported() &&
|
||||
System.getProperty(KOTLIN_CACHING_ENABLED_PROPERTY)?.toBoolean() ?: true
|
||||
|
||||
Reference in New Issue
Block a user