Subplugin options refactoring & Gradle input improvements
Introduce FilesSubpluginOption Special kind of SubpluginOption that holds a list of files together with the kind of these files with respect to the task. Add a logic for handling such options and converting them into task inputs. Refactor CompilerPluginOptions: make it store subplugin options to be able to add options from KotlinCompile to the kapt tasks. Introduce WrapperSubpluginOption for encoded and complex options. Remove pluginOptions from the Gradle inputs built from the compiler args. Do not cache Kotlin compilation with kapt1 enabled: since we are going to drop kapt1 it anyway, there's no point in implementing proper cache for it, so just disable the caching of the task in case kapt1 is used.
This commit is contained in:
+17
-1
@@ -19,8 +19,24 @@ package org.jetbrains.kotlin.gradle.plugin
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.SourceSet
|
import org.gradle.api.tasks.SourceSet
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class SubpluginOption(val key: String, val value: String)
|
open class SubpluginOption(val key: String, open val value: String)
|
||||||
|
|
||||||
|
class FilesSubpluginOption(
|
||||||
|
key: String,
|
||||||
|
val kind: FileOptionKind,
|
||||||
|
val files: List<File>,
|
||||||
|
value: String = files.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||||
|
: SubpluginOption(key, value)
|
||||||
|
|
||||||
|
class WrapperSubpluginOption(
|
||||||
|
key: String,
|
||||||
|
value: String,
|
||||||
|
val originalOptions: List<SubpluginOption>)
|
||||||
|
: SubpluginOption(key, value)
|
||||||
|
|
||||||
|
enum class FileOptionKind { INPUT_FILES, CLASSPATH_INPUT, OUTPUT_FILES, OUTPUT_DIRS, INTERNAL }
|
||||||
|
|
||||||
interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
|
interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
|
||||||
fun isApplicable(project: Project, task: AbstractCompile): Boolean
|
fun isApplicable(project: Project, task: AbstractCompile): Boolean
|
||||||
|
|||||||
+13
-4
@@ -116,8 +116,13 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
pluginOptions += SubpluginOption("package", applicationPackage)
|
pluginOptions += SubpluginOption("package", applicationPackage)
|
||||||
|
|
||||||
fun addVariant(sourceSet: AndroidSourceSet) {
|
fun addVariant(sourceSet: AndroidSourceSet) {
|
||||||
pluginOptions += SubpluginOption("variant", sourceSet.name + ';' +
|
val optionValue = sourceSet.name + ';' +
|
||||||
sourceSet.res.srcDirs.joinToString(";") { it.absolutePath })
|
sourceSet.res.srcDirs.joinToString(";") { it.absolutePath }
|
||||||
|
pluginOptions += WrapperSubpluginOption("variant", optionValue, listOf(
|
||||||
|
SubpluginOption("sourceSetName", sourceSet.name),
|
||||||
|
//use the INTERNAL option kind since the resources are tracked as sources (see below)
|
||||||
|
FilesSubpluginOption("resDirs", FileOptionKind.INTERNAL, sourceSet.res.srcDirs.toList())
|
||||||
|
))
|
||||||
kotlinCompile.source(project.files(getLayoutDirectories(sourceSet.res.srcDirs)))
|
kotlinCompile.source(project.files(getLayoutDirectories(sourceSet.res.srcDirs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,11 +165,15 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet))
|
pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet))
|
||||||
|
|
||||||
fun addVariant(name: String, resDirectories: List<File>) {
|
fun addVariant(name: String, resDirectories: List<File>) {
|
||||||
pluginOptions += SubpluginOption("variant", buildString {
|
val optionValue = buildString {
|
||||||
append(name)
|
append(name)
|
||||||
append(';')
|
append(';')
|
||||||
resDirectories.joinTo(this, separator = ";") { it.canonicalPath }
|
resDirectories.joinTo(this, separator = ";") { it.canonicalPath }
|
||||||
})
|
}
|
||||||
|
pluginOptions += WrapperSubpluginOption("variant", optionValue, listOf(
|
||||||
|
SubpluginOption("variantName", name),
|
||||||
|
// use INTERNAL option kind since the resources are tracked as sources (see below)
|
||||||
|
FilesSubpluginOption("resDirs", FileOptionKind.INTERNAL, resDirectories)))
|
||||||
|
|
||||||
kotlinCompile.source(project.files(getLayoutDirectories(resDirectories)))
|
kotlinCompile.source(project.files(getLayoutDirectories(resDirectories)))
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
import org.jetbrains.kotlin.gradle.tasks.kapt.generateAnnotationProcessorWrapper
|
import org.jetbrains.kotlin.gradle.tasks.kapt.generateAnnotationProcessorWrapper
|
||||||
import org.jetbrains.kotlin.gradle.tasks.kapt.generateKotlinAptAnnotation
|
import org.jetbrains.kotlin.gradle.tasks.kapt.generateKotlinAptAnnotation
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.shouldEnableGradleCache
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
@@ -78,6 +79,11 @@ internal fun Project.initKapt(
|
|||||||
// javaTask.doLast {
|
// javaTask.doLast {
|
||||||
// moveGeneratedJavaFilesToCorrespondingDirectories(kaptManager.aptOutputDir)
|
// moveGeneratedJavaFilesToCorrespondingDirectories(kaptManager.aptOutputDir)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (shouldEnableGradleCache()) {
|
||||||
|
// Since Kapt1 is about to be dropped, disable the cache for it:
|
||||||
|
kotlinAfterJavaTask.outputs.doNotCacheIf("Caching is not supported with deprecated Kapt1") { true }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
kotlinAfterJavaTask = null
|
kotlinAfterJavaTask = null
|
||||||
kotlinTask.logger.kotlinDebug("kapt: Class file stubs are not used")
|
kotlinTask.logger.kotlinDebug("kapt: Class file stubs are not used")
|
||||||
@@ -103,6 +109,12 @@ internal fun Project.initKapt(
|
|||||||
}
|
}
|
||||||
|
|
||||||
kotlinTask.kaptOptions.annotationsFile = kaptManager.getAnnotationFile()
|
kotlinTask.kaptOptions.annotationsFile = kaptManager.getAnnotationFile()
|
||||||
|
|
||||||
|
if (shouldEnableGradleCache()) {
|
||||||
|
// Since Kapt1 is about to be dropped, disable the cache for it:
|
||||||
|
kotlinTask.outputs.doNotCacheIf("Caching is not supported with deprecated Kapt1") { true }
|
||||||
|
}
|
||||||
|
|
||||||
return kotlinAfterJavaTask
|
return kotlinAfterJavaTask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+413
-403
@@ -1,403 +1,413 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
import com.android.build.gradle.api.AndroidSourceSet
|
import com.android.build.gradle.api.AndroidSourceSet
|
||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.tasks.SourceSet
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.tasks.TaskDependency
|
import org.gradle.api.tasks.SourceSet
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.TaskDependency
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||||
import java.io.File
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir
|
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
|
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir
|
||||||
import org.jetbrains.kotlin.gradle.tasks.shouldEnableGradleCache
|
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
|
||||||
import org.jetbrains.kotlin.gradle.tasks.useBuildCacheIfSupported
|
import org.jetbrains.kotlin.gradle.tasks.shouldEnableGradleCache
|
||||||
import java.io.ByteArrayOutputStream
|
import org.jetbrains.kotlin.gradle.tasks.useBuildCacheIfSupported
|
||||||
import java.io.ObjectOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.util.*
|
import java.io.ObjectOutputStream
|
||||||
|
import java.util.*
|
||||||
// apply plugin: 'kotlin-kapt'
|
|
||||||
class Kapt3GradleSubplugin : Plugin<Project> {
|
// apply plugin: 'kotlin-kapt'
|
||||||
companion object {
|
class Kapt3GradleSubplugin : Plugin<Project> {
|
||||||
fun isEnabled(project: Project) = project.plugins.findPlugin(Kapt3GradleSubplugin::class.java) != null
|
companion object {
|
||||||
|
fun isEnabled(project: Project) = project.plugins.findPlugin(Kapt3GradleSubplugin::class.java) != null
|
||||||
@JvmStatic
|
|
||||||
fun getKaptGeneratedClassesDir(project: Project, sourceSetName: String) =
|
@JvmStatic
|
||||||
File(project.project.buildDir, "tmp/kapt3/classes/$sourceSetName")
|
fun getKaptGeneratedClassesDir(project: Project, sourceSetName: String) =
|
||||||
|
File(project.project.buildDir, "tmp/kapt3/classes/$sourceSetName")
|
||||||
@JvmStatic
|
|
||||||
fun getKaptGeneratedSourcesDir(project: Project, sourceSetName: String) =
|
@JvmStatic
|
||||||
File(project.project.buildDir, "generated/source/kapt/$sourceSetName")
|
fun getKaptGeneratedSourcesDir(project: Project, sourceSetName: String) =
|
||||||
|
File(project.project.buildDir, "generated/source/kapt/$sourceSetName")
|
||||||
@JvmStatic
|
|
||||||
fun getKaptGeneratedKotlinSourcesDir(project: Project, sourceSetName: String) =
|
@JvmStatic
|
||||||
File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName")
|
fun getKaptGeneratedKotlinSourcesDir(project: Project, sourceSetName: String) =
|
||||||
}
|
File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName")
|
||||||
|
}
|
||||||
override fun apply(project: Project) {}
|
|
||||||
}
|
override fun apply(project: Project) {}
|
||||||
|
}
|
||||||
abstract class KaptVariantData<T>(val variantData: T) {
|
|
||||||
abstract val name: String
|
abstract class KaptVariantData<T>(val variantData: T) {
|
||||||
abstract val sourceProviders: Iterable<SourceProvider>
|
abstract val name: String
|
||||||
abstract fun addJavaSourceFoldersToModel(generatedFilesDir: File)
|
abstract val sourceProviders: Iterable<SourceProvider>
|
||||||
abstract val annotationProcessorOptions: Map<String, String>?
|
abstract fun addJavaSourceFoldersToModel(generatedFilesDir: File)
|
||||||
abstract fun registerGeneratedJavaSource(
|
abstract val annotationProcessorOptions: Map<String, String>?
|
||||||
project: Project,
|
abstract fun registerGeneratedJavaSource(
|
||||||
kaptTask: KaptTask,
|
project: Project,
|
||||||
javaTask: AbstractCompile)
|
kaptTask: KaptTask,
|
||||||
}
|
javaTask: AbstractCompile)
|
||||||
|
}
|
||||||
// Subplugin for the Kotlin Gradle plugin
|
|
||||||
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
// Subplugin for the Kotlin Gradle plugin
|
||||||
companion object {
|
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||||
private val VERBOSE_OPTION_NAME = "kapt.verbose"
|
companion object {
|
||||||
|
private val VERBOSE_OPTION_NAME = "kapt.verbose"
|
||||||
val MAIN_KAPT_CONFIGURATION_NAME = "kapt"
|
|
||||||
|
val MAIN_KAPT_CONFIGURATION_NAME = "kapt"
|
||||||
val KAPT_GROUP_NAME = "org.jetbrains.kotlin"
|
|
||||||
val KAPT_ARTIFACT_NAME = "kotlin-annotation-processing-gradle"
|
val KAPT_GROUP_NAME = "org.jetbrains.kotlin"
|
||||||
|
val KAPT_ARTIFACT_NAME = "kotlin-annotation-processing-gradle"
|
||||||
fun getKaptConfigurationName(sourceSetName: String): String {
|
|
||||||
return if (sourceSetName != "main")
|
fun getKaptConfigurationName(sourceSetName: String): String {
|
||||||
"$MAIN_KAPT_CONFIGURATION_NAME${sourceSetName.capitalize()}"
|
return if (sourceSetName != "main")
|
||||||
else
|
"$MAIN_KAPT_CONFIGURATION_NAME${sourceSetName.capitalize()}"
|
||||||
MAIN_KAPT_CONFIGURATION_NAME
|
else
|
||||||
}
|
MAIN_KAPT_CONFIGURATION_NAME
|
||||||
|
}
|
||||||
fun Project.findKaptConfiguration(sourceSetName: String): Configuration? {
|
|
||||||
return project.configurations.findByName(getKaptConfigurationName(sourceSetName))
|
fun Project.findKaptConfiguration(sourceSetName: String): Configuration? {
|
||||||
}
|
return project.configurations.findByName(getKaptConfigurationName(sourceSetName))
|
||||||
|
}
|
||||||
fun findMainKaptConfiguration(project: Project) = project.findKaptConfiguration(MAIN_KAPT_CONFIGURATION_NAME)
|
|
||||||
}
|
fun findMainKaptConfiguration(project: Project) = project.findKaptConfiguration(MAIN_KAPT_CONFIGURATION_NAME)
|
||||||
|
}
|
||||||
private val kotlinToKaptGenerateStubsTasksMap = mutableMapOf<KotlinCompile, KaptGenerateStubsTask>()
|
|
||||||
|
private val kotlinToKaptGenerateStubsTasksMap = mutableMapOf<KotlinCompile, KaptGenerateStubsTask>()
|
||||||
override fun isApplicable(project: Project, task: AbstractCompile) = task is KotlinCompile && Kapt3GradleSubplugin.isEnabled(project)
|
|
||||||
|
override fun isApplicable(project: Project, task: AbstractCompile) = task is KotlinCompile && Kapt3GradleSubplugin.isEnabled(project)
|
||||||
private fun Kapt3SubpluginContext.getKaptStubsDir() = createAndReturnTemporaryKaptDirectory("stubs")
|
|
||||||
|
private fun Kapt3SubpluginContext.getKaptStubsDir() = createAndReturnTemporaryKaptDirectory("stubs")
|
||||||
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = createAndReturnTemporaryKaptDirectory("incrementalData")
|
|
||||||
|
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = createAndReturnTemporaryKaptDirectory("incrementalData")
|
||||||
private fun Kapt3SubpluginContext.createAndReturnTemporaryKaptDirectory(name: String): File {
|
|
||||||
val dir = File(project.buildDir, "tmp/kapt3/$name/$sourceSetName")
|
private fun Kapt3SubpluginContext.createAndReturnTemporaryKaptDirectory(name: String): File {
|
||||||
dir.mkdirs()
|
val dir = File(project.buildDir, "tmp/kapt3/$name/$sourceSetName")
|
||||||
return dir
|
dir.mkdirs()
|
||||||
}
|
return dir
|
||||||
|
}
|
||||||
private inner class Kapt3SubpluginContext(
|
|
||||||
val project: Project,
|
private inner class Kapt3SubpluginContext(
|
||||||
val kotlinCompile: KotlinCompile,
|
val project: Project,
|
||||||
val javaCompile: AbstractCompile,
|
val kotlinCompile: KotlinCompile,
|
||||||
val kaptVariantData: KaptVariantData<*>?,
|
val javaCompile: AbstractCompile,
|
||||||
val sourceSetName: String,
|
val kaptVariantData: KaptVariantData<*>?,
|
||||||
val javaSourceSet: SourceSet?,
|
val sourceSetName: String,
|
||||||
val kaptExtension: KaptExtension,
|
val javaSourceSet: SourceSet?,
|
||||||
val kaptClasspath: MutableList<File>) {
|
val kaptExtension: KaptExtension,
|
||||||
val sourcesOutputDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
val kaptClasspath: MutableList<File>) {
|
||||||
val kotlinSourcesOutputDir = getKaptGeneratedKotlinSourcesDir(project, sourceSetName)
|
val sourcesOutputDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
||||||
val classesOutputDir = getKaptGeneratedClassesDir(project, sourceSetName)
|
val kotlinSourcesOutputDir = getKaptGeneratedKotlinSourcesDir(project, sourceSetName)
|
||||||
|
val classesOutputDir = getKaptGeneratedClassesDir(project, sourceSetName)
|
||||||
val kaptClasspathArtifacts = project
|
|
||||||
.resolveSubpluginArtifacts(listOf(this@Kapt3KotlinGradleSubplugin))
|
val kaptClasspathArtifacts = project
|
||||||
.flatMap { it.value }
|
.resolveSubpluginArtifacts(listOf(this@Kapt3KotlinGradleSubplugin))
|
||||||
}
|
.flatMap { it.value }
|
||||||
|
}
|
||||||
override fun apply(
|
|
||||||
project: Project,
|
override fun apply(
|
||||||
kotlinCompile: KotlinCompile,
|
project: Project,
|
||||||
javaCompile: AbstractCompile,
|
kotlinCompile: KotlinCompile,
|
||||||
variantData: Any?,
|
javaCompile: AbstractCompile,
|
||||||
androidProjectHandler: Any?,
|
variantData: Any?,
|
||||||
javaSourceSet: SourceSet?
|
androidProjectHandler: Any?,
|
||||||
): List<SubpluginOption> {
|
javaSourceSet: SourceSet?
|
||||||
assert((variantData != null) xor (javaSourceSet != null))
|
): List<SubpluginOption> {
|
||||||
|
assert((variantData != null) xor (javaSourceSet != null))
|
||||||
val kaptClasspath = arrayListOf<File>()
|
|
||||||
val buildDependencies = arrayListOf<TaskDependency>()
|
val kaptClasspath = arrayListOf<File>()
|
||||||
val kaptConfigurations = arrayListOf<Configuration>()
|
val buildDependencies = arrayListOf<TaskDependency>()
|
||||||
|
val kaptConfigurations = arrayListOf<Configuration>()
|
||||||
fun handleSourceSet(sourceSetName: String) {
|
|
||||||
val kaptConfiguration = project.findKaptConfiguration(sourceSetName)
|
fun handleSourceSet(sourceSetName: String) {
|
||||||
val filteredDependencies = kaptConfiguration?.dependencies?.filter {
|
val kaptConfiguration = project.findKaptConfiguration(sourceSetName)
|
||||||
it.group != getGroupName() || it.name != getArtifactName()
|
val filteredDependencies = kaptConfiguration?.dependencies?.filter {
|
||||||
} ?: emptyList()
|
it.group != getGroupName() || it.name != getArtifactName()
|
||||||
|
} ?: emptyList()
|
||||||
if (kaptConfiguration != null) {
|
|
||||||
kaptConfigurations += kaptConfiguration
|
if (kaptConfiguration != null) {
|
||||||
buildDependencies += kaptConfiguration.buildDependencies
|
kaptConfigurations += kaptConfiguration
|
||||||
|
buildDependencies += kaptConfiguration.buildDependencies
|
||||||
if (filteredDependencies.isNotEmpty()) {
|
|
||||||
kaptClasspath.addAll(kaptConfiguration.resolve())
|
if (filteredDependencies.isNotEmpty()) {
|
||||||
}
|
kaptClasspath.addAll(kaptConfiguration.resolve())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val kaptVariantData = variantData as? KaptVariantData<*>
|
|
||||||
|
val kaptVariantData = variantData as? KaptVariantData<*>
|
||||||
val sourceSetName = if (kaptVariantData != null) {
|
|
||||||
for (provider in kaptVariantData.sourceProviders) {
|
val sourceSetName = if (kaptVariantData != null) {
|
||||||
handleSourceSet((provider as AndroidSourceSet).name)
|
for (provider in kaptVariantData.sourceProviders) {
|
||||||
}
|
handleSourceSet((provider as AndroidSourceSet).name)
|
||||||
|
}
|
||||||
kaptVariantData.name
|
|
||||||
}
|
kaptVariantData.name
|
||||||
else {
|
}
|
||||||
if (javaSourceSet == null) error("Java source set should not be null")
|
else {
|
||||||
|
if (javaSourceSet == null) error("Java source set should not be null")
|
||||||
handleSourceSet(javaSourceSet.name)
|
|
||||||
javaSourceSet.name
|
handleSourceSet(javaSourceSet.name)
|
||||||
}
|
javaSourceSet.name
|
||||||
|
}
|
||||||
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
|
||||||
|
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
||||||
val context = Kapt3SubpluginContext(project, kotlinCompile, javaCompile,
|
|
||||||
kaptVariantData, sourceSetName, javaSourceSet, kaptExtension, kaptClasspath)
|
val context = Kapt3SubpluginContext(project, kotlinCompile, javaCompile,
|
||||||
|
kaptVariantData, sourceSetName, javaSourceSet, kaptExtension, kaptClasspath)
|
||||||
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
|
||||||
val kaptTask = context.createKaptKotlinTask()
|
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
||||||
|
val kaptTask = context.createKaptKotlinTask()
|
||||||
kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray())
|
|
||||||
|
kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray())
|
||||||
kaptGenerateStubsTask.dependsOn(*buildDependencies.toTypedArray())
|
|
||||||
kaptGenerateStubsTask.dependsOn(*kotlinCompile.dependsOn.toTypedArray())
|
kaptGenerateStubsTask.dependsOn(*buildDependencies.toTypedArray())
|
||||||
|
kaptGenerateStubsTask.dependsOn(*kotlinCompile.dependsOn.toTypedArray())
|
||||||
kaptTask.dependsOn(kaptGenerateStubsTask)
|
|
||||||
kotlinCompile.dependsOn(kaptTask)
|
kaptTask.dependsOn(kaptGenerateStubsTask)
|
||||||
|
kotlinCompile.dependsOn(kaptTask)
|
||||||
/** Plugin options are applied to kapt*Compile inside [createKaptKotlinTask] */
|
|
||||||
return emptyList()
|
/** Plugin options are applied to kapt*Compile inside [createKaptKotlinTask] */
|
||||||
}
|
return emptyList()
|
||||||
|
}
|
||||||
override fun getSubpluginKotlinTasks(project: Project, kotlinCompile: KotlinCompile): List<AbstractCompile> {
|
|
||||||
val kaptGenerateStubsTask = kotlinToKaptGenerateStubsTasksMap[kotlinCompile]
|
override fun getSubpluginKotlinTasks(project: Project, kotlinCompile: KotlinCompile): List<AbstractCompile> {
|
||||||
return if (kaptGenerateStubsTask == null) emptyList() else listOf(kaptGenerateStubsTask)
|
val kaptGenerateStubsTask = kotlinToKaptGenerateStubsTasksMap[kotlinCompile]
|
||||||
}
|
return if (kaptGenerateStubsTask == null) emptyList() else listOf(kaptGenerateStubsTask)
|
||||||
|
}
|
||||||
// This method should be called no more than once for each Kapt3SubpluginContext
|
|
||||||
private fun Kapt3SubpluginContext.buildOptions(aptMode: String): List<SubpluginOption> {
|
// This method should be called no more than once for each Kapt3SubpluginContext
|
||||||
val pluginOptions = mutableListOf<SubpluginOption>()
|
private fun Kapt3SubpluginContext.buildOptions(aptMode: String): List<SubpluginOption> {
|
||||||
|
val pluginOptions = mutableListOf<SubpluginOption>()
|
||||||
val generatedFilesDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
|
||||||
kaptVariantData?.addJavaSourceFoldersToModel(generatedFilesDir)
|
val generatedFilesDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
||||||
|
kaptVariantData?.addJavaSourceFoldersToModel(generatedFilesDir)
|
||||||
pluginOptions += SubpluginOption("aptMode", aptMode)
|
|
||||||
disableAnnotationProcessingInJavaTask()
|
pluginOptions += SubpluginOption("aptMode", aptMode)
|
||||||
|
disableAnnotationProcessingInJavaTask()
|
||||||
kaptClasspath.forEach { pluginOptions += SubpluginOption("apclasspath", it.absolutePath) }
|
|
||||||
|
kaptClasspath.forEach { pluginOptions += FilesSubpluginOption("apclasspath", FileOptionKind.INTERNAL, listOf(it)) }
|
||||||
javaCompile.source(generatedFilesDir)
|
|
||||||
|
javaCompile.source(generatedFilesDir)
|
||||||
pluginOptions += SubpluginOption("sources", generatedFilesDir.canonicalPath)
|
|
||||||
pluginOptions += SubpluginOption("classes", getKaptGeneratedClassesDir(project, sourceSetName).canonicalPath)
|
pluginOptions += FilesSubpluginOption("sources", FileOptionKind.INTERNAL, listOf(generatedFilesDir))
|
||||||
|
pluginOptions += FilesSubpluginOption("classes", FileOptionKind.INTERNAL, listOf(getKaptGeneratedClassesDir(project, sourceSetName)))
|
||||||
pluginOptions += SubpluginOption("incrementalData", getKaptIncrementalDataDir().canonicalPath)
|
|
||||||
|
pluginOptions += FilesSubpluginOption("incrementalData", FileOptionKind.INTERNAL, listOf(getKaptIncrementalDataDir()))
|
||||||
val annotationProcessors = kaptExtension.processors
|
|
||||||
if (annotationProcessors.isNotEmpty()) {
|
val annotationProcessors = kaptExtension.processors
|
||||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
if (annotationProcessors.isNotEmpty()) {
|
||||||
}
|
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
||||||
|
}
|
||||||
val androidPlugin = kaptVariantData?.let {
|
|
||||||
project.extensions.findByName("android") as? BaseExtension
|
val androidPlugin = kaptVariantData?.let {
|
||||||
}
|
project.extensions.findByName("android") as? BaseExtension
|
||||||
|
}
|
||||||
val androidOptions = kaptVariantData?.annotationProcessorOptions ?: emptyMap()
|
|
||||||
|
val androidOptions = kaptVariantData?.annotationProcessorOptions ?: emptyMap()
|
||||||
kotlinSourcesOutputDir.mkdirs()
|
|
||||||
|
kotlinSourcesOutputDir.mkdirs()
|
||||||
val apOptions = kaptExtension.getAdditionalArguments(
|
|
||||||
project,
|
val apOptions =
|
||||||
kaptVariantData?.variantData,
|
(kaptExtension.getAdditionalArguments(project, kaptVariantData?.variantData, androidPlugin) + androidOptions)
|
||||||
androidPlugin
|
.map { SubpluginOption(it.key, it.value) } +
|
||||||
) + androidOptions + mapOf("kapt.kotlin.generated" to kotlinSourcesOutputDir.absolutePath)
|
FilesSubpluginOption("kapt.kotlin.generated", FileOptionKind.INTERNAL, listOf(kotlinSourcesOutputDir))
|
||||||
|
|
||||||
pluginOptions += SubpluginOption("apoptions", encodeList(apOptions))
|
pluginOptions += WrapperSubpluginOption("apoptions", encodeList(apOptions.associate { it.key to it.value }), apOptions)
|
||||||
|
|
||||||
pluginOptions += SubpluginOption("javacArguments", encodeList(kaptExtension.getJavacOptions()))
|
pluginOptions += SubpluginOption("javacArguments", encodeList(kaptExtension.getJavacOptions()))
|
||||||
|
|
||||||
addMiscOptions(pluginOptions)
|
addMiscOptions(pluginOptions)
|
||||||
|
|
||||||
return pluginOptions
|
return pluginOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(container: CompilerPluginOptions, aptMode: String) {
|
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
|
||||||
val compilerPluginId = getCompilerPluginId()
|
val compilerPluginId = getCompilerPluginId()
|
||||||
for (option in wrapPluginOptions(buildOptions(aptMode), "configuration")) {
|
for (option in wrapPluginOptions(buildOptions(aptMode), "configuration")) {
|
||||||
container.addPluginArgument(compilerPluginId, option.key, option.value)
|
container.addPluginArgument(compilerPluginId, option)
|
||||||
}
|
task.registerSubpluginOptionAsInput(compilerPluginId, option)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun encodeList(options: Map<String, String>): String {
|
// Also register all the subplugin options from the Kotlin task:
|
||||||
val os = ByteArrayOutputStream()
|
project.afterEvaluate {
|
||||||
val oos = ObjectOutputStream(os)
|
kotlinCompile.pluginOptions.subpluginOptionsByPluginId.forEach { (pluginId, options) ->
|
||||||
|
options.forEach { option ->
|
||||||
oos.writeInt(options.size)
|
task.registerSubpluginOptionAsInput("kotlinCompile.$pluginId", option)
|
||||||
for ((key, value) in options.entries) {
|
}
|
||||||
oos.writeUTF(key)
|
}
|
||||||
oos.writeUTF(value)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oos.flush()
|
private fun encodeList(options: Map<String, String>): String {
|
||||||
return Base64.getEncoder().encodeToString(os.toByteArray())
|
val os = ByteArrayOutputStream()
|
||||||
}
|
val oos = ObjectOutputStream(os)
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.addMiscOptions(pluginOptions: MutableList<SubpluginOption>) {
|
oos.writeInt(options.size)
|
||||||
if (kaptExtension.generateStubs) {
|
for ((key, value) in options.entries) {
|
||||||
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
oos.writeUTF(key)
|
||||||
}
|
oos.writeUTF(value)
|
||||||
|
}
|
||||||
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
|
|
||||||
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
|
oos.flush()
|
||||||
pluginOptions += SubpluginOption("stubs", getKaptStubsDir().canonicalPath)
|
return Base64.getEncoder().encodeToString(os.toByteArray())
|
||||||
|
}
|
||||||
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
|
|
||||||
pluginOptions += SubpluginOption("verbose", "true")
|
private fun Kapt3SubpluginContext.addMiscOptions(pluginOptions: MutableList<SubpluginOption>) {
|
||||||
}
|
if (kaptExtension.generateStubs) {
|
||||||
}
|
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
||||||
|
}
|
||||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(): KaptTask {
|
|
||||||
val kaptTask = project.tasks.create(
|
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
|
||||||
getKaptTaskName("kapt"),
|
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
|
||||||
KaptTask::class.java)
|
pluginOptions += FilesSubpluginOption("stubs", FileOptionKind.INTERNAL, listOf(getKaptStubsDir()))
|
||||||
|
|
||||||
kaptTask.useBuildCacheIfSupported()
|
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
|
||||||
|
pluginOptions += SubpluginOption("verbose", "true")
|
||||||
kaptTask.kotlinCompileTask = kotlinCompile
|
}
|
||||||
|
}
|
||||||
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
|
|
||||||
|
private fun Kapt3SubpluginContext.createKaptKotlinTask(): KaptTask {
|
||||||
kaptTask.stubsDir = getKaptStubsDir()
|
val kaptTask = project.tasks.create(
|
||||||
kaptTask.destinationDir = sourcesOutputDir
|
getKaptTaskName("kapt"),
|
||||||
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
KaptTask::class.java)
|
||||||
kaptTask.classesDir = classesOutputDir
|
|
||||||
|
kaptTask.useBuildCacheIfSupported()
|
||||||
javaSourceSet?.output?.apply {
|
|
||||||
if (tryAddClassesDir { project.files(classesOutputDir).builtBy(kaptTask) }) {
|
if (shouldEnableGradleCache()) {
|
||||||
kotlinCompile.attachClassesDir { classesOutputDir }
|
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."
|
||||||
}
|
kaptTask.outputs.doNotCacheIf(reason) { !kaptTask.useBuildCache }
|
||||||
|
}
|
||||||
kotlinCompile.source(sourcesOutputDir, kotlinSourcesOutputDir)
|
|
||||||
|
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
||||||
if (kaptVariantData != null) {
|
|
||||||
kaptVariantData.registerGeneratedJavaSource(project, kaptTask, javaCompile)
|
kaptTask.kotlinCompileTask = kotlinCompile
|
||||||
}
|
|
||||||
else {
|
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
|
||||||
registerGeneratedJavaSource(kaptTask, javaCompile)
|
|
||||||
}
|
kaptTask.stubsDir = getKaptStubsDir()
|
||||||
|
kaptTask.destinationDir = sourcesOutputDir
|
||||||
kaptTask.kaptClasspath = kaptClasspath
|
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
||||||
|
kaptTask.classesDir = classesOutputDir
|
||||||
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
|
||||||
|
javaSourceSet?.output?.apply {
|
||||||
if (shouldEnableGradleCache()) {
|
if (tryAddClassesDir { project.files(classesOutputDir).builtBy(kaptTask) }) {
|
||||||
val reason = "Caching is disabled by default for kapt because of arbitrary behavior of external " +
|
kotlinCompile.attachClassesDir { classesOutputDir }
|
||||||
"annotation processors. You can enable it by adding 'kapt.useBuildCache = true' to the build script."
|
}
|
||||||
kaptTask.outputs.doNotCacheIf(reason) { !kaptTask.useBuildCache }
|
}
|
||||||
}
|
|
||||||
|
kotlinCompile.source(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||||
buildAndAddOptionsTo(kaptTask.pluginOptions, aptMode = "apt")
|
|
||||||
|
if (kaptVariantData != null) {
|
||||||
return kaptTask
|
kaptVariantData.registerGeneratedJavaSource(project, kaptTask, javaCompile)
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): KaptGenerateStubsTask {
|
registerGeneratedJavaSource(kaptTask, javaCompile)
|
||||||
val kaptTask = project.tasks.create(
|
}
|
||||||
getKaptTaskName("kaptGenerateStubs"),
|
|
||||||
KaptGenerateStubsTask::class.java)
|
kaptTask.kaptClasspath = kaptClasspath
|
||||||
|
|
||||||
kaptTask.useBuildCacheIfSupported()
|
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt")
|
||||||
|
|
||||||
kaptTask.sourceSetName = sourceSetName
|
return kaptTask
|
||||||
kaptTask.kotlinCompileTask = kotlinCompile
|
}
|
||||||
kotlinToKaptGenerateStubsTasksMap[kotlinCompile] = kaptTask
|
|
||||||
|
private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): KaptGenerateStubsTask {
|
||||||
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
|
val kaptTask = project.tasks.create(
|
||||||
|
getKaptTaskName("kaptGenerateStubs"),
|
||||||
kaptTask.stubsDir = getKaptStubsDir()
|
KaptGenerateStubsTask::class.java)
|
||||||
kaptTask.destinationDir = getKaptIncrementalDataDir()
|
|
||||||
kaptTask.mapClasspath { kotlinCompile.classpath }
|
kaptTask.useBuildCacheIfSupported()
|
||||||
kaptTask.generatedSourcesDir = sourcesOutputDir
|
|
||||||
mapKotlinTaskProperties(project, kaptTask)
|
kaptTask.sourceSetName = sourceSetName
|
||||||
|
kaptTask.kotlinCompileTask = kotlinCompile
|
||||||
kaptTask.kaptClasspath = kaptClasspath
|
kotlinToKaptGenerateStubsTasksMap[kotlinCompile] = kaptTask
|
||||||
buildAndAddOptionsTo(kaptTask.pluginOptions, aptMode = "stubs")
|
|
||||||
|
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
|
||||||
return kaptTask
|
|
||||||
}
|
kaptTask.stubsDir = getKaptStubsDir()
|
||||||
|
kaptTask.destinationDir = getKaptIncrementalDataDir()
|
||||||
private fun Kapt3SubpluginContext.getKaptTaskName(prefix: String): String {
|
kaptTask.mapClasspath { kotlinCompile.classpath }
|
||||||
// Replace compile*Kotlin to kapt*Kotlin
|
kaptTask.generatedSourcesDir = sourcesOutputDir
|
||||||
val baseName = kotlinCompile.name
|
mapKotlinTaskProperties(project, kaptTask)
|
||||||
assert(baseName.startsWith("compile"))
|
|
||||||
return baseName.replaceFirst("compile", prefix)
|
kaptTask.kaptClasspath = kaptClasspath
|
||||||
}
|
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "stubs")
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.disableAnnotationProcessingInJavaTask() {
|
return kaptTask
|
||||||
(javaCompile as? JavaCompile)?.let { javaCompile ->
|
}
|
||||||
val options = javaCompile.options
|
|
||||||
// 'android-apt' (com.neenbedankt) adds a File instance to compilerArgs (List<String>).
|
private fun Kapt3SubpluginContext.getKaptTaskName(prefix: String): String {
|
||||||
// Although it's not our problem, we need to handle this case properly.
|
// Replace compile*Kotlin to kapt*Kotlin
|
||||||
val oldCompilerArgs: List<Any> = options.compilerArgs
|
val baseName = kotlinCompile.name
|
||||||
val newCompilerArgs = oldCompilerArgs.filterTo(mutableListOf()) {
|
assert(baseName.startsWith("compile"))
|
||||||
it !is CharSequence || !it.toString().startsWith("-proc:")
|
return baseName.replaceFirst("compile", prefix)
|
||||||
}
|
}
|
||||||
newCompilerArgs.add("-proc:none")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
private fun Kapt3SubpluginContext.disableAnnotationProcessingInJavaTask() {
|
||||||
options.compilerArgs = newCompilerArgs as List<String>
|
(javaCompile as? JavaCompile)?.let { javaCompile ->
|
||||||
}
|
val options = javaCompile.options
|
||||||
}
|
// 'android-apt' (com.neenbedankt) adds a File instance to compilerArgs (List<String>).
|
||||||
|
// Although it's not our problem, we need to handle this case properly.
|
||||||
override fun getCompilerPluginId() = "org.jetbrains.kotlin.kapt3"
|
val oldCompilerArgs: List<Any> = options.compilerArgs
|
||||||
override fun getGroupName() = KAPT_GROUP_NAME
|
val newCompilerArgs = oldCompilerArgs.filterTo(mutableListOf()) {
|
||||||
override fun getArtifactName() = KAPT_ARTIFACT_NAME
|
it !is CharSequence || !it.toString().startsWith("-proc:")
|
||||||
}
|
}
|
||||||
|
newCompilerArgs.add("-proc:none")
|
||||||
internal fun registerGeneratedJavaSource(kaptTask: KaptTask, javaTask: AbstractCompile) {
|
@Suppress("UNCHECKED_CAST")
|
||||||
javaTask.source(kaptTask.destinationDir)
|
options.compilerArgs = newCompilerArgs as List<String>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
internal fun Configuration.getNamedDependencies(): List<Dependency> = allDependencies.filter { it.group != null && it.name != null }
|
|
||||||
|
override fun getCompilerPluginId() = "org.jetbrains.kotlin.kapt3"
|
||||||
internal fun checkAndroidAnnotationProcessorDependencyUsage(project: Project) {
|
override fun getGroupName() = KAPT_GROUP_NAME
|
||||||
val isKapt3Enabled = Kapt3GradleSubplugin.isEnabled(project)
|
override fun getArtifactName() = KAPT_ARTIFACT_NAME
|
||||||
|
}
|
||||||
val androidAPDependencies = project.configurations
|
|
||||||
.filter { it.name == "annotationProcessor"
|
internal fun registerGeneratedJavaSource(kaptTask: KaptTask, javaTask: AbstractCompile) {
|
||||||
|| (it.name.endsWith("AnnotationProcessor") && !it.name.startsWith("_")) }
|
javaTask.source(kaptTask.destinationDir)
|
||||||
.flatMap { it.getNamedDependencies() }
|
}
|
||||||
|
|
||||||
if (androidAPDependencies.isNotEmpty()) {
|
internal fun Configuration.getNamedDependencies(): List<Dependency> = allDependencies.filter { it.group != null && it.name != null }
|
||||||
val artifactsRendered = androidAPDependencies.joinToString { "'${it.group}:${it.name}:${it.version}'" }
|
|
||||||
val andApplyKapt = if (isKapt3Enabled) "" else " and apply the kapt plugin: \"apply plugin: 'kotlin-kapt'\""
|
internal fun checkAndroidAnnotationProcessorDependencyUsage(project: Project) {
|
||||||
project.logger.warn("${project.name}: " +
|
val isKapt3Enabled = Kapt3GradleSubplugin.isEnabled(project)
|
||||||
"'annotationProcessor' dependencies won't be recognized as kapt annotation processors. " +
|
|
||||||
"Please change the configuration name to 'kapt' for these artifacts: $artifactsRendered$andApplyKapt.")
|
val androidAPDependencies = project.configurations
|
||||||
}
|
.filter { it.name == "annotationProcessor"
|
||||||
}
|
|| (it.name.endsWith("AnnotationProcessor") && !it.name.startsWith("_")) }
|
||||||
|
.flatMap { it.getNamedDependencies() }
|
||||||
|
|
||||||
|
if (androidAPDependencies.isNotEmpty()) {
|
||||||
|
val artifactsRendered = androidAPDependencies.joinToString { "'${it.group}:${it.name}:${it.version}'" }
|
||||||
|
val andApplyKapt = if (isKapt3Enabled) "" else " and apply the kapt plugin: \"apply plugin: 'kotlin-kapt'\""
|
||||||
|
project.logger.warn("${project.name}: " +
|
||||||
|
"'annotationProcessor' dependencies won't be recognized as kapt annotation processors. " +
|
||||||
|
"Please change the configuration name to 'kapt' for these artifacts: $artifactsRendered$andApplyKapt.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.WrapperSubpluginOption
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.ObjectOutputStream
|
import java.io.ObjectOutputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -42,6 +43,6 @@ fun encodePluginOptions(options: Map<String, List<String>>): String {
|
|||||||
fun wrapPluginOptions(options: List<SubpluginOption>, newOptionName: String): List<SubpluginOption> {
|
fun wrapPluginOptions(options: List<SubpluginOption>, newOptionName: String): List<SubpluginOption> {
|
||||||
val groupedOptions = options.groupBy { it.key }.mapValues { opt -> opt.value.map { it.value } }
|
val groupedOptions = options.groupBy { it.key }.mapValues { opt -> opt.value.map { it.value } }
|
||||||
val encodedOptions = encodePluginOptions(groupedOptions)
|
val encodedOptions = encodePluginOptions(groupedOptions)
|
||||||
val singleOption = SubpluginOption(newOptionName, encodedOptions)
|
val singleOption = WrapperSubpluginOption(newOptionName, encodedOptions, options)
|
||||||
return listOf(singleOption)
|
return listOf(singleOption)
|
||||||
}
|
}
|
||||||
+41
-4
@@ -20,9 +20,7 @@ import org.gradle.api.plugins.InvalidPluginException
|
|||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
import org.gradle.api.plugins.JavaPluginConvention
|
import org.gradle.api.plugins.JavaPluginConvention
|
||||||
import org.gradle.api.tasks.Delete
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.api.tasks.SourceSet
|
|
||||||
import org.gradle.api.tasks.SourceSetOutput
|
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
@@ -822,7 +820,9 @@ internal class SubpluginEnvironment(
|
|||||||
subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) }
|
subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) }
|
||||||
|
|
||||||
for (option in subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, javaSourceSet)) {
|
for (option in subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, javaSourceSet)) {
|
||||||
pluginOptions.addPluginArgument(subplugin.getCompilerPluginId(), option.key, option.value)
|
val pluginId = subplugin.getCompilerPluginId()
|
||||||
|
pluginOptions.addPluginArgument(pluginId, option)
|
||||||
|
kotlinTask.registerSubpluginOptionAsInput(pluginId, option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,6 +830,43 @@ internal class SubpluginEnvironment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val fileOptionsPathSensitivity = PathSensitivity.ABSOLUTE
|
||||||
|
|
||||||
|
internal fun Task.registerSubpluginOptionAsInput(subpluginId: String, option: SubpluginOption) {
|
||||||
|
when (option) {
|
||||||
|
is WrapperSubpluginOption -> {
|
||||||
|
val subpluginIdWithWrapperKey = "$subpluginId.${option.key}"
|
||||||
|
option.originalOptions.forEach { registerSubpluginOptionAsInput(subpluginIdWithWrapperKey, it) }
|
||||||
|
}
|
||||||
|
is FilesSubpluginOption -> {
|
||||||
|
when (option.kind) {
|
||||||
|
FileOptionKind.INTERNAL -> Unit
|
||||||
|
FileOptionKind.OUTPUT_FILES -> outputsCompatible.filesCompatible(*option.files.toTypedArray())
|
||||||
|
FileOptionKind.OUTPUT_DIRS -> option.files.forEach { outputsCompatible.dirCompatible(it) }
|
||||||
|
FileOptionKind.INPUT_FILES, FileOptionKind.CLASSPATH_INPUT -> {
|
||||||
|
if (!shouldEnableGradleCache()) {
|
||||||
|
// Normalization makes no sense when we don't mean to use the cache,
|
||||||
|
// and moreover, Gradle lacks some of the APIs in the earlier versions.
|
||||||
|
inputsCompatible.filesCompatible(option.files)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (option.kind == FileOptionKind.CLASSPATH_INPUT)
|
||||||
|
inputs.files(option.files).withNormalizer(ClasspathNormalizer::class.java)
|
||||||
|
else
|
||||||
|
inputs.files(option.files).withPathSensitivity(fileOptionsPathSensitivity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// Since there might be multiple subplugin options with the same key,
|
||||||
|
// use the properties count to resolve duplication:
|
||||||
|
val propertyInputsCount = inputsCompatible.properties.size
|
||||||
|
inputsCompatible.propertyCompatible("$subpluginId." + option.key + ".$propertyInputsCount", option.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair<File, File> {
|
private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair<File, File> {
|
||||||
val aptOutputDir = File(buildDir, "generated/source/kapt")
|
val aptOutputDir = File(buildDir, "generated/source/kapt")
|
||||||
val aptOutputDirForVariant = File(aptOutputDir, sourceSetName)
|
val aptOutputDirForVariant = File(aptOutputDir, sourceSetName)
|
||||||
|
|||||||
+7
-2
@@ -16,12 +16,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.tasks
|
package org.jetbrains.kotlin.gradle.tasks
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class CompilerPluginOptions {
|
internal class CompilerPluginOptions {
|
||||||
private val mutableClasspath = arrayListOf<String>()
|
private val mutableClasspath = arrayListOf<String>()
|
||||||
private val mutableArguments = arrayListOf<String>()
|
private val mutableArguments = arrayListOf<String>()
|
||||||
|
|
||||||
|
internal val subpluginOptionsByPluginId =
|
||||||
|
mutableMapOf<String, MutableList<SubpluginOption>>()
|
||||||
|
|
||||||
val classpath: List<String>
|
val classpath: List<String>
|
||||||
get() = mutableClasspath
|
get() = mutableClasspath
|
||||||
|
|
||||||
@@ -38,7 +42,8 @@ internal class CompilerPluginOptions {
|
|||||||
mutableClasspath.remove(file.canonicalPath)
|
mutableClasspath.remove(file.canonicalPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addPluginArgument(pluginId: String, key: String, value: String) {
|
fun addPluginArgument(pluginId: String, option: SubpluginOption) {
|
||||||
mutableArguments.add("plugin:$pluginId:$key=$value")
|
mutableArguments.add("plugin:$pluginId:${option.key}=${option.value}")
|
||||||
|
subpluginOptionsByPluginId.getOrPut(pluginId) { mutableListOf() }.add(option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -38,8 +38,7 @@ import org.jetbrains.kotlin.compilerRunner.*
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.internal.CompilerArgumentAware
|
import org.jetbrains.kotlin.gradle.internal.CompilerArgumentAware
|
||||||
import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments
|
import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments
|
||||||
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.kotlinInfo
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
||||||
import org.jetbrains.kotlin.incremental.*
|
import org.jetbrains.kotlin.incremental.*
|
||||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistry
|
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistry
|
||||||
@@ -413,15 +412,15 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
kaptAnnotationsFileUpdater = AnnotationFileUpdaterImpl(kaptAnnotationsFile)
|
kaptAnnotationsFileUpdater = AnnotationFileUpdaterImpl(kaptAnnotationsFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, "output", kaptAnnotationsFile.canonicalPath)
|
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, FilesSubpluginOption("output", FileOptionKind.INTERNAL, listOf(kaptAnnotationsFile)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kaptOptions.generateStubs) {
|
if (kaptOptions.generateStubs) {
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, "stubs", destinationDir.canonicalPath)
|
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, FilesSubpluginOption("stubs", FileOptionKind.INTERNAL, listOf(destinationDir)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kaptOptions.supportInheritedAnnotations) {
|
if (kaptOptions.supportInheritedAnnotations) {
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, "inherited", true.toString())
|
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, SubpluginOption("inherited", true.toString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user