K2 kapt: add kapt.use.k2 Gradle property

... and `-Kapt-use-k2` CLI flag to enable K2 kapt.

 #KT-61114 Fixed
This commit is contained in:
Alexander Udalov
2023-08-17 17:25:24 +02:00
committed by Space Team
parent 059046a2b1
commit 761221904c
12 changed files with 98 additions and 8 deletions
@@ -121,6 +121,10 @@ open class Kapt3ClassLoadersCacheIT : Kapt3IT() {
override fun testMultipleProcessingPasses(gradleVersion: GradleVersion) {
}
@Disabled("classloaders cache is leaking file descriptors that prevents cleaning test project")
override fun useK2KaptProperty(gradleVersion: GradleVersion) {
}
override fun testAnnotationProcessorAsFqName(gradleVersion: GradleVersion) {
project("annotationProcessorAsFqName".withPrefix, gradleVersion) {
//classloaders caching is not compatible with includeCompileClasspath
@@ -1268,6 +1272,41 @@ open class Kapt3IT : Kapt3BaseIT() {
}
}
@DisplayName("K2 Kapt can be enabled via Gradle property kapt.use.k2")
@GradleTest
open fun useK2KaptProperty(gradleVersion: GradleVersion) {
project("simple".withPrefix, gradleVersion) {
buildGradle.appendText(
"""
|tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
| compilerOptions {
| freeCompilerArgs.addAll([
| "-Xuse-fir-ic",
| "-Xuse-fir-lt"
| ])
| }
| kotlinOptions {
| languageVersion = "2.0"
| }
|}
|
|compileKotlin.kotlinOptions.allWarningsAsErrors = false
""".trimMargin()
)
build("-Pkapt.use.k2=true", "build") {
assertKaptSuccessful()
assertTasksExecuted(":kaptGenerateStubsKotlin", ":kaptKotlin", ":compileKotlin")
assertOutputDoesNotContain("Falling back to 1.9.")
assertOutputContains("Kapt 4 is an experimental feature. Use with caution.")
}
build("-Pkapt.use.k2=true", "cleanCompileKotlin", "compileKotlin") {
assertTasksExecuted(":compileKotlin")
// The warning should not be displayed for the compile task.
assertOutputDoesNotContain("Kapt 4 is an experimental feature. Use with caution.")
}
}
}
@DisplayName("Kapt-generated Kotlin sources can be used in Kotlin")
@GradleTest
open fun useGeneratedKotlinSource(gradleVersion: GradleVersion) {
@@ -36,6 +36,9 @@ class Kapt4IT : Kapt3IT() {
@Disabled("Doesn't make sense in Kapt 4")
override fun fallBackModeWithLanguageVersion2_0(gradleVersion: GradleVersion) {}
@Disabled("Doesn't make sense in Kapt 4")
override fun useK2KaptProperty(gradleVersion: GradleVersion) {}
@Disabled("Doesn't make sense in Kapt 4")
override fun testRepeatableAnnotationsWithOldJvmBackend(gradleVersion: GradleVersion) {}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isInf
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isKaptKeepKdocCommentsInStubs
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isKaptVerbose
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isUseJvmIr
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isUseK2
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
@@ -109,6 +110,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
return getBooleanOptionValue(BooleanOption.KAPT_USE_JVM_IR)
}
fun Project.isUseK2(): Boolean {
return getBooleanOptionValue(BooleanOption.KAPT_USE_K2)
}
fun Project.classLoadersCacheSize(): Int = findPropertySafe(CLASSLOADERS_CACHE_SIZE)?.toString()?.toInt() ?: 0
fun Project.disableClassloaderCacheForProcessors(): Set<String> {
@@ -203,6 +208,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
KAPT_INCLUDE_COMPILE_CLASSPATH("kapt.include.compile.classpath", true),
KAPT_KEEP_KDOC_COMMENTS_IN_STUBS("kapt.keep.kdoc.comments.in.stubs", true),
KAPT_USE_JVM_IR("kapt.use.jvm.ir", true),
KAPT_USE_K2("kapt.use.k2", false),
}
}
@@ -546,6 +552,7 @@ internal fun buildKaptSubpluginOptions(
pluginOptions += SubpluginOption("showProcessorTimings", "${kaptExtension.showProcessorStats}")
pluginOptions += SubpluginOption("detectMemoryLeaks", kaptExtension.detectMemoryLeaks)
pluginOptions += SubpluginOption("useJvmIr", "${project.isUseJvmIr()}")
pluginOptions += SubpluginOption("useK2", "${project.isUseK2()}")
pluginOptions += SubpluginOption("infoAsWarnings", "${project.isInfoAsWarnings()}")
pluginOptions += FilesSubpluginOption("stubs", kaptStubsDir)
@@ -17,9 +17,10 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.Project
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.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.work.Incremental
@@ -65,6 +66,9 @@ abstract class KaptGenerateStubsTask @Inject constructor(
@get:Input
abstract val verbose: Property<Boolean>
@get:Input
abstract val useK2Kapt: Property<Boolean>
/**
* Changes in this additional sources will trigger stubs regeneration,
* but the sources themselves will not be used to find kapt annotations and generate stubs.
@@ -125,6 +129,10 @@ abstract class KaptGenerateStubsTask @Inject constructor(
args.verbose = verbose.get()
args.destinationAsFile = destinationDirectory.get().asFile
if (useK2Kapt.get()) {
args.freeArgs += "-Xuse-kapt4"
}
}
pluginClasspath { args ->
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
import org.jetbrains.kotlin.gradle.internal.*
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.Kapt3GradleSubplugin.Companion.isUseK2
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
@@ -49,6 +50,7 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStu
configureTask { task ->
task.verbose.set(KaptTask.queryKaptVerboseProperty(project))
task.pluginOptions.add(buildOptions(kaptExtension, task))
task.useK2Kapt.value(project.isUseK2()).finalizeValueOnRead()
if (!isIncludeCompileClasspath(kaptExtension)) {
task.onlyIf {