KT-64719 K2 KAPT stub generation should fail on syntax errors

This commit is contained in:
strangepleasures
2024-01-05 15:58:41 +00:00
committed by Space Team
parent bace053ea9
commit 894df8f641
4 changed files with 61 additions and 18 deletions
@@ -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")
}
}
}
}
@@ -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" }
@@ -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<PsiFile>,
options: KaptOptions,
onError: (messages: String) -> Unit,
logger: KaptLogger,
overriddenMetadataVersion: BinaryVersion? = null,
metadataRenderer: (Printer.(Metadata) -> Unit)? = null
): Map<KtLightClass, KaptStub?> =
analyze(module) {
StubGenerator(files.filterIsInstance<KtFile>(), options, onError, metadataRenderer, overriddenMetadataVersion).generateStubs()
): Map<KtLightClass, KaptStub?> {
for (file in files) {
file.findDescendantOfType<PsiErrorElement>()?.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<KtFile>(), 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<KtFile>,
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<KtLightClass, KaptStub?> =
@@ -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<ResultingArtifact.Source, Kapt4ContextBinaryArtifact>() {
@@ -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(