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) {
|
private fun addAndroidExtensionsRuntimeIfNeeded(project: Project) {
|
||||||
val kotlinPluginWrapper = project.plugins.findPlugin(KotlinAndroidPluginWrapper::class.java) ?: run {
|
val kotlinPluginVersion = project.getKotlinPluginVersion() ?: return
|
||||||
project.logger.error("'kotlin-android' plugin should be enabled before 'kotlin-android-extensions'")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val kotlinPluginVersion = kotlinPluginWrapper.kotlinPluginVersion
|
|
||||||
|
|
||||||
project.configurations.all { configuration ->
|
project.configurations.all { configuration ->
|
||||||
val name = configuration.name
|
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.getKaptGeneratedClassesDir
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
|
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
|
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.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
@@ -71,6 +72,11 @@ abstract class KaptVariantData<T>(val variantData: T) {
|
|||||||
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||||
companion object {
|
companion object {
|
||||||
private val VERBOSE_OPTION_NAME = "kapt.verbose"
|
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"
|
val MAIN_KAPT_CONFIGURATION_NAME = "kapt"
|
||||||
|
|
||||||
@@ -88,6 +94,14 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
return project.configurations.findByName(getKaptConfigurationName(sourceSetName))
|
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 findMainKaptConfiguration(project: Project) = project.findKaptConfiguration(MAIN_KAPT_CONFIGURATION_NAME)
|
||||||
|
|
||||||
fun createAptConfigurationIfNeeded(project: Project, sourceSetName: String): Configuration {
|
fun createAptConfigurationIfNeeded(project: Project, sourceSetName: String): Configuration {
|
||||||
@@ -183,7 +197,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
||||||
val kaptTask = context.createKaptKotlinTask()
|
val kaptTask = context.createKaptKotlinTask(useWorkerApi = project.isUseWorkerApi())
|
||||||
|
|
||||||
kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray())
|
kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray())
|
||||||
|
|
||||||
@@ -224,14 +238,26 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
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 {
|
val androidPlugin = kaptVariantData?.let {
|
||||||
project.extensions.findByName("android") as? BaseExtension
|
project.extensions.findByName("android") as? BaseExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
val androidOptions = kaptVariantData?.annotationProcessorOptions ?: emptyMap()
|
val androidOptions = kaptVariantData?.annotationProcessorOptions ?: emptyMap()
|
||||||
|
|
||||||
kotlinSourcesOutputDir.mkdirs()
|
|
||||||
|
|
||||||
val apOptionsFromProviders =
|
val apOptionsFromProviders =
|
||||||
if (isGradleVersionAtLeast(4, 6))
|
if (isGradleVersionAtLeast(4, 6))
|
||||||
kaptVariantData?.annotationProcessorOptionProviders
|
kaptVariantData?.annotationProcessorOptionProviders
|
||||||
@@ -245,16 +271,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
androidOptions.toList() +
|
androidOptions.toList() +
|
||||||
apOptionsFromProviders
|
apOptionsFromProviders
|
||||||
|
|
||||||
val apOptions = apOptionsPairsList.map { SubpluginOption(it.first, it.second) } +
|
return apOptionsPairsList.map { SubpluginOption(it.first, it.second) } +
|
||||||
FilesSubpluginOption("kapt.kotlin.generated", listOf(kotlinSourcesOutputDir))
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
|
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
|
||||||
@@ -298,15 +316,14 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
|
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
|
||||||
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
|
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
|
||||||
|
|
||||||
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
|
if (project.isKaptVerbose()) {
|
||||||
pluginOptions += SubpluginOption("verbose", "true")
|
pluginOptions += SubpluginOption("verbose", "true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(): KaptTask {
|
private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean): KaptTask {
|
||||||
val kaptTask = project.tasks.create(
|
val taskClass = if (useWorkerApi) KaptWithoutKotlincTask::class.java else KaptWithKotlincTask::class.java
|
||||||
getKaptTaskName("kapt"),
|
val kaptTask = project.tasks.create(getKaptTaskName("kapt"), taskClass)
|
||||||
KaptTask::class.java)
|
|
||||||
|
|
||||||
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
||||||
|
|
||||||
@@ -333,11 +350,32 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
|
|
||||||
kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations
|
kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations
|
||||||
|
|
||||||
kaptVariantData?.annotationProcessorOptionProviders?.let {
|
if (kaptTask is KaptWithKotlincTask) {
|
||||||
kaptTask.annotationProcessorOptionProviders.add(it)
|
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
|
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
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.ConventionTask
|
import org.gradle.api.tasks.Classpath
|
||||||
import org.gradle.api.tasks.*
|
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.cli.common.arguments.K2JVMCompilerArguments
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
||||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
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.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 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
|
@get:Internal
|
||||||
internal val pluginOptions = CompilerPluginOptions()
|
internal val pluginOptions = CompilerPluginOptions()
|
||||||
|
|
||||||
@get:Internal
|
@get:Classpath
|
||||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
@get:InputFiles
|
||||||
|
@Suppress("unused")
|
||||||
|
internal val kotlinTaskPluginClasspaths get() = kotlinCompileTask.pluginClasspath
|
||||||
|
|
||||||
@get:Internal
|
@get:Classpath
|
||||||
internal lateinit var stubsDir: File
|
@get:InputFiles
|
||||||
|
val pluginClasspath: FileCollection
|
||||||
@get:Classpath @get:InputFiles
|
get() = project.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
|
||||||
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()
|
|
||||||
|
|
||||||
override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
|
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
|
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
|
@TaskAction
|
||||||
fun compile() {
|
fun compile() {
|
||||||
|
logger.debug("Running kapt annotation processing using the Kotlin compiler")
|
||||||
|
|
||||||
/** Delete everything inside generated sources and classes output directory
|
/** Delete everything inside generated sources and classes output directory
|
||||||
* (annotation processing is not incremental) */
|
* (annotation processing is not incremental) */
|
||||||
clearOutputDirectories()
|
clearOutputDirectories()
|
||||||
@@ -130,7 +79,7 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val isAtLeastJava9: Boolean
|
private val isAtLeastJava9: Boolean
|
||||||
get() = compareVersionNumbers(getJavaRuntimeVersion(), "9") >= 0
|
get() = StringUtil.compareVersionNumbers(getJavaRuntimeVersion(), "9") >= 0
|
||||||
|
|
||||||
private fun getJavaRuntimeVersion(): String {
|
private fun getJavaRuntimeVersion(): String {
|
||||||
val rtVersion = System.getProperty("java.runtime.version")
|
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)
|
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 {
|
private fun Any.loadKotlinVersionFromResource(log: Logger): String {
|
||||||
log.kotlinDebug("Loading version information")
|
log.kotlinDebug("Loading version information")
|
||||||
val props = Properties()
|
val props = Properties()
|
||||||
|
|||||||
+3
@@ -23,6 +23,9 @@ import org.jetbrains.kotlin.gradle.utils.outputsCompatible
|
|||||||
internal fun isBuildCacheSupported(): Boolean =
|
internal fun isBuildCacheSupported(): Boolean =
|
||||||
gradleVersion >= GradleVersion.version("4.3")
|
gradleVersion >= GradleVersion.version("4.3")
|
||||||
|
|
||||||
|
internal fun isWorkerAPISupported(): Boolean =
|
||||||
|
gradleVersion >= GradleVersion.version("4.3")
|
||||||
|
|
||||||
internal fun isBuildCacheEnabledForKotlin(): Boolean =
|
internal fun isBuildCacheEnabledForKotlin(): Boolean =
|
||||||
isBuildCacheSupported() &&
|
isBuildCacheSupported() &&
|
||||||
System.getProperty(KOTLIN_CACHING_ENABLED_PROPERTY)?.toBoolean() ?: true
|
System.getProperty(KOTLIN_CACHING_ENABLED_PROPERTY)?.toBoolean() ?: true
|
||||||
|
|||||||
Reference in New Issue
Block a user