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 {
@@ -129,7 +129,8 @@ enum class KaptFlag(val description: String, val defaultValue: Boolean = false)
INCREMENTAL_APT("Incremental annotation processing (apt mode)"),
STRIP_METADATA("Strip @Metadata annotations from stubs"),
KEEP_KDOC_COMMENTS_IN_STUBS("Keep KDoc comments in stubs", defaultValue = true),
USE_JVM_IR("Use JVM IR backend", defaultValue = true)
USE_JVM_IR("Use JVM IR backend", defaultValue = true),
USE_K2("Use K2"),
;
}
+1
View File
@@ -107,6 +107,7 @@ private fun transformKaptToolArgs(args: List<String>, messageCollector: MessageC
}
KaptCliOption.APT_MODE_OPTION -> aptModePassed = true
KaptCliOption.VERBOSE_MODE_OPTION -> kaptVerboseModePassed = true
KaptCliOption.USE_K2 -> transformed.add("-Xuse-kapt4")
else -> {}
}
@@ -221,6 +221,13 @@ enum class KaptCliOption(
cliToolOption = CliToolOption("-Kapt-use-jvm-ir", FLAG)
),
USE_K2(
"useK2",
"true | false",
"Use K2",
cliToolOption = CliToolOption("-Kapt-use-k2", FLAG)
),
DETECT_MEMORY_LEAKS_OPTION("detectMemoryLeaks", "true | false", "Detect memory leaks in annotation processors"),
INCLUDE_COMPILE_CLASSPATH(
"includeCompileClasspath",
@@ -0,0 +1,11 @@
# kapt
-language-version 2.0
-Xsuppress-version-warnings
-Kapt-use-k2=true
-Kapt-mode=compile
../simple/Test.kt
# after
Return code: 1
error: [kapt] KAPT "compile" mode is not supported in Kotlin 2.x. Run kapt with -Kapt-mode=stubsAndApt and use kotlinc for the final compilation step.
@@ -48,6 +48,12 @@ public class Kapt4ToolIntegrationTestGenerated extends AbstractKapt4ToolIntegrat
runTest("plugins/kapt3/kapt3-cli/testData/integration-kapt4/defaultPackage/");
}
@Test
@TestMetadata("kaptUseK2Flag")
public void testKaptUseK2Flag() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration-kapt4/kaptUseK2Flag/");
}
@Test
@TestMetadata("kotlinFileGeneration")
public void testKotlinFileGeneration() throws Exception {
@@ -125,6 +125,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
STRIP_METADATA_OPTION -> setFlag(KaptFlag.STRIP_METADATA, value)
KEEP_KDOC_COMMENTS_IN_STUBS -> setFlag(KaptFlag.KEEP_KDOC_COMMENTS_IN_STUBS, value)
USE_JVM_IR -> setFlag(KaptFlag.USE_JVM_IR, value)
USE_K2 -> setFlag(KaptFlag.USE_K2, value)
SHOW_PROCESSOR_STATS -> setFlag(KaptFlag.SHOW_PROCESSOR_STATS, value)
DUMP_PROCESSOR_STATS -> processorsStatsReportFile = File(value)
@@ -171,11 +172,13 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
get() = false
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
if (configuration.getBoolean(USE_FIR)) return
val optionsBuilder = (configuration[KAPT_OPTIONS] ?: KaptOptions.Builder())
if (configuration.getBoolean(USE_FIR) || KaptFlag.USE_K2 in optionsBuilder.flags) return
doOpenInternalPackagesIfRequired()
val contentRoots = configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
val optionsBuilder = (configuration[KAPT_OPTIONS] ?: KaptOptions.Builder()).apply {
optionsBuilder.apply {
projectBaseDir = project.basePath?.let(::File)
compileClasspath.addAll(contentRoots.filterIsInstance<JvmClasspathRoot>().map { it.file })
javaSourceRoots.addAll(contentRoots.filterIsInstance<JavaSourceRoot>().map { it.file })
@@ -31,8 +31,10 @@ import org.jetbrains.kotlin.psi.KtFile
import java.io.File
private class Kapt4AnalysisHandlerExtension : FirAnalysisHandlerExtension() {
override fun isApplicable(configuration: CompilerConfiguration): Boolean =
configuration.getBoolean(USE_FIR) && configuration[KAPT_OPTIONS] != null
override fun isApplicable(configuration: CompilerConfiguration): Boolean {
val options = configuration[KAPT_OPTIONS]
return options != null && (configuration.getBoolean(USE_FIR) || KaptFlag.USE_K2 in options.flags)
}
@OptIn(KtAnalysisApiInternals::class)
override fun doAnalysis(configuration: CompilerConfiguration): Boolean {
@@ -187,4 +189,4 @@ class Kapt4CompilerPluginRegistrar : CompilerPluginRegistrar() {
FirAnalysisHandlerExtension.registerExtension(Kapt4AnalysisHandlerExtension())
}
}
}
}