KT-57598 Run Kapt with K1 even when the compiler is run with K2

This commit is contained in:
Pavel Mikhailovskii
2023-04-20 09:30:38 +00:00
committed by Space Team
parent cb4c41a5ca
commit 58143a2006
8 changed files with 224 additions and 1 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.cli.common
import com.intellij.ide.highlighter.JavaFileType
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.ManualLanguageFeatureSetting
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -23,6 +24,8 @@ fun <A : CommonCompilerArguments> CompilerConfiguration.setupCommonArguments(
arguments: A,
createMetadataVersion: ((IntArray) -> BinaryVersion)? = null
) {
val messageCollector = getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
put(CommonConfigurationKeys.DISABLE_INLINE, arguments.noInline)
put(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS, arguments.useFirExtendedCheckers)
put(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER, arguments.expectActualLinker)
@@ -35,7 +38,6 @@ fun <A : CommonCompilerArguments> CompilerConfiguration.setupCommonArguments(
val metadataVersionString = arguments.metadataVersion
if (metadataVersionString != null) {
val versionArray = BinaryVersion.parseVersionArray(metadataVersionString)
val messageCollector = getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
when {
versionArray == null -> messageCollector.report(
CompilerMessageSeverity.ERROR, "Invalid metadata version: $metadataVersionString", null
@@ -45,6 +47,7 @@ fun <A : CommonCompilerArguments> CompilerConfiguration.setupCommonArguments(
}
}
switchToFallbackModeIfNecessary(arguments, messageCollector)
setupLanguageVersionSettings(arguments)
val usesK2 = arguments.useK2 || languageVersionSettings.languageVersion.usesK2
@@ -53,6 +56,29 @@ fun <A : CommonCompilerArguments> CompilerConfiguration.setupCommonArguments(
buildHmppModuleStructure(arguments)?.let { put(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE, it) }
}
fun switchToFallbackModeIfNecessary(arguments: CommonCompilerArguments, messageCollector: MessageCollector) {
val isK2 = arguments.useK2 || (arguments.languageVersion?.startsWith('2') ?: (LanguageVersion.LATEST_STABLE >= LanguageVersion.KOTLIN_2_0))
if (isK2) {
val isKaptUsed = arguments.pluginOptions?.any { it.startsWith("plugin:org.jetbrains.kotlin.kapt3") } == true
if (isKaptUsed) {
if (!arguments.suppressVersionWarnings) {
messageCollector.report(
CompilerMessageSeverity.STRONG_WARNING,
"Kapt currently doesn't support language version 2.0+.\nFalling back to 1.9."
)
}
arguments.languageVersion = LanguageVersion.KOTLIN_1_9.versionString
if (arguments.apiVersion?.startsWith("2") == true) {
arguments.apiVersion = ApiVersion.KOTLIN_1_9.versionString
}
arguments.useK2 = false
arguments.skipMetadataVersionCheck = true
arguments.skipPrereleaseCheck = true
(arguments as? K2JVMCompilerArguments)?.allowUnstableDependencies = true
}
}
}
fun <A : CommonCompilerArguments> CompilerConfiguration.setupLanguageVersionSettings(arguments: A) {
languageVersionSettings = arguments.toLanguageVersionSettings(getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.gradle
import org.gradle.api.JavaVersion
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.tasks.USING_JVM_INCREMENTAL_COMPILATION_MESSAGE
@@ -1121,4 +1122,62 @@ open class Kapt3IT : Kapt3BaseIT() {
}
}
}
@DisplayName("Kapt runs in fallback mode with useK2 = true")
@GradleTest
internal fun fallBackModeWithUseK2(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 {
| useK2 = true
| }
|}
|
|compileKotlin.kotlinOptions.allWarningsAsErrors = false
""".trimMargin()
)
build("build") {
assertKaptSuccessful()
assertTasksExecuted(":kaptGenerateStubsKotlin", ":kaptKotlin", ":compileKotlin")
assertOutputContains("Falling back to 1.9.")
}
}
}
@DisplayName("Kapt runs in fallback mode with languageVersion = 2.0")
@GradleTest
internal fun fallBackModeWithLanguageVersion2_0(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("build") {
assertKaptSuccessful()
assertTasksExecuted(":kaptGenerateStubsKotlin", ":kaptKotlin", ":compileKotlin")
assertOutputContains("Falling back to 1.9.")
}
}
}
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.SystemInfo
import org.jetbrains.kotlin.cli.common.arguments.readArgumentsFromArgFile
import org.jetbrains.kotlin.test.services.JUnit5Assertions
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.TestInfo
import java.io.File
@@ -52,6 +53,13 @@ abstract class AbstractKaptToolIntegrationTest {
"kapt" -> runKotlinDistBinary("kapt", section.args)
"javac" -> runJavac(section.args)
"java" -> runJava(section.args)
"output" -> {
val output = File(tmpdir, "processOutput.txt").readText()
val expected = section.content.trim()
JUnit5Assertions.assertTrue(output.contains(expected)) {
"Output\"$output\" doesn't contain the expected string \"$expected\""
}
}
"after" -> {}
else -> error("Unknown section name ${section.name}")
}
@@ -0,0 +1,19 @@
package test
import apt.Anno
import generated.Test as TestGenerated
@Anno
class Test {
@field:Anno
val property: String = ""
@Anno
fun function() {
}
}
fun main() {
println("Generated class: " + TestGenerated::class.java.name)
}
@@ -0,0 +1,34 @@
package apt
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic.Kind.*
import javax.tools.StandardLocation
annotation class Anno
class SampleApt : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
val writeKotlinFiles = processingEnv.options["kapt.test.writeKotlinFiles"] == "true"
for (element in roundEnv.getElementsAnnotatedWith(Anno::class.java)) {
val generatedSimpleName = element.simpleName.toString().capitalize()
val file = when (writeKotlinFiles) {
true -> processingEnv.filer.createResource(StandardLocation.SOURCE_OUTPUT, "generated", "$generatedSimpleName.kt")
false -> processingEnv.filer.createSourceFile("generated.$generatedSimpleName")
}
file.openWriter().use {
it.write("package generated;\npublic class $generatedSimpleName {}")
}
}
return true
}
override fun getSupportedOptions() = setOf("kapt.test.writeKotlinFiles")
override fun getSupportedSourceVersion() = SourceVersion.RELEASE_8
override fun getSupportedAnnotationTypes() = setOf("apt.Anno")
}
@@ -0,0 +1,70 @@
# mkdir
output/stubs
output/classes
output/javaClasses
output/sources
output/stubsAlt
output/classesAlt
output/javaClassesAlt
output/sourcesAlt
# kotlinc
-language-version 2.0
-cp %KOTLIN_STDLIB%
-d output/ap.jar
ap/Processor.kt
# copy
ap/META-INF/services/javax.annotation.processing.Processor
output/ap/META-INF/services/javax.annotation.processing.Processor
# kapt
-Xuse-k2
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-d output/classes
-cp output/ap.jar:%KOTLIN_STDLIB%
Test.kt
# javac
-cp output/ap.jar
-d output/javaClasses
-proc:none
output/sources/generated/Function.java
output/sources/generated/Property.java
output/sources/generated/Test.java
# kapt
-language-version 2.0
-Kapt-stubs=output/stubsAlt
-Kapt-classes=output/classesAlt
-Kapt-sources=output/sourcesAlt
-Kapt-classpath=output/ap
-d output/classesAlt
-cp output/ap.jar:%KOTLIN_STDLIB%
Test.kt
# output
warning: kapt currently doesn't support language version 2.0+.
Falling back to 1.9.
# java
-cp output/classes:output/javaClasses:output/ap.jar:%KOTLIN_STDLIB%
test.TestKt
# javac
-cp output/ap.jar
-d output/javaClassesAlt
-proc:none
output/sourcesAlt/generated/Function.java
output/sourcesAlt/generated/Property.java
output/sourcesAlt/generated/Test.java
# java
-cp output/classes:output/javaClassesAlt:output/ap.jar:%KOTLIN_STDLIB%
test.TestKt
# after
Generated class: generated.Test
@@ -48,6 +48,12 @@ public class KaptToolIntegrationTestGenerated extends AbstractKaptToolIntegratio
runTest("plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/");
}
@Test
@TestMetadata("fallback")
public void testFallback() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/fallback/");
}
@Test
@TestMetadata("kotlinFileGeneration")
public void testKotlinFileGeneration() throws Exception {