[Gradle] Add APIs that allow AGP to configure Kotlin compilation
Add APIs that describe tasks, so that AGP can configure them. This change all adds support to *Config objects to support configuring tasks when there is no access to internal KGP objects. ^KT-50869 In Progress
This commit is contained in:
+39
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import java.io.File
|
||||
|
||||
@@ -73,6 +74,44 @@ open class CompilerPluginConfig {
|
||||
fun addPluginArgument(pluginId: String, option: SubpluginOption) {
|
||||
optionsByPluginId.getOrPut(pluginId) { mutableListOf() }.add(option)
|
||||
}
|
||||
|
||||
@Input
|
||||
fun getAsTaskInputArgs(): Map<String, String> {
|
||||
val result = mutableMapOf<String, String>()
|
||||
optionsByPluginId.forEach { (id, subpluginOptions) ->
|
||||
result += computeForSubpluginId(id, subpluginOptions)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun computeForSubpluginId(subpluginId: String, subpluginOptions: List<SubpluginOption>): Map<String, String> {
|
||||
// There might be several options with the same key. We group them together
|
||||
// and add an index to the Gradle input property name to resolve possible duplication:
|
||||
val result = mutableMapOf<String, String>()
|
||||
val pluginOptionsGrouped = subpluginOptions.groupBy { it.key }
|
||||
for ((optionKey, optionsGroup) in pluginOptionsGrouped) {
|
||||
optionsGroup.forEachIndexed { index, option ->
|
||||
val indexSuffix = if (optionsGroup.size > 1) ".$index" else ""
|
||||
when (option) {
|
||||
is InternalSubpluginOption -> return@forEachIndexed
|
||||
|
||||
is CompositeSubpluginOption -> {
|
||||
val subpluginIdWithWrapperKey = "$subpluginId.$optionKey$indexSuffix"
|
||||
result += computeForSubpluginId(subpluginIdWithWrapperKey, option.originalOptions)
|
||||
}
|
||||
|
||||
is FilesSubpluginOption -> when (option.kind) {
|
||||
FilesOptionKind.INTERNAL -> Unit
|
||||
}.run { /* exhaustive when */ }
|
||||
|
||||
else -> {
|
||||
result["$subpluginId." + option.key + indexSuffix] = option.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.plugin
|
||||
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KaptExtensionConfig
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtensionConfig
|
||||
import org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kapt
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
/** An API used by third-party plugins to integration with the Kotlin Gradle plugin. */
|
||||
interface KotlinJvmFactory {
|
||||
/** Instance of DSL object that should be used to configure KAPT stub generation and annotation processing tasks.*/
|
||||
val kaptExtension: KaptExtensionConfig
|
||||
|
||||
/** Instance of DSL object that should be used to configure Kotlin compilation pipeline. */
|
||||
val kotlinExtension: KotlinTopLevelExtensionConfig
|
||||
|
||||
/** Gets the current version of the Kotlin Gradle plugin. */
|
||||
val pluginVersion: String
|
||||
|
||||
/** Creates instance of DSL object that should be used to configure JVM/android specific compilation. */
|
||||
fun createKotlinJvmOptions(): KotlinJvmOptions
|
||||
|
||||
/** Creates a Kotlin compile task. */
|
||||
fun registerKotlinJvmCompileTask(taskName: String): TaskProvider<out KotlinJvmCompile>
|
||||
|
||||
/** Creates a stub generation task which creates Java sources stubs from Kotlin sources. */
|
||||
fun registerKaptGenerateStubsTask(taskName: String): TaskProvider<out KaptGenerateStubs>
|
||||
|
||||
/** Creates a KAPT task which runs annotation processing. */
|
||||
fun registerKaptTask(taskName: String): TaskProvider<out Kapt>
|
||||
|
||||
/** Adds a compiler plugin dependency to this project. This can be e.g a Maven coordinate or a project included in the build. */
|
||||
fun addCompilerPluginDependency(dependency: Provider<Any>)
|
||||
|
||||
/** Returns a [FileCollection] that contains all compiler plugins classpath for this project. */
|
||||
fun getCompilerPlugins(): FileCollection
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.tasks
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.util.PatternFilterable
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilerPluginConfig
|
||||
|
||||
interface KotlinCompileTool : PatternFilterable, Task {
|
||||
@get:InputFiles
|
||||
@get:SkipWhenEmpty
|
||||
@get:NormalizeLineEndings
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
val sources: FileCollection
|
||||
|
||||
/**
|
||||
* Sets sources for this task.
|
||||
* The given sources object is evaluated as per [org.gradle.api.Project.files].
|
||||
*/
|
||||
fun source(vararg sources: Any)
|
||||
|
||||
/**
|
||||
* Sets sources for this task.
|
||||
* The given sources object is evaluated as per [org.gradle.api.Project.files].
|
||||
*/
|
||||
fun setSource(vararg sources: Any)
|
||||
|
||||
@get:Classpath
|
||||
@get:NormalizeLineEndings
|
||||
@get:Incremental
|
||||
val libraries: ConfigurableFileCollection
|
||||
|
||||
@get:OutputDirectory
|
||||
val destinationDirectory: DirectoryProperty
|
||||
}
|
||||
|
||||
interface BaseKotlinCompile : KotlinCompileTool {
|
||||
|
||||
@get:Internal
|
||||
val friendPaths: ConfigurableFileCollection
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
val pluginClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Input
|
||||
val moduleName: Property<String>
|
||||
|
||||
@get:Internal
|
||||
val sourceSetName: Property<String>
|
||||
|
||||
@get:Input
|
||||
val multiPlatformEnabled: Property<Boolean>
|
||||
|
||||
@get:Input
|
||||
val useModuleDetection: Property<Boolean>
|
||||
|
||||
@get:Nested
|
||||
val pluginOptions: ListProperty<CompilerPluginConfig>
|
||||
}
|
||||
|
||||
interface KotlinJvmCompile : BaseKotlinCompile, KotlinCompile<KotlinJvmOptions> {
|
||||
|
||||
// JVM specific
|
||||
@get:Internal("Takes part in compiler args.")
|
||||
val parentKotlinOptions: Property<KotlinJvmOptions>
|
||||
}
|
||||
|
||||
interface KaptGenerateStubs : KotlinJvmCompile {
|
||||
@get:OutputDirectory
|
||||
val stubsDir: DirectoryProperty
|
||||
|
||||
@get:Internal("Not an input, just passed as kapt args. ")
|
||||
val kaptClasspath: ConfigurableFileCollection
|
||||
}
|
||||
|
||||
interface BaseKapt : Task {
|
||||
|
||||
//part of kaptClasspath consisting from external artifacts only
|
||||
//basically kaptClasspath = kaptExternalClasspath + artifacts built locally
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
val kaptExternalClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
val kaptClasspathConfigurationNames: ListProperty<String>
|
||||
|
||||
/**
|
||||
* Output directory that contains caches necessary to support incremental annotation processing.
|
||||
*/
|
||||
@get:LocalState
|
||||
val incAptCache: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
val classesDir: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
val destinationDir: DirectoryProperty
|
||||
|
||||
/** Used in the model builder only. */
|
||||
@get:OutputDirectory
|
||||
val kotlinSourcesDestinationDir: DirectoryProperty
|
||||
|
||||
@get:Nested
|
||||
val annotationProcessorOptionProviders: MutableList<Any>
|
||||
|
||||
@get:Internal
|
||||
val stubsDir: DirectoryProperty
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
val kaptClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
val compiledSources: ConfigurableFileCollection
|
||||
|
||||
@get:Internal("Task implementation adds correct input annotation.")
|
||||
val classpath: ConfigurableFileCollection
|
||||
|
||||
/** Needed for the model builder. */
|
||||
@get:Internal
|
||||
val sourceSetName: Property<String>
|
||||
|
||||
@get:InputFiles
|
||||
@get:NormalizeLineEndings
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:Incremental
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
val source: ConfigurableFileCollection
|
||||
|
||||
@get:Input
|
||||
val includeCompileClasspath: Property<Boolean>
|
||||
|
||||
@get:Internal("Used to compute javac option.")
|
||||
val defaultJavaSourceCompatibility: Property<String>
|
||||
}
|
||||
|
||||
interface Kapt : BaseKapt {
|
||||
|
||||
@get:Input
|
||||
val addJdkClassesToClasspath: Property<Boolean>
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
val kaptJars: ConfigurableFileCollection
|
||||
}
|
||||
+27
-1
@@ -53,6 +53,7 @@ class UpToDateIT : KGPBaseTest() {
|
||||
OptionMutation("compileKotlin.kotlinOptions.freeCompilerArgs", "[]", "['-Xallow-kotlin-package']"),
|
||||
OptionMutation("archivesBaseName", "'someName'", "'otherName'"),
|
||||
subpluginOptionMutation,
|
||||
subpluginOptionMutationWithKapt,
|
||||
externalOutputMutation,
|
||||
compilerClasspathMutation
|
||||
)
|
||||
@@ -137,7 +138,9 @@ class UpToDateIT : KGPBaseTest() {
|
||||
}
|
||||
|
||||
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
|
||||
assertTasksExecuted(":compileKotlin", ":kaptGenerateStubsKotlin", ":kaptKotlin")
|
||||
assertTasksExecuted(":compileKotlin", ":kaptGenerateStubsKotlin")
|
||||
// KAPT with workers is not impacted by compiler classpath changes.
|
||||
assertTasksUpToDate(":kaptKotlin")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +166,29 @@ class UpToDateIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
private val subpluginOptionMutationWithKapt = object : ProjectMutation {
|
||||
override val name: String get() = "subpluginOptionMutationWithKapt"
|
||||
|
||||
override fun initProject(project: TestProject) = with(project) {
|
||||
buildGradle.appendText(
|
||||
"\n" + """
|
||||
apply plugin: 'kotlin-kapt'
|
||||
plugins.apply("org.jetbrains.kotlin.plugin.allopen")
|
||||
allOpen { annotation("allopen.Foo"); annotation("allopen.Bar") }
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
override fun mutateProject(project: TestProject) = with(project) {
|
||||
buildGradle.modify { it.replace("allopen.Foo", "allopen.Baz") }
|
||||
}
|
||||
|
||||
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
|
||||
assertTasksExecuted(":compileKotlin", ":kaptGenerateStubsKotlin")
|
||||
assertTasksUpToDate(":kaptKotlin")
|
||||
}
|
||||
}
|
||||
|
||||
private val externalOutputMutation = object : ProjectMutation {
|
||||
override val name = "externalOutputMutation"
|
||||
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.tasks
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
@DisplayName("JVM API validation")
|
||||
class KotlinJvmApiTest : KGPBaseTest() {
|
||||
@DisplayName("Kotlin compilation can be set up using APIs")
|
||||
@JvmGradlePluginTests
|
||||
@GradleTest
|
||||
internal fun kotlinCompilationShouldRunIfSetUpWithApi(gradleVersion: GradleVersion) {
|
||||
project(
|
||||
projectName = "kotlinJavaProject",
|
||||
gradleVersion = gradleVersion
|
||||
) {
|
||||
projectPath.resolve("src").let {
|
||||
it.deleteRecursively()
|
||||
it.resolve("main").createDirectories()
|
||||
it.resolve("main/foo.kt").writeText(
|
||||
"""
|
||||
class Foo
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
buildGradle.modify {
|
||||
it.replace("id 'org.jetbrains.kotlin.jvm'", "id 'org.jetbrains.kotlin.jvm' apply false") +
|
||||
"""
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinBaseApiPlugin
|
||||
KotlinBaseApiPlugin apiPlugin = plugins.apply(KotlinBaseApiPlugin.class)
|
||||
|
||||
apiPlugin.registerKotlinJvmCompileTask("foo").configure {
|
||||
it.source("src/main")
|
||||
it.multiPlatformEnabled.set(false)
|
||||
it.moduleName.set("main")
|
||||
it.sourceSetName.set("main")
|
||||
it.useModuleDetection.set(false)
|
||||
it.destinationDirectory.fileValue(new File(project.buildDir, "fooOutput"))
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
val expectedOutput = projectPath.resolve("build/fooOutput/Foo.class")
|
||||
|
||||
build("foo") {
|
||||
assertFileExists(expectedOutput)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("KAPT can be set up using APIs")
|
||||
@OtherGradlePluginTests
|
||||
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_0)
|
||||
@GradleTest
|
||||
internal fun kaptShouldRunIfSetUpWithApi(gradleVersion: GradleVersion) {
|
||||
project(
|
||||
projectName = "kotlinJavaProject",
|
||||
gradleVersion = gradleVersion
|
||||
) {
|
||||
projectPath.resolve("src").let {
|
||||
it.deleteRecursively()
|
||||
it.resolve("main").createDirectories()
|
||||
it.resolve("main/foo.kt").writeText(
|
||||
"""
|
||||
class Foo
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
buildGradle.modify {
|
||||
it.replace("id 'org.jetbrains.kotlin.jvm'", "id 'org.jetbrains.kotlin.jvm' apply false") +
|
||||
"""
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinBaseApiPlugin
|
||||
KotlinBaseApiPlugin apiPlugin = plugins.apply(KotlinBaseApiPlugin.class)
|
||||
|
||||
File kaptFakeJar = new File(project.projectDir, "kapt.jar")
|
||||
kaptFakeJar.createNewFile()
|
||||
|
||||
apiPlugin.addCompilerPluginDependency(
|
||||
project.provider {
|
||||
"org.jetbrains.kotlin:kotlin-annotation-processing-gradle:${"$"}kotlin_version"
|
||||
}
|
||||
)
|
||||
|
||||
apiPlugin.registerKaptGenerateStubsTask("foo").configure {
|
||||
it.source("src/main")
|
||||
it.multiPlatformEnabled.set(false)
|
||||
it.moduleName.set("main")
|
||||
it.sourceSetName.set("main")
|
||||
it.useModuleDetection.set(false)
|
||||
it.destinationDirectory.fileValue(new File(project.buildDir, "fooOutput"))
|
||||
it.stubsDir.fileValue(new File(project.buildDir, "fooOutputStubs"))
|
||||
it.kaptClasspath.from(kaptFakeJar)
|
||||
it.pluginClasspath.from(apiPlugin.getCompilerPlugins())
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
val expectedOutputClass = projectPath.resolve("build/fooOutput/Foo.class")
|
||||
val expectedOutputStubs = listOf(
|
||||
projectPath.resolve("build/fooOutputStubs/Foo.java"),
|
||||
projectPath.resolve("build/fooOutputStubs/Foo.kapt_metadata"),
|
||||
projectPath.resolve("build/fooOutputStubs/error/NonExistentClass.java")
|
||||
)
|
||||
|
||||
build("foo") {
|
||||
assertFileExists(expectedOutputClass)
|
||||
expectedOutputStubs.forEach { assertFileExists(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -23,6 +23,10 @@ import org.gradle.api.tasks.Internal
|
||||
|
||||
interface KotlinJsCompile : KotlinCompile<KotlinJsOptions>
|
||||
|
||||
@Deprecated(
|
||||
message = "Moved into API artifact",
|
||||
replaceWith = ReplaceWith("KotlinJvmCompile", "org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile")
|
||||
)
|
||||
interface KotlinJvmCompile : KotlinCompile<KotlinJvmOptions>
|
||||
|
||||
interface KotlinCommonCompile : KotlinCompile<KotlinMultiplatformCommonOptions>
|
||||
|
||||
+24
-14
@@ -29,8 +29,7 @@ import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
@@ -386,9 +385,9 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
val androidOptions = androidVariantData?.annotationProcessorOptions ?: emptyMap()
|
||||
val androidSubpluginOptions = androidOptions.toList().map { SubpluginOption(it.first, it.second) }
|
||||
|
||||
androidSubpluginOptions + kaptExtension.getAdditionalArguments(project, androidVariantData, androidExtension).toList()
|
||||
.map { SubpluginOption(it.first, it.second) } +
|
||||
FilesSubpluginOption(KAPT_KOTLIN_GENERATED, listOf(kotlinSourcesOutputDir))
|
||||
androidSubpluginOptions + getNonAndroidDslApOptions(
|
||||
kaptExtension, project, listOf(kotlinSourcesOutputDir), androidVariantData, androidExtension
|
||||
).get()
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean): TaskProvider<out KaptTask> {
|
||||
@@ -396,9 +395,9 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
val taskName = getKaptTaskName("kapt")
|
||||
|
||||
val taskConfigAction = if (taskClass == KaptWithoutKotlincTask::class.java ) {
|
||||
KaptWithoutKotlincConfigAction(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
KaptWithoutKotlincConfig(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
} else {
|
||||
KaptWithKotlincConfigAction(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
KaptWithKotlincConfig(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
}
|
||||
|
||||
val kaptClasspathConfiguration = project.configurations.create("kaptClasspath_$taskName")
|
||||
@@ -452,22 +451,18 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
} else {
|
||||
check(taskClass == KaptWithoutKotlincTask::class.java)
|
||||
getDslKaptApOptions()
|
||||
}.map {
|
||||
val res = CompilerPluginOptions()
|
||||
it.forEach { res.addPluginArgument(KAPT_SUBPLUGIN_ID, it) }
|
||||
return@map res
|
||||
}
|
||||
}.toCompilerPluginOptions()
|
||||
|
||||
task.kaptPluginOptions.add(pluginOptions)
|
||||
}
|
||||
|
||||
return if (taskClass == KaptWithoutKotlincTask::class.java) {
|
||||
taskConfigAction as KaptWithoutKotlincConfigAction
|
||||
taskConfigAction as KaptWithoutKotlincConfig
|
||||
project.registerTask(taskName, KaptWithoutKotlincTask::class.java, emptyList()).also {
|
||||
taskConfigAction.execute(it)
|
||||
}
|
||||
} else {
|
||||
taskConfigAction as KaptWithKotlincConfigAction
|
||||
taskConfigAction as KaptWithKotlincConfig
|
||||
project.registerTask(taskName, KaptWithKotlincTask::class.java, emptyList()).also {
|
||||
taskConfigAction.execute(it)
|
||||
}
|
||||
@@ -593,6 +588,21 @@ internal fun buildKaptSubpluginOptions(
|
||||
return pluginOptions
|
||||
}
|
||||
|
||||
/* Returns AP options from KAPT static DSL. */
|
||||
internal fun getNonAndroidDslApOptions(
|
||||
kaptExtension: KaptExtension,
|
||||
project: Project,
|
||||
kotlinSourcesOutputDir: Iterable<File>,
|
||||
variantData: BaseVariant?,
|
||||
androidExtension: BaseExtension?
|
||||
): Provider<List<SubpluginOption>> {
|
||||
return project.provider {
|
||||
kaptExtension.getAdditionalArguments(project, variantData, androidExtension).toList()
|
||||
.map { SubpluginOption(it.first, it.second) } +
|
||||
FilesSubpluginOption(Kapt3GradleSubplugin.KAPT_KOTLIN_GENERATED, kotlinSourcesOutputDir)
|
||||
}
|
||||
}
|
||||
|
||||
private fun encodeList(options: Map<String, String>): String {
|
||||
val os = ByteArrayOutputStream()
|
||||
val oos = ObjectOutputStream(os)
|
||||
|
||||
+9
-10
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.Incremental
|
||||
@@ -27,9 +26,10 @@ import org.gradle.work.NormalizeLineEndings
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
||||
import org.jetbrains.kotlin.incremental.classpathAsList
|
||||
import org.jetbrains.kotlin.incremental.destinationAsFile
|
||||
import java.io.File
|
||||
@@ -43,13 +43,12 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
KotlinJvmOptionsImpl(),
|
||||
workerExecutor,
|
||||
objectFactory
|
||||
) {
|
||||
), KaptGenerateStubs {
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val stubsDir: DirectoryProperty
|
||||
|
||||
@get:Internal("Not an input, just passed as kapt args. ")
|
||||
abstract val kaptClasspath: ConfigurableFileCollection
|
||||
// Bug in Gradle - without this override Gradle complains @Internal is not
|
||||
// compatible with @Classpath and @Incremental annotations
|
||||
@get:Internal
|
||||
abstract override val libraries: ConfigurableFileCollection
|
||||
|
||||
/* Used as input as empty kapt classpath should not trigger stub generation, but a non-empty one should. */
|
||||
@Input
|
||||
@@ -88,10 +87,10 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
abstract override val scriptSources: FileCollection
|
||||
override val scriptSources: FileCollection = objectFactory.fileCollection()
|
||||
|
||||
@get:Internal
|
||||
abstract override val androidLayoutResources: FileCollection
|
||||
override val androidLayoutResources: FileCollection = objectFactory.fileCollection()
|
||||
|
||||
override val incrementalProps: List<FileCollection>
|
||||
get() = listOf(
|
||||
|
||||
+6
-59
@@ -3,7 +3,6 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
@@ -20,6 +19,7 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptClasspathChange
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChanges
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.UnknownSnapshot
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilerPluginConfig
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
@@ -32,7 +32,8 @@ abstract class KaptTask @Inject constructor(
|
||||
objectFactory: ObjectFactory
|
||||
) : DefaultTask(),
|
||||
TaskWithLocalState,
|
||||
UsesKotlinJavaToolchain {
|
||||
UsesKotlinJavaToolchain,
|
||||
BaseKapt {
|
||||
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
@@ -41,26 +42,10 @@ abstract class KaptTask @Inject constructor(
|
||||
outputs.cacheIf(reason) { useBuildCache }
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal abstract val stubsDir: DirectoryProperty
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val kaptClasspath: ConfigurableFileCollection
|
||||
|
||||
//part of kaptClasspath consisting from external artifacts only
|
||||
//basically kaptClasspath = kaptExternalClasspath + artifacts built locally
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val kaptExternalClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val compilerClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
internal abstract val kaptClasspathConfigurationNames: ListProperty<String>
|
||||
|
||||
@get:PathSensitive(PathSensitivity.NONE)
|
||||
@get:Incremental
|
||||
@get:NormalizeLineEndings
|
||||
@@ -70,39 +55,19 @@ abstract class KaptTask @Inject constructor(
|
||||
abstract val classpathStructure: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
abstract val kaptPluginOptions: ListProperty<CompilerPluginOptions>
|
||||
|
||||
/**
|
||||
* Output directory that contains caches necessary to support incremental annotation processing.
|
||||
*/
|
||||
@get:LocalState
|
||||
abstract val incAptCache: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
internal abstract val classesDir: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val destinationDir: DirectoryProperty
|
||||
|
||||
/** Used in the model builder only. */
|
||||
@get:OutputDirectory
|
||||
abstract val kotlinSourcesDestinationDir: DirectoryProperty
|
||||
abstract val kaptPluginOptions: ListProperty<CompilerPluginConfig>
|
||||
|
||||
@get:Nested
|
||||
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
override val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
|
||||
@get:Input
|
||||
internal val includeCompileClasspath: Property<Boolean> = objectFactory
|
||||
override val includeCompileClasspath: Property<Boolean> = objectFactory
|
||||
.propertyWithConvention(true)
|
||||
.chainedFinalizeValueOnRead()
|
||||
|
||||
@get:Input
|
||||
internal var isIncremental = true
|
||||
|
||||
// @Internal because _abiClasspath and _nonAbiClasspath are used for actual checks
|
||||
@get:Internal
|
||||
abstract val classpath: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objectFactory
|
||||
.propertyWithNewInstance({ null })
|
||||
@@ -136,17 +101,6 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:Internal
|
||||
var useBuildCache: Boolean = false
|
||||
|
||||
/** Needed for the model builder. */
|
||||
@get:Internal
|
||||
abstract val sourceSetName: Property<String>
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:NormalizeLineEndings
|
||||
@get:Incremental
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
abstract val source: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
override val metrics: Property<BuildMetricsReporter> = objectFactory
|
||||
.property(BuildMetricsReporterImpl())
|
||||
@@ -154,9 +108,6 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:Input
|
||||
abstract val verbose: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
abstract val defaultJavaSourceCompatibility: Property<String>
|
||||
|
||||
protected fun checkAnnotationProcessorClasspath() {
|
||||
if (!includeCompileClasspath.get()) return
|
||||
|
||||
@@ -186,10 +137,6 @@ abstract class KaptTask @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(gavra): Here we assume that kotlinc and javac output is available for incremental runs. We should insert some checks.
|
||||
@get:Internal
|
||||
internal abstract val compiledSources: ConfigurableFileCollection
|
||||
|
||||
protected fun getIncrementalChanges(inputChanges: InputChanges): KaptIncrementalChanges {
|
||||
return if (isIncremental) {
|
||||
findClasspathChanges(inputChanges)
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChan
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
||||
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
|
||||
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilerPluginConfig
|
||||
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
@@ -46,7 +47,7 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
|
||||
/** Used only as task input, actual values come from [compileKotlinArgumentsContributor]. */
|
||||
@get:Nested
|
||||
internal abstract val additionalPluginOptionsAsInputs: ListProperty<CompilerPluginOptions>
|
||||
internal abstract val additionalPluginOptionsAsInputs: ListProperty<CompilerPluginConfig>
|
||||
|
||||
override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
|
||||
|
||||
|
||||
+2
-11
@@ -16,7 +16,6 @@ import org.gradle.api.tasks.*
|
||||
import org.gradle.kotlin.dsl.listProperty
|
||||
import org.gradle.process.CommandLineArgumentProvider
|
||||
import org.gradle.work.InputChanges
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import org.gradle.workers.IsolationMode
|
||||
import org.gradle.workers.WorkAction
|
||||
import org.gradle.workers.WorkParameters
|
||||
@@ -24,8 +23,7 @@ import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.ClassLoadersCache
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.rootOrSelf
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChanges
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinAndroidPluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kapt
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
@@ -40,11 +38,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
objectFactory: ObjectFactory,
|
||||
private val providerFactory: ProviderFactory,
|
||||
private val workerExecutor: WorkerExecutor
|
||||
) : KaptTask(objectFactory) {
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val kaptJars: ConfigurableFileCollection
|
||||
) : KaptTask(objectFactory), Kapt {
|
||||
|
||||
@get:Input
|
||||
var classLoadersCacheSize: Int = 0
|
||||
@@ -61,9 +55,6 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
@get:Input
|
||||
abstract val javacOptions: MapProperty<String, String>
|
||||
|
||||
@get:Input
|
||||
abstract val addJdkClassesToClasspath: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
internal val projectDir = project.projectDir
|
||||
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.plugin
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.KaptGenerateStubsConfig
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.KaptWithoutKotlincConfig
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig
|
||||
|
||||
/** Plugin that can be used by third-party plugins to create Kotlin-specific DSL and tasks (compilation and KAPT) for JVM platform. */
|
||||
abstract class KotlinBaseApiPlugin : KotlinBasePlugin(), KotlinJvmFactory {
|
||||
|
||||
private val logger = Logging.getLogger(KotlinBaseApiPlugin::class.java)
|
||||
override val pluginVersion = getKotlinPluginVersion(logger)
|
||||
|
||||
private lateinit var myProject: Project
|
||||
private val taskCreator = KotlinTasksProvider()
|
||||
|
||||
override fun apply(project: Project) {
|
||||
super.apply(project)
|
||||
myProject = project
|
||||
setupAttributeMatchingStrategy(project, isKotlinGranularMetadata = false)
|
||||
}
|
||||
|
||||
override fun addCompilerPluginDependency(dependency: Provider<Any>) {
|
||||
myProject.dependencies.addProvider(
|
||||
PLUGIN_CLASSPATH_CONFIGURATION_NAME,
|
||||
dependency
|
||||
)
|
||||
}
|
||||
|
||||
override fun getCompilerPlugins(): FileCollection {
|
||||
return myProject.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
|
||||
}
|
||||
|
||||
override fun createKotlinJvmOptions(): KotlinJvmOptions {
|
||||
return KotlinJvmOptionsImpl()
|
||||
}
|
||||
|
||||
override val kotlinExtension: KotlinProjectExtension by lazy {
|
||||
myProject.objects.newInstance(KotlinProjectExtension::class.java, myProject)
|
||||
}
|
||||
|
||||
override val kaptExtension: KaptExtension by lazy {
|
||||
myProject.objects.newInstance(KaptExtension::class.java)
|
||||
}
|
||||
|
||||
override fun registerKotlinJvmCompileTask(taskName: String): TaskProvider<out KotlinJvmCompile> {
|
||||
return taskCreator.registerKotlinJVMTask(
|
||||
myProject, taskName, KotlinJvmOptionsImpl(), KotlinCompileConfig(myProject, kotlinExtension)
|
||||
)
|
||||
}
|
||||
|
||||
override fun registerKaptGenerateStubsTask(taskName: String): TaskProvider<out KaptGenerateStubs> {
|
||||
val taskConfig = KaptGenerateStubsConfig(myProject, kotlinExtension, kaptExtension)
|
||||
return myProject.registerTask(taskName, KaptGenerateStubsTask::class.java, emptyList()).also {
|
||||
taskConfig.execute(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerKaptTask(taskName: String): TaskProvider<out Kapt> {
|
||||
val taskConfiguration = KaptWithoutKotlincConfig(myProject, kaptExtension)
|
||||
return myProject.registerTask(taskName, KaptWithoutKotlincTask::class.java, emptyList()).also {
|
||||
taskConfiguration.execute(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -933,7 +933,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool
|
||||
|
||||
val configAction = KotlinCompileConfig(compilation)
|
||||
configAction.configureTask { task ->
|
||||
task.parentKotlinOptionsImpl.value(rootKotlinOptions).disallowChanges()
|
||||
task.parentKotlinOptions.value(rootKotlinOptions).disallowChanges()
|
||||
task.useModuleDetection.value(true).disallowChanges()
|
||||
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
||||
task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName"))
|
||||
|
||||
+76
-57
@@ -20,6 +20,7 @@ import org.gradle.api.GradleException
|
||||
import org.gradle.api.NamedDomainObjectFactory
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||
import org.jetbrains.kotlin.compilerRunner.registerCommonizerClasspathConfigurationIfNecessary
|
||||
@@ -40,8 +41,9 @@ import org.jetbrains.kotlin.gradle.report.HttpReportService
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
|
||||
import org.jetbrains.kotlin.gradle.tooling.registerBuildKotlinToolingMetadataTask
|
||||
import org.jetbrains.kotlin.gradle.utils.addGradlePluginMetadataAttributes
|
||||
@@ -53,22 +55,15 @@ import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||
import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
|
||||
open val projectExtensionClass: KClass<out KotlinTopLevelExtension> get() = KotlinProjectExtension::class
|
||||
|
||||
abstract val pluginVariant: String
|
||||
|
||||
internal open fun kotlinSourceSetFactory(project: Project): NamedDomainObjectFactory<KotlinSourceSet> =
|
||||
if (PropertiesProvider(project).experimentalKpmModelMapping)
|
||||
FragmentMappedKotlinSourceSetFactory(project)
|
||||
else DefaultKotlinSourceSetFactory(project)
|
||||
/**
|
||||
* Base Kotlin plugin that is responsible for creating basic build services, configurations,
|
||||
* and other setup that is common for all Kotlin projects.
|
||||
*/
|
||||
abstract class KotlinBasePlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
val kotlinPluginVersion = project.getKotlinPluginVersion()
|
||||
|
||||
project.logger.info("Using Kotlin Gradle Plugin $pluginVariant variant")
|
||||
|
||||
val statisticsReporter = KotlinBuildStatsService.getOrCreateInstance(project)
|
||||
statisticsReporter?.report(StringMetrics.KOTLIN_COMPILER_VERSION, kotlinPluginVersion)
|
||||
|
||||
@@ -86,6 +81,69 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
addGradlePluginMetadataAttributes(project)
|
||||
}
|
||||
|
||||
KotlinGradleBuildServices.registerIfAbsent(project, kotlinPluginVersion).get()
|
||||
KotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
|
||||
|
||||
BuildMetricsReporterService.registerIfAbsent(project)?.also {
|
||||
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it)
|
||||
}
|
||||
HttpReportService.registerIfAbsent(project, kotlinPluginVersion)?.also {
|
||||
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addKotlinCompilerConfiguration(project: Project) {
|
||||
project
|
||||
.configurations
|
||||
.maybeCreate(COMPILER_CLASSPATH_CONFIGURATION_NAME)
|
||||
.defaultDependencies {
|
||||
it.add(
|
||||
project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_COMPILER_EMBEDDABLE:${project.getKotlinPluginVersion()}")
|
||||
)
|
||||
}
|
||||
project
|
||||
.tasks
|
||||
.withType(AbstractKotlinCompileTool::class.java)
|
||||
.configureEach { task ->
|
||||
task.defaultCompilerClasspath.setFrom(
|
||||
project.configurations.named(COMPILER_CLASSPATH_CONFIGURATION_NAME)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun setupAttributeMatchingStrategy(
|
||||
project: Project,
|
||||
isKotlinGranularMetadata: Boolean = project.isKotlinGranularMetadataEnabled
|
||||
) = with(project.dependencies.attributesSchema) {
|
||||
KotlinPlatformType.setupAttributesMatchingStrategy(this)
|
||||
KotlinUsages.setupAttributesMatchingStrategy(this, isKotlinGranularMetadata)
|
||||
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
|
||||
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
|
||||
CInteropKlibLibraryElements.setupAttributesMatchingStrategy(this)
|
||||
}
|
||||
|
||||
open fun whenBuildEvaluated(project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class KotlinBasePluginWrapper : KotlinBasePlugin() {
|
||||
|
||||
open val projectExtensionClass: KClass<out KotlinTopLevelExtension> get() = KotlinProjectExtension::class
|
||||
|
||||
abstract val pluginVariant: String
|
||||
|
||||
internal open fun kotlinSourceSetFactory(project: Project): NamedDomainObjectFactory<KotlinSourceSet> =
|
||||
if (PropertiesProvider(project).experimentalKpmModelMapping)
|
||||
FragmentMappedKotlinSourceSetFactory(project)
|
||||
else DefaultKotlinSourceSetFactory(project)
|
||||
|
||||
override fun apply(project: Project) {
|
||||
super.apply(project)
|
||||
val kotlinPluginVersion = project.getKotlinPluginVersion()
|
||||
|
||||
project.logger.info("Using Kotlin Gradle Plugin $pluginVariant variant")
|
||||
|
||||
project.configurations.maybeCreate(NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME).apply {
|
||||
isVisible = false
|
||||
isCanBeConsumed = false
|
||||
@@ -96,17 +154,6 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
|
||||
project.registerDefaultVariantImplementations()
|
||||
|
||||
KotlinGradleBuildServices.registerIfAbsent(project, kotlinPluginVersion).get()
|
||||
|
||||
KotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
|
||||
|
||||
BuildMetricsReporterService.registerIfAbsent(project)?.also {
|
||||
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it)
|
||||
}
|
||||
|
||||
HttpReportService.registerIfAbsent(project, kotlinPluginVersion)
|
||||
?.also { BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it) }
|
||||
|
||||
project.createKotlinExtension(projectExtensionClass).apply {
|
||||
coreLibrariesVersion = kotlinPluginVersion
|
||||
|
||||
@@ -140,38 +187,8 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
)
|
||||
}
|
||||
|
||||
private fun addKotlinCompilerConfiguration(project: Project) {
|
||||
project
|
||||
.configurations
|
||||
.maybeCreate(COMPILER_CLASSPATH_CONFIGURATION_NAME)
|
||||
.defaultDependencies {
|
||||
it.add(
|
||||
project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_COMPILER_EMBEDDABLE:${project.getKotlinPluginVersion()}")
|
||||
)
|
||||
}
|
||||
project
|
||||
.tasks
|
||||
.withType(AbstractKotlinCompile::class.java)
|
||||
.configureEach { task ->
|
||||
task.defaultCompilerClasspath.setFrom(
|
||||
project.configurations.named(COMPILER_CLASSPATH_CONFIGURATION_NAME)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
open fun whenBuildEvaluated(project: Project) {
|
||||
}
|
||||
|
||||
internal open fun createTestRegistry(project: Project) = KotlinTestsRegistry(project)
|
||||
|
||||
private fun setupAttributeMatchingStrategy(project: Project) = with(project.dependencies.attributesSchema) {
|
||||
KotlinPlatformType.setupAttributesMatchingStrategy(this)
|
||||
KotlinUsages.setupAttributesMatchingStrategy(project, this)
|
||||
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
|
||||
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
|
||||
CInteropKlibLibraryElements.setupAttributesMatchingStrategy(this)
|
||||
}
|
||||
|
||||
internal abstract fun getPlugin(
|
||||
project: Project,
|
||||
): Plugin<Project>
|
||||
@@ -278,10 +295,12 @@ abstract class AbstractKotlinPm20PluginWrapper(
|
||||
get() = KotlinPm20ProjectExtension::class
|
||||
}
|
||||
|
||||
fun Project.getKotlinPluginVersion(): String {
|
||||
fun Project.getKotlinPluginVersion() = getKotlinPluginVersion(project.logger)
|
||||
|
||||
fun getKotlinPluginVersion(logger: Logger): String {
|
||||
if (!kotlinPluginVersionFromResources.isInitialized()) {
|
||||
project.logger.kotlinDebug("Loading version information")
|
||||
project.logger.kotlinDebug("Found project version [${kotlinPluginVersionFromResources.value}")
|
||||
logger.kotlinDebug("Loading version information")
|
||||
logger.kotlinDebug("Found project version [${kotlinPluginVersionFromResources.value}")
|
||||
}
|
||||
return kotlinPluginVersionFromResources.value
|
||||
}
|
||||
|
||||
+2
-3
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
|
||||
object KotlinUsages {
|
||||
const val KOTLIN_API = "kotlin-api"
|
||||
@@ -167,7 +166,7 @@ object KotlinUsages {
|
||||
closestMatch(candidateValues.single { it?.name == name }!!)
|
||||
}
|
||||
|
||||
internal fun setupAttributesMatchingStrategy(project: Project, attributesSchema: AttributesSchema) {
|
||||
internal fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema, isKotlinGranularMetadata: Boolean) {
|
||||
attributesSchema.attribute(USAGE_ATTRIBUTE) { strategy ->
|
||||
strategy.compatibilityRules.add(KotlinJavaRuntimeJarsCompatibility::class.java)
|
||||
strategy.disambiguationRules.add(KotlinUsagesDisambiguation::class.java)
|
||||
@@ -175,7 +174,7 @@ object KotlinUsages {
|
||||
strategy.compatibilityRules.add(KotlinCinteropCompatibility::class.java)
|
||||
strategy.disambiguationRules.add(KotlinCinteropDisambiguation::class.java)
|
||||
|
||||
if (project.isKotlinGranularMetadataEnabled) {
|
||||
if (isKotlinGranularMetadata) {
|
||||
strategy.compatibilityRules.add(KotlinMetadataCompatibility::class.java)
|
||||
strategy.disambiguationRules.add(KotlinMetadataDisambiguation::class.java)
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import javax.inject.Inject
|
||||
|
||||
@CacheableTask
|
||||
abstract class KotlinJsIrLink @Inject constructor(
|
||||
private val objectFactory: ObjectFactory,
|
||||
objectFactory: ObjectFactory,
|
||||
workerExecutor: WorkerExecutor,
|
||||
private val projectLayout: ProjectLayout
|
||||
) : Kotlin2JsCompile(
|
||||
|
||||
+16
-43
@@ -17,9 +17,11 @@
|
||||
package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilerPluginConfig
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
|
||||
class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
|
||||
@@ -51,44 +53,6 @@ class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
return newOptions
|
||||
}
|
||||
|
||||
@Input
|
||||
fun getAsTaskInputArgs(): Map<String, String> {
|
||||
val result = mutableMapOf<String, String>()
|
||||
subpluginOptionsByPluginId.forEach { (id, subpluginOptions) ->
|
||||
result += computeForSubpluginId(id, subpluginOptions)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun computeForSubpluginId(subpluginId: String, subpluginOptions: List<SubpluginOption>): Map<String, String> {
|
||||
// There might be several options with the same key. We group them together
|
||||
// and add an index to the Gradle input property name to resolve possible duplication:
|
||||
val result = mutableMapOf<String, String>()
|
||||
val pluginOptionsGrouped = subpluginOptions.groupBy { it.key }
|
||||
for ((optionKey, optionsGroup) in pluginOptionsGrouped) {
|
||||
optionsGroup.forEachIndexed { index, option ->
|
||||
val indexSuffix = if (optionsGroup.size > 1) ".$index" else ""
|
||||
when (option) {
|
||||
is InternalSubpluginOption -> return@forEachIndexed
|
||||
|
||||
is CompositeSubpluginOption -> {
|
||||
val subpluginIdWithWrapperKey = "$subpluginId.$optionKey$indexSuffix"
|
||||
result += computeForSubpluginId(subpluginIdWithWrapperKey, option.originalOptions)
|
||||
}
|
||||
|
||||
is FilesSubpluginOption -> when (option.kind) {
|
||||
FilesOptionKind.INTERNAL -> Unit
|
||||
}.run { /* exhaustive when */ }
|
||||
|
||||
else -> {
|
||||
result["$subpluginId." + option.key + indexSuffix] = option.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun copyOptionsFrom(options: CompilerPluginConfig) {
|
||||
options.allOptions().forEach { entry ->
|
||||
optionsByPluginId[entry.key] = entry.value.toMutableList()
|
||||
@@ -96,7 +60,16 @@ class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ListProperty<CompilerPluginOptions>.toSingleCompilerPluginOptions(): CompilerPluginOptions {
|
||||
val values = this.orNull ?: return CompilerPluginOptions()
|
||||
return values.reduceOrNull(CompilerPluginOptions::plus) ?: CompilerPluginOptions()
|
||||
internal fun ListProperty<out CompilerPluginConfig>.toSingleCompilerPluginOptions(): CompilerPluginOptions {
|
||||
var res = CompilerPluginOptions()
|
||||
this.get().forEach { res += it }
|
||||
return res
|
||||
}
|
||||
|
||||
internal fun Provider<List<SubpluginOption>>.toCompilerPluginOptions(): Provider<CompilerPluginOptions> {
|
||||
return map {
|
||||
val res = CompilerPluginOptions()
|
||||
it.forEach { res.addPluginArgument(Kapt3GradleSubplugin.KAPT_SUBPLUGIN_ID, it) }
|
||||
return@map res
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -133,7 +133,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
val jdkVersion = javaVersion.get()
|
||||
|
||||
// parentKotlinOptionsImpl is set from 'kotlin-android' plugin
|
||||
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptionsImpl.orNull)
|
||||
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptions.orNull)
|
||||
.mapNotNull { (it as KotlinJvmOptionsImpl).jvmTarget }
|
||||
|
||||
if (appliedJvmTargets.isEmpty()) {
|
||||
@@ -158,7 +158,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
) {
|
||||
kotlinCompileTaskProvider()?.let { task ->
|
||||
// parentKotlinOptionsImpl is set from 'kotlin-android' plugin
|
||||
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptionsImpl.orNull)
|
||||
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptions.orNull)
|
||||
.mapNotNull { (it as KotlinJvmOptionsImpl).jvmTarget }
|
||||
|
||||
if (appliedJvmTargets.isEmpty()) {
|
||||
|
||||
+22
-69
@@ -14,7 +14,6 @@ import org.gradle.api.file.*
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.SetProperty
|
||||
@@ -77,7 +76,7 @@ const val USING_JS_IR_BACKEND_MESSAGE = "Using Kotlin/JS IR backend"
|
||||
abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constructor(
|
||||
objectFactory: ObjectFactory
|
||||
) : DefaultTask(),
|
||||
PatternFilterable,
|
||||
KotlinCompileTool,
|
||||
CompilerArgumentAwareWithInput<T>,
|
||||
TaskWithLocalState {
|
||||
|
||||
@@ -91,30 +90,17 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constr
|
||||
|
||||
private val sourceFiles = objectFactory.fileCollection()
|
||||
|
||||
@get:InputFiles
|
||||
@get:SkipWhenEmpty
|
||||
@get:NormalizeLineEndings
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
open val sources: FileCollection = objectFactory.fileCollection()
|
||||
override val sources: FileCollection = objectFactory.fileCollection()
|
||||
.from(
|
||||
{ sourceFiles.asFileTree.matching(patternFilterable) }
|
||||
)
|
||||
|
||||
/**
|
||||
* Sets the source for this task.
|
||||
* The given source object is evaluated as per [org.gradle.api.Project.files].
|
||||
*/
|
||||
open fun setSource(source: Any) {
|
||||
sourceFiles.from(source)
|
||||
override fun source(vararg sources: Any) {
|
||||
sourceFiles.from(sources)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source for this task.
|
||||
* The given source object is evaluated as per [org.gradle.api.Project.files].
|
||||
*/
|
||||
open fun setSource(vararg source: Any) {
|
||||
sourceFiles.from(source)
|
||||
override fun setSource(vararg sources: Any) {
|
||||
sourceFiles.from(sources)
|
||||
}
|
||||
|
||||
fun disallowSourceChanges() {
|
||||
@@ -167,14 +153,6 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constr
|
||||
patternFilterable.exclude(excludeSpec)
|
||||
}
|
||||
|
||||
@get:Classpath
|
||||
@get:NormalizeLineEndings
|
||||
@get:Incremental
|
||||
abstract val libraries: ConfigurableFileCollection
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val destinationDirectory: DirectoryProperty
|
||||
|
||||
@get:Internal
|
||||
override val metrics: Property<BuildMetricsReporter> = project.objects
|
||||
.property(BuildMetricsReporterImpl())
|
||||
@@ -254,7 +232,8 @@ abstract class GradleCompileTaskProvider @Inject constructor(
|
||||
abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constructor(
|
||||
objectFactory: ObjectFactory
|
||||
) : AbstractKotlinCompileTool<T>(objectFactory),
|
||||
CompileUsingKotlinDaemonWithNormalization {
|
||||
CompileUsingKotlinDaemonWithNormalization,
|
||||
BaseKotlinCompile {
|
||||
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
@@ -300,21 +279,10 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
|
||||
internal fun reportingSettings() = buildMetricsReporterService.orNull?.parameters?.reportingSettings ?: ReportingSettings()
|
||||
|
||||
@get:Input
|
||||
internal abstract val useModuleDetection: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
protected val multiModuleICSettings: MultiModuleICSettings
|
||||
get() = MultiModuleICSettings(buildHistoryFile.get().asFile, useModuleDetection.get())
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val pluginClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Nested
|
||||
internal abstract val pluginOptions: ListProperty<CompilerPluginOptions>
|
||||
|
||||
|
||||
/**
|
||||
* Plugin Data provided by [KpmCompilerPlugin]
|
||||
*/
|
||||
@@ -326,9 +294,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
@get:Internal
|
||||
internal val javaOutputDir: DirectoryProperty = objectFactory.directoryProperty()
|
||||
|
||||
@get:Internal
|
||||
internal abstract val sourceSetName: Property<String>
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:NormalizeLineEndings
|
||||
@@ -336,9 +301,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal val commonSourceSet: ConfigurableFileCollection = objectFactory.fileCollection()
|
||||
|
||||
@get:Input
|
||||
internal abstract val moduleName: Property<String>
|
||||
|
||||
@get:Internal
|
||||
val abiSnapshotFile
|
||||
get() = taskBuildCacheableOutputDirectory.file(IncrementalCompilerRunner.ABI_SNAPSHOT_FILE_NAME)
|
||||
@@ -352,9 +314,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
@get:Internal
|
||||
internal val friendSourceSets = objectFactory.listProperty(String::class.java)
|
||||
|
||||
@get:Internal // takes part in the compiler arguments
|
||||
abstract val friendPaths: ConfigurableFileCollection
|
||||
|
||||
private val kotlinLogger by lazy { GradleKotlinLogger(logger) }
|
||||
|
||||
@get:Internal
|
||||
@@ -496,9 +455,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
taskOutputsBackup: TaskOutputsBackup?
|
||||
)
|
||||
|
||||
@get:Input
|
||||
internal abstract val multiPlatformEnabled: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
internal val abstractKotlinCompileArgumentsContributor by lazy {
|
||||
AbstractKotlinCompileArgumentsContributor(
|
||||
@@ -533,7 +489,7 @@ class KotlinJvmCompilerArgumentsProvider
|
||||
val compileClasspath: Iterable<File> = taskProvider.libraries
|
||||
val destinationDir: File = taskProvider.destinationDirectory.get().asFile
|
||||
internal val kotlinOptions: List<KotlinJvmOptionsImpl> = listOfNotNull(
|
||||
taskProvider.parentKotlinOptionsImpl.orNull as? KotlinJvmOptionsImpl,
|
||||
taskProvider.parentKotlinOptions.orNull as? KotlinJvmOptionsImpl,
|
||||
taskProvider.kotlinOptions as KotlinJvmOptionsImpl
|
||||
)
|
||||
}
|
||||
@@ -550,9 +506,6 @@ abstract class KotlinCompile @Inject constructor(
|
||||
KotlinJvmCompile,
|
||||
UsesKotlinJavaToolchain {
|
||||
|
||||
@get:Internal("Takes part in compiler args.")
|
||||
internal abstract val parentKotlinOptionsImpl: Property<KotlinJvmOptions>
|
||||
|
||||
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
|
||||
*
|
||||
* Example: a Java source file with `package com.example.my.package` is located in directory `src/main/java/my/package`.
|
||||
@@ -575,16 +528,16 @@ abstract class KotlinCompile @Inject constructor(
|
||||
"Replaced with 'libraries' input",
|
||||
replaceWith = ReplaceWith("libraries")
|
||||
)
|
||||
@Internal
|
||||
fun getClasspath(): FileCollection = libraries
|
||||
fun setClasspath(classpath: FileCollection) {
|
||||
libraries.setFrom(classpath)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Replaced with 'libraries' input",
|
||||
replaceWith = ReplaceWith("libraries")
|
||||
)
|
||||
fun setClasspath(configuration: FileCollection) {
|
||||
libraries.setFrom(configuration)
|
||||
}
|
||||
@Internal
|
||||
fun getClasspath(): FileCollection = libraries
|
||||
|
||||
@get:Input
|
||||
abstract val useKotlinAbiSnapshot: Property<Boolean>
|
||||
@@ -881,17 +834,17 @@ abstract class KotlinCompile @Inject constructor(
|
||||
}
|
||||
|
||||
// override setSource to track Java and script sources as well
|
||||
override fun setSource(source: Any) {
|
||||
javaSourceFiles.from(source)
|
||||
scriptSourceFiles.from(source)
|
||||
super.setSource(source)
|
||||
override fun source(vararg sources: Any) {
|
||||
javaSourceFiles.from(sources)
|
||||
scriptSourceFiles.from(sources)
|
||||
super.setSource(sources)
|
||||
}
|
||||
|
||||
// override source to track Java and script sources as well
|
||||
override fun setSource(vararg source: Any) {
|
||||
javaSourceFiles.from(*source)
|
||||
scriptSourceFiles.from(*source)
|
||||
super.setSource(*source)
|
||||
override fun setSource(vararg sources: Any) {
|
||||
javaSourceFiles.from(*sources)
|
||||
scriptSourceFiles.from(*sources)
|
||||
super.setSource(*sources)
|
||||
}
|
||||
|
||||
private fun getClasspathChanges(inputChanges: InputChanges): ClasspathChanges = when {
|
||||
|
||||
+34
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
@@ -21,7 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinO
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME
|
||||
import java.util.concurrent.Callable
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
/**
|
||||
* Configuration for the base compile task, [org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile].
|
||||
@@ -31,39 +32,22 @@ import java.util.concurrent.Callable
|
||||
*/
|
||||
internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile<*>>(
|
||||
project: Project,
|
||||
private val ext: KotlinTopLevelExtension,
|
||||
private val languageSettings: Provider<LanguageSettings>
|
||||
) : TaskConfigAction<TASK>(project) {
|
||||
|
||||
constructor(compilation: KotlinCompilationData<*>) : this(compilation.project) {
|
||||
val ext = compilation.project.topLevelExtension
|
||||
|
||||
init {
|
||||
configureTaskProvider { taskProvider ->
|
||||
project.runOnceAfterEvaluated("apply properties and language settings to ${taskProvider.name}") {
|
||||
taskProvider.configure {
|
||||
applyLanguageSettingsToKotlinOptions(
|
||||
compilation.languageSettings, (it as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
||||
languageSettings.get(), (it as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configureTask { task ->
|
||||
task.friendPaths.from({ compilation.friendPaths })
|
||||
if (compilation is KotlinCompilation<*>) {
|
||||
task.friendSourceSets.value(providers.provider { compilation.associateWithClosure.map { it.name } })
|
||||
.disallowChanges()
|
||||
task.pluginClasspath.from(compilation.project.configurations.getByName(compilation.pluginConfigurationName))
|
||||
}
|
||||
task.moduleName.set(providers.provider { compilation.moduleName })
|
||||
task.sourceSetName.value(providers.provider { compilation.compilationPurpose })
|
||||
task.multiPlatformEnabled.value(
|
||||
providers.provider {
|
||||
compilation.project.plugins.any {
|
||||
it is KotlinPlatformPluginBase ||
|
||||
it is AbstractKotlinMultiplatformPluginWrapper ||
|
||||
it is AbstractKotlinPm20PluginWrapper
|
||||
}
|
||||
}
|
||||
)
|
||||
val propertiesProvider = project.kotlinPropertiesProvider
|
||||
|
||||
task.taskBuildCacheableOutputDirectory
|
||||
@@ -85,7 +69,6 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
|
||||
}
|
||||
task.compilerExecutionStrategy.value(propertiesProvider.kotlinCompilerExecutionStrategy)
|
||||
|
||||
// Default values
|
||||
task.incremental = false
|
||||
task.useModuleDetection.convention(false)
|
||||
}
|
||||
@@ -96,6 +79,33 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
|
||||
|
||||
protected fun getClasspathSnapshotDir(task: TASK): Provider<Directory> =
|
||||
getKotlinBuildDir(task).map { it.dir("classpath-snapshot") }
|
||||
|
||||
constructor(compilation: KotlinCompilationData<*>) : this(
|
||||
compilation.project, compilation.project.topLevelExtension, compilation.project.provider { compilation.languageSettings }
|
||||
) {
|
||||
configureTask { task ->
|
||||
task.friendPaths.from({ compilation.friendPaths })
|
||||
if (compilation is KotlinCompilation<*>) {
|
||||
task.friendSourceSets
|
||||
.value(providers.provider { compilation.associateWithClosure.map { it.name } })
|
||||
.disallowChanges()
|
||||
task.pluginClasspath.from(
|
||||
compilation.project.configurations.getByName(compilation.pluginConfigurationName)
|
||||
)
|
||||
}
|
||||
task.moduleName.set(providers.provider { compilation.moduleName })
|
||||
task.sourceSetName.value(providers.provider { compilation.compilationPurpose })
|
||||
task.multiPlatformEnabled.value(
|
||||
providers.provider {
|
||||
compilation.project.plugins.any {
|
||||
it is KotlinPlatformPluginBase ||
|
||||
it is AbstractKotlinMultiplatformPluginWrapper ||
|
||||
it is AbstractKotlinPm20PluginWrapper
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class TaskConfigAction<TASK : Task>(protected val project: Project) {
|
||||
|
||||
+51
-35
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID
|
||||
@@ -26,47 +25,26 @@ import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isInc
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformAction
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinAndroidPluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.toCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||
import org.jetbrains.kotlin.gradle.utils.listProperty
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal open class KaptConfigAction<TASK : KaptTask>(
|
||||
internal open class KaptConfig<TASK : KaptTask>(
|
||||
project: Project,
|
||||
protected val ext: KaptExtension,
|
||||
) : TaskConfigAction<TASK>(project) {
|
||||
|
||||
internal constructor(kotlinCompileTask: KotlinCompile, ext: KaptExtension) : this(kotlinCompileTask.project, ext) {
|
||||
init {
|
||||
configureTaskProvider { taskProvider ->
|
||||
val kaptClasspathSnapshot = getKaptClasspathSnapshot(taskProvider)
|
||||
|
||||
taskProvider.configure { task ->
|
||||
task.classpath.from(kotlinCompileTask.libraries)
|
||||
task.compiledSources.from(
|
||||
kotlinCompileTask.destinationDirectory,
|
||||
Callable { kotlinCompileTask.javaOutputDir.takeIf { it.isPresent } })
|
||||
.disallowChanges()
|
||||
task.sourceSetName.value(kotlinCompileTask.sourceSetName).disallowChanges()
|
||||
|
||||
val kaptSources = objectFactory
|
||||
.fileCollection()
|
||||
.from(kotlinCompileTask.javaSources, task.stubsDir)
|
||||
.asFileTree
|
||||
.matching { it.include("**/*.java") }
|
||||
.filter {
|
||||
it.exists() &&
|
||||
!isAncestor(task.destinationDir.get().asFile, it) &&
|
||||
!isAncestor(task.classesDir.get().asFile, it)
|
||||
}
|
||||
task.source.from(kaptSources).disallowChanges()
|
||||
task.verbose.set(KaptTask.queryKaptVerboseProperty(project))
|
||||
task.compilerClasspath.from(providers.provider { kotlinCompileTask.defaultCompilerClasspath })
|
||||
|
||||
task.isIncremental = project.isIncrementalKapt()
|
||||
task.useBuildCache = ext.useBuildCache
|
||||
@@ -83,6 +61,29 @@ internal open class KaptConfigAction<TASK : KaptTask>(
|
||||
}
|
||||
}
|
||||
|
||||
internal constructor(kotlinCompileTask: KotlinCompile, ext: KaptExtension) : this(kotlinCompileTask.project, ext) {
|
||||
configureTask { task ->
|
||||
task.classpath.from(kotlinCompileTask.libraries)
|
||||
task.compiledSources.from(
|
||||
kotlinCompileTask.destinationDirectory,
|
||||
Callable { kotlinCompileTask.javaOutputDir.takeIf { it.isPresent } })
|
||||
.disallowChanges()
|
||||
task.sourceSetName.value(kotlinCompileTask.sourceSetName).disallowChanges()
|
||||
|
||||
|
||||
val kaptSources = objectFactory.fileCollection()
|
||||
.from(kotlinCompileTask.javaSources, task.stubsDir)
|
||||
.asFileTree
|
||||
.matching { it.include("**/*.java") }
|
||||
.filter {
|
||||
it.exists() &&
|
||||
!isAncestor(task.destinationDir.get().asFile, it) &&
|
||||
!isAncestor(task.classesDir.get().asFile, it)
|
||||
}
|
||||
task.source.from(kaptSources).disallowChanges()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getKaptClasspathSnapshot(taskProvider: TaskProvider<TASK>): FileCollection? {
|
||||
return if (project.isIncrementalKapt()) {
|
||||
maybeRegisterTransform(project)
|
||||
@@ -173,12 +174,9 @@ private fun isAncestor(dir: File, file: File): Boolean {
|
||||
}
|
||||
}
|
||||
|
||||
internal class KaptWithoutKotlincConfigAction(kotlinCompileTask: KotlinCompile, ext: KaptExtension) :
|
||||
KaptConfigAction<KaptWithoutKotlincTask>(kotlinCompileTask, ext) {
|
||||
internal class KaptWithoutKotlincConfig : KaptConfig<KaptWithoutKotlincTask> {
|
||||
|
||||
init {
|
||||
initKaptWorkersConfiguration(project.topLevelExtension)
|
||||
|
||||
configureTask { task ->
|
||||
task.addJdkClassesToClasspath.set(
|
||||
project.providers.provider {
|
||||
@@ -194,7 +192,7 @@ internal class KaptWithoutKotlincConfigAction(kotlinCompileTask: KotlinCompile,
|
||||
}
|
||||
}
|
||||
|
||||
private fun initKaptWorkersConfiguration(kotlinExt: KotlinTopLevelExtension) {
|
||||
constructor(kotlinCompileTask: KotlinCompile, ext: KaptExtension) : super(kotlinCompileTask, ext) {
|
||||
project.configurations.findByName(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME)
|
||||
?: project.configurations.create(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).apply {
|
||||
dependencies.addAllLater(project.listProperty {
|
||||
@@ -203,16 +201,33 @@ internal class KaptWithoutKotlincConfigAction(kotlinCompileTask: KotlinCompile,
|
||||
project.dependencies.create(kaptDependency),
|
||||
project.kotlinDependency(
|
||||
"kotlin-stdlib",
|
||||
kotlinExt.coreLibrariesVersion
|
||||
project.topLevelExtension.coreLibrariesVersion
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
configureTask { task ->
|
||||
task.addJdkClassesToClasspath.set(
|
||||
project.providers.provider {
|
||||
project.plugins.none { it is AbstractKotlinAndroidPluginWrapper }
|
||||
}
|
||||
)
|
||||
task.kaptJars.from(project.configurations.getByName(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME))
|
||||
}
|
||||
}
|
||||
|
||||
constructor(project: Project, ext: KaptExtension) : super(project, ext) {
|
||||
configureTask { task ->
|
||||
val kotlinSourceDir = objectFactory.fileCollection().from(task.kotlinSourcesDestinationDir)
|
||||
val nonAndroidDslOptions = getNonAndroidDslApOptions(ext, project, kotlinSourceDir, null, null)
|
||||
task.kaptPluginOptions.add(nonAndroidDslOptions.toCompilerPluginOptions())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class KaptWithKotlincConfigAction(kotlinCompileTask: KotlinCompile, ext: KaptExtension) :
|
||||
KaptConfigAction<KaptWithKotlincTask>(kotlinCompileTask, ext) {
|
||||
internal class KaptWithKotlincConfig(kotlinCompileTask: KotlinCompile, ext: KaptExtension) :
|
||||
KaptConfig<KaptWithKotlincTask>(kotlinCompileTask, ext) {
|
||||
|
||||
init {
|
||||
configureTask { task ->
|
||||
@@ -227,6 +242,7 @@ internal class KaptWithKotlincConfigAction(kotlinCompileTask: KotlinCompile, ext
|
||||
task.kaptPluginOptions.add(incAptCacheOption)
|
||||
}
|
||||
|
||||
task.compilerClasspath.from(providers.provider { kotlinCompileTask.defaultCompilerClasspath })
|
||||
task.pluginClasspath.from(kotlinCompileTask.pluginClasspath)
|
||||
task.additionalPluginOptionsAsInputs.value(kotlinCompileTask.pluginOptions).disallowChanges()
|
||||
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
|
||||
|
||||
+31
-13
@@ -1,40 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.tasks.configuration
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isIncludeCompileClasspath
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptTask
|
||||
import org.jetbrains.kotlin.gradle.internal.KotlinJvmCompilerArgumentsContributor
|
||||
import org.jetbrains.kotlin.gradle.internal.buildKaptSubpluginOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal class KaptGenerateStubsConfig(compilation: KotlinCompilationData<*>, kotlinTaskProvider: TaskProvider<KotlinCompile>) :
|
||||
BaseKotlinCompileConfig<KaptGenerateStubsTask>(compilation) {
|
||||
internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStubsTask> {
|
||||
|
||||
private val kaptExtension: KaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
||||
|
||||
init {
|
||||
constructor(compilation: KotlinCompilationData<*>, kotlinTaskProvider: TaskProvider<KotlinCompile>) : super(compilation) {
|
||||
configureFromExtension(project.extensions.getByType(KaptExtension::class.java))
|
||||
configureTask { task ->
|
||||
val kotlinCompileTask = kotlinTaskProvider.get()
|
||||
task.useModuleDetection.value(kotlinCompileTask.useModuleDetection).disallowChanges()
|
||||
task.moduleName.value(kotlinCompileTask.moduleName).disallowChanges()
|
||||
task.libraries.from({ kotlinCompileTask.libraries })
|
||||
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
|
||||
task.pluginOptions.addAll(kotlinCompileTask.pluginOptions)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(project: Project, ext: KotlinTopLevelExtension, kaptExtension: KaptExtension) : super(project, ext) {
|
||||
configureFromExtension(kaptExtension)
|
||||
configureTask { task ->
|
||||
task.compileKotlinArgumentsContributor.set(
|
||||
providers.provider {
|
||||
KotlinJvmCompilerArgumentsContributor(KotlinJvmCompilerArgumentsProvider(task))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureFromExtension(kaptExtension: KaptExtension) {
|
||||
configureTask { task ->
|
||||
task.verbose.set(KaptTask.queryKaptVerboseProperty(project))
|
||||
task.pluginOptions.add(buildOptions(kaptExtension, task))
|
||||
|
||||
task.pluginOptions.add(buildOptions(task))
|
||||
|
||||
if (!isIncludeCompileClasspath()) {
|
||||
if (!isIncludeCompileClasspath(kaptExtension)) {
|
||||
task.onlyIf {
|
||||
!(it as KaptGenerateStubsTask).kaptClasspath.isEmpty
|
||||
}
|
||||
@@ -42,9 +60,9 @@ internal class KaptGenerateStubsConfig(compilation: KotlinCompilationData<*>, ko
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIncludeCompileClasspath() = kaptExtension.includeCompileClasspath ?: project.isIncludeCompileClasspath()
|
||||
private fun isIncludeCompileClasspath(kaptExtension: KaptExtension) = kaptExtension.includeCompileClasspath ?: project.isIncludeCompileClasspath()
|
||||
|
||||
private fun buildOptions(task: KaptGenerateStubsTask): Provider<CompilerPluginOptions> {
|
||||
private fun buildOptions(kaptExtension: KaptExtension, task: KaptGenerateStubsTask): Provider<CompilerPluginOptions> {
|
||||
val javacOptions = project.provider { kaptExtension.getJavacOptions() }
|
||||
return project.provider {
|
||||
val compilerPluginOptions = CompilerPluginOptions()
|
||||
@@ -56,7 +74,7 @@ internal class KaptGenerateStubsConfig(compilation: KotlinCompilationData<*>, ko
|
||||
generatedSourcesDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
generatedClassesDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
incrementalDataDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
includeCompileClasspath = isIncludeCompileClasspath(),
|
||||
includeCompileClasspath = isIncludeCompileClasspath(kaptExtension),
|
||||
kaptStubsDir = objectFactory.fileCollection().from(task.stubsDir.asFile)
|
||||
).forEach {
|
||||
compilerPluginOptions.addPluginArgument(KAPT_SUBPLUGIN_ID, it)
|
||||
|
||||
+42
-21
@@ -8,44 +8,29 @@ package org.jetbrains.kotlin.gradle.tasks.configuration
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile>
|
||||
|
||||
internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotlinCompileConfig<TASK> {
|
||||
|
||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||
constructor(compilation: KotlinCompilationData<*>) : super(compilation) {
|
||||
val javaTaskProvider = when (compilation) {
|
||||
is KotlinJvmCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinWithJavaCompilation<*> -> compilation.compileJavaTaskProvider
|
||||
else -> null
|
||||
}
|
||||
|
||||
init {
|
||||
configureTaskProvider { taskProvider ->
|
||||
val snapshotConfiguration = runAtConfigurationTime(taskProvider)
|
||||
|
||||
taskProvider.configure { task ->
|
||||
javaTaskProvider?.let {
|
||||
task.associatedJavaCompileTaskTargetCompatibility.value(javaTaskProvider.map { it.targetCompatibility })
|
||||
task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source })
|
||||
task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
|
||||
}
|
||||
task.moduleName.value(providers.provider {
|
||||
(compilation.kotlinOptions as? KotlinJvmOptions)?.moduleName ?: task.parentKotlinOptionsImpl.orNull?.moduleName
|
||||
?: compilation.moduleName
|
||||
})
|
||||
|
||||
task.incremental = propertiesProvider.incrementalJvm ?: true
|
||||
|
||||
if (propertiesProvider.useFir == true) {
|
||||
@@ -71,6 +56,34 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||
constructor(compilation: KotlinCompilationData<*>) : super(compilation) {
|
||||
val javaTaskProvider = when (compilation) {
|
||||
is KotlinJvmCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinWithJavaCompilation<*> -> compilation.compileJavaTaskProvider
|
||||
else -> null
|
||||
}
|
||||
|
||||
configureTaskProvider { taskProvider ->
|
||||
taskProvider.configure { task ->
|
||||
javaTaskProvider?.let {
|
||||
task.associatedJavaCompileTaskTargetCompatibility.value(javaTaskProvider.map { it.targetCompatibility })
|
||||
task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source })
|
||||
task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
|
||||
}
|
||||
task.moduleName.value(providers.provider {
|
||||
(compilation.kotlinOptions as? KotlinJvmOptions)?.moduleName ?: task.parentKotlinOptions.orNull?.moduleName
|
||||
?: compilation.moduleName
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(project: Project, ext: KotlinTopLevelExtension) : super(
|
||||
project, ext, languageSettings = getDefaultLangSetting(project, ext)
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val TRANSFORMS_REGISTERED = "_kgp_internal_kotlin_compile_transforms_registered"
|
||||
|
||||
@@ -78,6 +91,14 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
|
||||
private const val DIRECTORY_ARTIFACT_TYPE = "directory"
|
||||
private const val JAR_ARTIFACT_TYPE = "jar"
|
||||
const val CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE = "classpath-entry-snapshot"
|
||||
|
||||
private fun getDefaultLangSetting(project: Project, ext: KotlinTopLevelExtension): Provider<LanguageSettings> {
|
||||
return project.provider {
|
||||
DefaultLanguageSettingsBuilder().also {
|
||||
it.freeCompilerArgsProvider = project.provider { listOfNotNull(ext.explicitApi?.toCompilerArg()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerTransformsOnce(project: Project) {
|
||||
@@ -110,7 +131,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
|
||||
return if (propertiesProvider.useClasspathSnapshot) {
|
||||
registerTransformsOnce(project)
|
||||
project.configurations.detachedConfiguration(
|
||||
project.dependencies.create(objectFactory.fileCollection().from(taskProvider.get().libraries))
|
||||
project.dependencies.create(objectFactory.fileCollection().from(project.provider { taskProvider.get().libraries }))
|
||||
)
|
||||
} else null
|
||||
}
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask
|
||||
import org.jetbrains.kotlin.gradle.mpp.buildProject
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinBaseApiPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJvmFactory
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kapt
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class KaptApiTest {
|
||||
|
||||
@get:Rule
|
||||
val tmpDir = TemporaryFolder()
|
||||
|
||||
private lateinit var project: ProjectInternal
|
||||
private lateinit var plugin: KotlinJvmFactory
|
||||
|
||||
companion object {
|
||||
private const val TASK_NAME = "kapt"
|
||||
private const val GENERATE_STUBS = "kaptGenerateStubs"
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUpProject() {
|
||||
project = buildProject {}
|
||||
plugin = project.plugins.apply(KotlinBaseApiPlugin::class.java)
|
||||
project.configurations.create(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTaskName() {
|
||||
val task = configureKapt {}
|
||||
assertEquals(TASK_NAME, task.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSources() {
|
||||
val sourcePath = tmpDir.newFolder().resolve("foo.kt").also {
|
||||
it.createNewFile()
|
||||
}
|
||||
val task = configureKapt {
|
||||
source.from(sourcePath)
|
||||
}
|
||||
assertEquals(setOf(sourcePath), task.source.files)
|
||||
|
||||
val sourcesDir = tmpDir.newFolder().also {
|
||||
it.resolve("a.kt").createNewFile()
|
||||
it.resolve("b.kt").createNewFile()
|
||||
}
|
||||
task.source.from(sourcesDir)
|
||||
assertEquals(setOf(sourcePath, sourcesDir), task.source.files)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKaptClasspath() {
|
||||
val kaptClasspath = tmpDir.newFolder()
|
||||
val externalClasspath = tmpDir.newFolder()
|
||||
val configurationNames = listOf("a", "b", "c")
|
||||
val task = configureKapt {
|
||||
this.kaptClasspath.from(kaptClasspath)
|
||||
kaptExternalClasspath.from(externalClasspath)
|
||||
kaptClasspathConfigurationNames.set(configurationNames)
|
||||
}
|
||||
|
||||
assertEquals(setOf(kaptClasspath), task.kaptClasspath.files)
|
||||
assertEquals(setOf(externalClasspath), task.kaptExternalClasspath.files)
|
||||
assertEquals(configurationNames, task.kaptClasspathConfigurationNames.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKaptOutputs() {
|
||||
val incAptCache = tmpDir.newFolder()
|
||||
val classesDir = tmpDir.newFolder()
|
||||
val destinationDir = tmpDir.newFolder()
|
||||
val generatedKotlinSources = tmpDir.newFolder()
|
||||
|
||||
val task = configureKapt {
|
||||
this.incAptCache.fileValue(incAptCache)
|
||||
this.classesDir.fileValue(classesDir)
|
||||
this.destinationDir.fileValue(destinationDir)
|
||||
kotlinSourcesDestinationDir.fileValue(generatedKotlinSources)
|
||||
}
|
||||
|
||||
assertEquals(incAptCache, task.incAptCache.get().asFile)
|
||||
assertEquals(classesDir, task.classesDir.get().asFile)
|
||||
assertEquals(destinationDir, task.destinationDir.get().asFile)
|
||||
assertEquals(generatedKotlinSources, task.kotlinSourcesDestinationDir.get().asFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testClasspath() {
|
||||
val compiledSources = tmpDir.newFolder()
|
||||
val classpath = tmpDir.newFolder()
|
||||
val includeCompileClasspath = false
|
||||
|
||||
val task = configureKapt {
|
||||
this.compiledSources.from(compiledSources)
|
||||
this.classpath.from(classpath)
|
||||
this.includeCompileClasspath.set(includeCompileClasspath)
|
||||
}
|
||||
|
||||
assertEquals(setOf(compiledSources), task.compiledSources.files)
|
||||
assertEquals(setOf(classpath), task.classpath.files)
|
||||
assertEquals(includeCompileClasspath, task.includeCompileClasspath.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOptions() {
|
||||
val sourceCompatibility = "11"
|
||||
val addJdkClassesToMissingClasspathSnapshot = true
|
||||
|
||||
val task = configureKapt {
|
||||
defaultJavaSourceCompatibility.set(sourceCompatibility)
|
||||
addJdkClassesToClasspath.set(addJdkClassesToMissingClasspathSnapshot)
|
||||
}
|
||||
|
||||
assertEquals(sourceCompatibility, task.defaultJavaSourceCompatibility.get())
|
||||
assertEquals(addJdkClassesToMissingClasspathSnapshot, task.addJdkClassesToClasspath.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKaptExtension() {
|
||||
plugin.kaptExtension.useBuildCache = false
|
||||
plugin.kaptExtension.includeCompileClasspath = true
|
||||
|
||||
val task = configureKapt {}
|
||||
assertEquals(false, task.useBuildCache)
|
||||
assertEquals(true, task.includeCompileClasspath.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateStubs() {
|
||||
val task = plugin.registerKaptGenerateStubsTask(GENERATE_STUBS).get()
|
||||
assertEquals(GENERATE_STUBS, task.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateStubsOptions() {
|
||||
val stubsDir = tmpDir.newFolder()
|
||||
val kaptClasspath = setOf(tmpDir.newFolder())
|
||||
val task = plugin.registerKaptGenerateStubsTask(GENERATE_STUBS).let { provider ->
|
||||
provider.configure {
|
||||
it.stubsDir.fileValue(stubsDir)
|
||||
it.kaptClasspath.from(kaptClasspath)
|
||||
}
|
||||
provider.get()
|
||||
}
|
||||
assertEquals(stubsDir, task.stubsDir.get().asFile)
|
||||
assertEquals(kaptClasspath, task.kaptClasspath.files)
|
||||
}
|
||||
|
||||
private fun configureKapt(configAction: Kapt.() -> Unit): KaptWithoutKotlincTask {
|
||||
val provider = plugin.registerKaptTask(TASK_NAME)
|
||||
provider.configure(configAction)
|
||||
return provider.get() as KaptWithoutKotlincTask
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.gradle.mpp.buildProject
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinBaseApiPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJvmFactory
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class KotlinCompileApiTest {
|
||||
|
||||
@get:Rule
|
||||
val tmpDir = TemporaryFolder()
|
||||
|
||||
private lateinit var project: ProjectInternal
|
||||
private lateinit var plugin: KotlinJvmFactory
|
||||
private lateinit var taskApi: KotlinJvmCompile
|
||||
private lateinit var taskImpl: KotlinCompile
|
||||
|
||||
companion object {
|
||||
private const val TASK_NAME = "kotlinCompile"
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUpProject() {
|
||||
project = buildProject {}
|
||||
plugin = project.plugins.apply(KotlinBaseApiPlugin::class.java)
|
||||
plugin.registerKotlinJvmCompileTask(TASK_NAME).configure { task ->
|
||||
taskApi = task
|
||||
}
|
||||
taskImpl = project.tasks.getByName(TASK_NAME) as KotlinCompile
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTaskName() {
|
||||
assertEquals(TASK_NAME, taskImpl.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSources() {
|
||||
val sourcePath = tmpDir.newFolder().resolve("foo.kt").also {
|
||||
it.createNewFile()
|
||||
}
|
||||
taskApi.setSource(sourcePath)
|
||||
assertEquals(setOf(sourcePath), taskImpl.sources.files)
|
||||
|
||||
val sourcesDir = tmpDir.newFolder().also {
|
||||
it.resolve("a.kt").createNewFile()
|
||||
it.resolve("b.kt").createNewFile()
|
||||
}
|
||||
taskApi.setSource(sourcePath, sourcesDir)
|
||||
assertEquals(
|
||||
setOf(sourcePath, sourcesDir.resolve("a.kt"), sourcesDir.resolve("b.kt")),
|
||||
taskImpl.sources.files
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFriendPaths() {
|
||||
val friendPath = tmpDir.newFolder()
|
||||
taskApi.friendPaths.from(friendPath)
|
||||
assertEquals(setOf(friendPath), taskImpl.friendPaths.files)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLibraries() {
|
||||
val classpathEntries = setOf(tmpDir.newFolder(), tmpDir.newFolder())
|
||||
taskApi.libraries.from(classpathEntries)
|
||||
assertEquals(classpathEntries, taskImpl.libraries.files)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPluginClasspath() {
|
||||
val pluginDependency = tmpDir.newFile()
|
||||
plugin.addCompilerPluginDependency(project.provider { project.files(pluginDependency) })
|
||||
|
||||
val anotherCompilerPlugin = tmpDir.newFile()
|
||||
taskApi.pluginClasspath.from(plugin.getCompilerPlugins(), anotherCompilerPlugin)
|
||||
assertEquals(setOf(pluginDependency, anotherCompilerPlugin), taskImpl.pluginClasspath.files)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testModuleName() {
|
||||
taskApi.moduleName.set("foo")
|
||||
assertEquals("foo", taskImpl.moduleName.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSourceSetName() {
|
||||
taskApi.sourceSetName.set("sourceSetFoo")
|
||||
assertEquals("sourceSetFoo", taskImpl.sourceSetName.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTaskBuildDirectory() {
|
||||
val taskBuildDir = tmpDir.newFolder()
|
||||
taskApi.destinationDirectory.fileValue(taskBuildDir)
|
||||
assertEquals(taskBuildDir, taskImpl.destinationDirectory.get().asFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDestinationDirectory() {
|
||||
val destinationDir = tmpDir.newFolder()
|
||||
taskApi.destinationDirectory.fileValue(destinationDir)
|
||||
assertEquals(destinationDir, taskImpl.destinationDirectory.get().asFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultiplatform() {
|
||||
taskApi.multiPlatformEnabled.set(true)
|
||||
assertEquals(true, taskImpl.multiPlatformEnabled.get())
|
||||
|
||||
taskApi.multiPlatformEnabled.set(false)
|
||||
assertEquals(false, taskImpl.multiPlatformEnabled.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testModuleDetection() {
|
||||
taskApi.useModuleDetection.set(true)
|
||||
assertEquals(true, taskImpl.useModuleDetection.get())
|
||||
|
||||
taskApi.useModuleDetection.set(false)
|
||||
assertEquals(false, taskImpl.useModuleDetection.get())
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testParentKotlinOptions() {
|
||||
val parentOptions = plugin.createKotlinJvmOptions()
|
||||
parentOptions.moduleName = "foo"
|
||||
parentOptions.javaParameters = true
|
||||
parentOptions.languageVersion = "lang_version"
|
||||
taskApi.parentKotlinOptions.set(parentOptions)
|
||||
|
||||
taskImpl.parentKotlinOptions.get().let {
|
||||
assertEquals(parentOptions.moduleName, it.moduleName)
|
||||
assertEquals(parentOptions.javaParameters, it.javaParameters)
|
||||
assertEquals(parentOptions.languageVersion, it.languageVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTopLevelExtension() {
|
||||
plugin.kotlinExtension.explicitApi = ExplicitApiMode.Strict
|
||||
project.evaluate()
|
||||
assertTrue(ExplicitApiMode.Strict.toCompilerArg() in taskImpl.kotlinOptions.freeCompilerArgs)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user