Skip to content

Commit 5a19640

Browse files
committed
fix behavior for KSP error case with compilation.
respect returnOkOnError when withCompilation is set true.
1 parent 4f5f880 commit 5a19640

File tree

12 files changed

+201
-1
lines changed

12 files changed

+201
-1
lines changed

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/KotlinSymbolProcessingExtension.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ abstract class AbstractKotlinSymbolProcessingExtension(
129129
if (finished) {
130130
if (!options.withCompilation)
131131
throw IllegalStateException("KSP is re-entered unexpectedly.")
132+
if (!options.returnOkOnError && logger.hasError()) {
133+
return AnalysisResult.compilationError(BindingContext.EMPTY)
134+
}
132135
return null
133136
}
134137

gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
158158
options += SubpluginOption("projectBaseDir", project.project.projectDir.canonicalPath)
159159
options += SubpluginOption("allWarningsAsErrors", allWarningsAsErrors.toString())
160160
options += FilesSubpluginOption("apclasspath", classpath.toList())
161-
// Turn this on by default to work KT-30172 around. It is off by default in the ccompiler plugin.
161+
// Turn this on by default to work KT-30172 around. It is off by default in the compiler plugin.
162162
options += SubpluginOption(
163163
"returnOkOnError",
164164
project.findProperty("ksp.return.ok.on.error")?.toString() ?: "true"

integration-tests/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ plugins {
99
dependencies {
1010
testImplementation("junit:junit:$junitVersion")
1111
testImplementation(gradleTestKit())
12+
testImplementation("org.jetbrains.kotlin:kotlin-compiler:$kotlinBaseVersion")
1213
}
1314

1415
tasks.named<Test>("test") {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.google.devtools.ksp.test
2+
3+
import org.gradle.testkit.runner.GradleRunner
4+
import org.jetbrains.kotlin.cli.common.ExitCode
5+
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
6+
import org.junit.Assert
7+
import org.junit.Rule
8+
import org.junit.Test
9+
import java.io.ByteArrayOutputStream
10+
import java.io.File
11+
import java.io.PrintStream
12+
import java.net.URLClassLoader
13+
14+
data class CompileResult(val exitCode: ExitCode, val output: String)
15+
16+
class KSPCmdLineOptionsIT {
17+
@Rule
18+
@JvmField
19+
val project: TemporaryTestProject = TemporaryTestProject("cmd-options")
20+
21+
private fun runCmdCompiler(pluginOptions: List<String>): CompileResult {
22+
val gradleRunner = GradleRunner.create().withProjectDir(project.root)
23+
gradleRunner.withArguments("clean", ":processors:build").build()
24+
val processorJar = File(project.root, "processors/build/libs/processors-1.0-SNAPSHOT.jar")
25+
val classLoader = URLClassLoader(arrayOf(processorJar.toURI().toURL()), javaClass.classLoader)
26+
val compiler = classLoader.loadClass(K2JVMCompiler::class.java.name).newInstance() as K2JVMCompiler
27+
val repoPath = "../build/repos/test/com/google/devtools/ksp/"
28+
val kspPluginId = "com.google.devtools.ksp.symbol-processing"
29+
val kspPluginJar = File("$repoPath/symbol-processing-cmdline/2.0.255-SNAPSHOT").listFiles()!!.filter {
30+
it.name.matches(Regex(".*-\\d.jar"))
31+
}.maxByOrNull { it.lastModified() }!!
32+
val kspApiJar = File("$repoPath/symbol-processing-api/2.0.255-SNAPSHOT").listFiles()!!.filter {
33+
it.name.matches(Regex(".*-\\d.jar"))
34+
}.maxByOrNull { it.lastModified() }!!
35+
val compilerArgs = mutableListOf(
36+
"-no-stdlib",
37+
"-Xplugin=${kspPluginJar.absolutePath}",
38+
"-Xplugin=${kspApiJar.absolutePath}",
39+
"-P", "plugin:$kspPluginId:apclasspath=${processorJar.absolutePath}",
40+
"-P", "plugin:$kspPluginId:projectBaseDir=${project.root}/build",
41+
"-P", "plugin:$kspPluginId:classOutputDir=${project.root}/build",
42+
"-P", "plugin:$kspPluginId:javaOutputDir=${project.root}/build/out",
43+
"-P", "plugin:$kspPluginId:kotlinOutputDir=${project.root}/build/out",
44+
"-P", "plugin:$kspPluginId:resourceOutputDir=${project.root}/build/out",
45+
"-P", "plugin:$kspPluginId:kspOutputDir=${project.root}/build/out",
46+
"-P", "plugin:$kspPluginId:cachesDir=${project.root}/build/out",
47+
"-P", "plugin:$kspPluginId:incremental=false",
48+
"-d", "${project.root}/build/out"
49+
)
50+
pluginOptions.forEach {
51+
compilerArgs.add("-P")
52+
compilerArgs.add("plugin:$kspPluginId:$it")
53+
}
54+
compilerArgs.add(File(project.root, "workload/src/main/kotlin/com/example/A.kt").absolutePath)
55+
val outStream = ByteArrayOutputStream()
56+
val exitCode = compiler.exec(PrintStream(outStream), *compilerArgs.toTypedArray())
57+
return CompileResult(exitCode, outStream.toString())
58+
}
59+
60+
@Test
61+
fun testWithCompilationOnError() {
62+
val result = runCmdCompiler(listOf("apoption=error=true", "withCompilation=true"))
63+
val errors = result.output.lines().filter { it.startsWith("error: [ksp]") }
64+
val exitCode = result.exitCode
65+
Assert.assertTrue(exitCode == ExitCode.COMPILATION_ERROR)
66+
Assert.assertTrue(
67+
errors.any {
68+
it.startsWith("error: [ksp] java.lang.IllegalStateException: Error on request")
69+
}
70+
)
71+
}
72+
73+
@Test
74+
fun testWithCompilationOnErrorOk() {
75+
val result = runCmdCompiler(listOf("apoption=error=true", "returnOkOnError=true", "withCompilation=true"))
76+
val errors = result.output.lines().filter { it.startsWith("error: [ksp]") }
77+
val exitCode = result.exitCode
78+
Assert.assertTrue(exitCode == ExitCode.OK)
79+
Assert.assertTrue(
80+
errors.any {
81+
it.startsWith("error: [ksp] java.lang.IllegalStateException: Error on request")
82+
}
83+
)
84+
}
85+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
kotlin("jvm")
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/")
8+
}

integration-tests/src/test/resources/cmd-options/gradle.properties

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
val kspVersion: String by project
2+
val testRepo: String by project
3+
4+
plugins {
5+
kotlin("jvm")
6+
}
7+
8+
group = "com.example"
9+
version = "1.0-SNAPSHOT"
10+
11+
repositories {
12+
maven(testRepo)
13+
mavenCentral()
14+
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/")
15+
}
16+
17+
dependencies {
18+
implementation("com.google.devtools.ksp:symbol-processing-api:$kspVersion")
19+
}
20+
21+
sourceSets.main {
22+
java.srcDirs("src/main/kotlin")
23+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import com.google.devtools.ksp.processing.*
2+
import com.google.devtools.ksp.symbol.*
3+
4+
class TestProcessor : SymbolProcessor {
5+
lateinit var codeGenerator: CodeGenerator
6+
lateinit var logger: KSPLogger
7+
lateinit var options: Map<String, String>
8+
var rounds = 0
9+
10+
fun init(
11+
options: Map<String, String>,
12+
kotlinVersion: KotlinVersion,
13+
codeGenerator: CodeGenerator,
14+
logger: KSPLogger
15+
) {
16+
this.logger = logger
17+
this.options = options
18+
this.codeGenerator = codeGenerator
19+
}
20+
21+
override fun process(resolver: Resolver): List<KSAnnotated> {
22+
if (options.containsKey("error")) {
23+
throw IllegalStateException("Error on request")
24+
}
25+
return emptyList()
26+
}
27+
}
28+
29+
class TestProcessorProvider : SymbolProcessorProvider {
30+
override fun create(
31+
env: SymbolProcessorEnvironment
32+
): SymbolProcessor {
33+
return TestProcessor().apply {
34+
init(env.options, env.kotlinVersion, env.codeGenerator, env.logger)
35+
}
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TestProcessorProvider
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pluginManagement {
2+
val kspVersion: String by settings
3+
val kotlinVersion: String by settings
4+
val testRepo: String by settings
5+
plugins {
6+
id("com.google.devtools.ksp") version kspVersion
7+
kotlin("jvm") version kotlinVersion
8+
}
9+
repositories {
10+
maven(testRepo)
11+
gradlePluginPortal()
12+
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/")
13+
}
14+
}
15+
16+
rootProject.name = "cmd-options"
17+
18+
include(":workload")
19+
include(":processors")

0 commit comments

Comments
 (0)