From 894df8f6414fe8461a130634bcb3c7e300ef3c85 Mon Sep 17 00:00:00 2001 From: strangepleasures Date: Fri, 5 Jan 2024 15:58:41 +0000 Subject: [PATCH] KT-64719 K2 KAPT stub generation should fail on syntax errors --- .../org/jetbrains/kotlin/gradle/Kapt3IT.kt | 13 +++++++ .../kapt4/Kapt4AnalysisHandlerExtension.kt | 9 +---- .../jetbrains/kotlin/kapt4/StubGenerator.kt | 23 +++++++++---- .../org/jetbrains/kotlin/kapt4/Kapt4Facade.kt | 34 ++++++++++++++++--- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt index 72777e555d8..f44abb3d075 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt @@ -37,6 +37,7 @@ import java.util.zip.ZipOutputStream import kotlin.io.path.appendText import kotlin.io.path.deleteExisting import kotlin.io.path.outputStream +import kotlin.io.path.writeText import kotlin.test.assertEquals abstract class Kapt3BaseIT : KGPBaseTest() { @@ -1448,4 +1449,16 @@ open class Kapt3IT : Kapt3BaseIT() { } } } + + @DisplayName("KT-64719 KAPT stub generation should fail on files with syntax errors") + @GradleTest + fun testTopLevelSyntaxError(gradleVersion: GradleVersion) { + project("simple".withPrefix, gradleVersion) { + javaSourcesDir().resolve("invalid.kt").writeText("fun foo() { !!! }") + + buildAndFail(":kaptGenerateStubsKotlin") { + assertOutputContains("invalid.kt:1:16 Expecting an element") + } + } + } } diff --git a/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/Kapt4AnalysisHandlerExtension.kt b/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/Kapt4AnalysisHandlerExtension.kt index db563db601d..25999924c64 100644 --- a/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/Kapt4AnalysisHandlerExtension.kt +++ b/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/Kapt4AnalysisHandlerExtension.kt @@ -133,15 +133,8 @@ private class Kapt4AnalysisHandlerExtension : FirAnalysisHandlerExtension() { reportOutputFiles: Boolean, overriddenMetadataVersion: BinaryVersion? ) { - fun onError(message: String) { - if(options[KaptFlag.STRICT]) { - logger.error(message) - } else { - logger.warn(message) - } - } val (stubGenerationTime, classesToStubs) = measureTimeMillis { - generateStubs(module, files, options, ::onError, overriddenMetadataVersion) + generateStubs(module, files, options, logger, overriddenMetadataVersion) } logger.info { "Java stub generation took $stubGenerationTime ms" } diff --git a/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/StubGenerator.kt b/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/StubGenerator.kt index e09e5227c00..81359ff91f4 100644 --- a/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/StubGenerator.kt +++ b/plugins/kapt4/src/org/jetbrains/kotlin/kapt4/StubGenerator.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.asJava.findFacadeClass import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils.offsetToLineAndColumn import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.kapt3.base.KaptFlag @@ -43,9 +44,10 @@ import org.jetbrains.kotlin.psi.psiUtil.parameterIndex import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny import org.jetbrains.kotlin.utils.toMetadataVersion import org.jetbrains.kotlin.kapt3.base.KaptOptions -import org.jetbrains.kotlin.kapt3.base.javac.kaptError +import org.jetbrains.kotlin.kapt3.base.util.KaptLogger import org.jetbrains.kotlin.kapt3.stubs.MembersPositionComparator import org.jetbrains.kotlin.psi.psiUtil.children +import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.utils.Printer import java.io.File @@ -53,13 +55,21 @@ internal fun generateStubs( module: KtSourceModule, files: List, options: KaptOptions, - onError: (messages: String) -> Unit, + logger: KaptLogger, overriddenMetadataVersion: BinaryVersion? = null, metadataRenderer: (Printer.(Metadata) -> Unit)? = null -): Map = - analyze(module) { - StubGenerator(files.filterIsInstance(), options, onError, metadataRenderer, overriddenMetadataVersion).generateStubs() +): Map { + for (file in files) { + file.findDescendantOfType()?.let { + val pos = offsetToLineAndColumn(it.containingFile.viewProvider.document, it.textRange.startOffset) + logger.error("${file.virtualFile.path}:${pos.line}:${pos.column} ${it.errorDescription}") + return emptyMap() + } } + return analyze(module) { + StubGenerator(files.filterIsInstance(), options, logger, metadataRenderer, overriddenMetadataVersion).generateStubs() + } +} class KaptStub(val source: String, val kaptMetadata: ByteArray) { fun writeMetadata(forSource: File) { @@ -72,7 +82,7 @@ context(KtAnalysisSession) private class StubGenerator( private val files: List, options: KaptOptions, - private val onError: (String) -> Unit, + private val logger: KaptLogger, private val metadataRenderer: (Printer.(Metadata) -> Unit)? = null, private val overriddenMetadataVersion: BinaryVersion? = null, ) { @@ -80,6 +90,7 @@ private class StubGenerator( private val stripMetadata = options[KaptFlag.STRIP_METADATA] private val keepKdocComments = options[KaptFlag.KEEP_KDOC_COMMENTS_IN_STUBS] private val dumpDefaultParameterValues = options[KaptFlag.DUMP_DEFAULT_PARAMETER_VALUES] + private val onError = if (options[KaptFlag.STRICT]) logger::error else logger::warn fun generateStubs(): Map = diff --git a/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4Facade.kt b/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4Facade.kt index a5c5b19a31f..de0473077fc 100644 --- a/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4Facade.kt +++ b/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4Facade.kt @@ -16,9 +16,9 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoots import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.kapt3.base.KaptContext -import org.jetbrains.kotlin.kapt3.base.KaptFlag import org.jetbrains.kotlin.kapt3.base.KaptOptions import org.jetbrains.kotlin.kapt3.base.javac.reportKaptError +import org.jetbrains.kotlin.kapt3.base.util.KaptLogger import org.jetbrains.kotlin.kapt3.base.util.WriterBackedKaptLogger import org.jetbrains.kotlin.kapt3.test.KaptMessageCollectorProvider import org.jetbrains.kotlin.kapt3.test.kaptOptionsProvider @@ -27,7 +27,9 @@ import org.jetbrains.kotlin.kotlinp.KotlinpSettings import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.utils.Printer +import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import java.io.File +import java.io.PrintWriter internal class Kapt4Facade(private val testServices: TestServices) : AbstractTestFacade() { @@ -82,10 +84,34 @@ private fun run( withJdk = false, WriterBackedKaptLogger(isVerbose = false), ) - val onError = { message: String -> - context.reportKaptError(*message.split("\n").toTypedArray()) + + val logger = object : KaptLogger { + override val errorWriter: PrintWriter + get() = shouldNotBeCalled() + override val infoWriter: PrintWriter + get() = shouldNotBeCalled() + override val isVerbose: Boolean + get() = shouldNotBeCalled() + override val warnWriter: PrintWriter + get() = shouldNotBeCalled() + + override fun error(message: String) { + context.reportKaptError(*message.split("\n").toTypedArray()) + } + + override fun exception(e: Throwable) { + error(e.toString()) + } + + override fun info(message: String) { + } + + override fun warn(message: String) { + error(message) + } } - return context to generateStubs(module, files, options, onError, metadataRenderer = { renderMetadata(it) }) + + return context to generateStubs(module, files, options, logger, metadataRenderer = { renderMetadata(it) }) } internal data class Kapt4ContextBinaryArtifact(