KT-60821 [KAPT] Generate stubs without KaptTreeMaker

Merge-request: KT-MR-12979
Merged-by: Pavel Mikhailovskii <Pavel.Mikhailovskii@jetbrains.com>
This commit is contained in:
strangepleasures
2023-11-16 21:14:36 +00:00
committed by Space Team
parent 0fba58eee7
commit 9c2ce475e2
21 changed files with 1035 additions and 1644 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.kapt4
import com.intellij.mock.MockProject
import com.intellij.openapi.Disposable
import kotlinx.metadata.jvm.KotlinClassMetadata
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.lifetime.KtReadActionConfinementLifetimeTokenProvider
@@ -15,13 +16,19 @@ import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISe
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.WriterBackedKaptLogger
import org.jetbrains.kotlin.kapt3.test.KaptMessageCollectorProvider
import org.jetbrains.kotlin.kapt3.test.kaptOptionsProvider
import org.jetbrains.kotlin.kotlinp.Kotlinp
import org.jetbrains.kotlin.kotlinp.KotlinpSettings
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.utils.Printer
import java.io.File
internal class Kapt4Facade(private val testServices: TestServices) :
@@ -64,7 +71,7 @@ private fun run(
options: KaptOptions,
applicationDisposable: Disposable,
projectDisposable: Disposable,
): Pair<Kapt4ContextForStubGeneration, Map<KtLightClass, Kapt4StubGenerator.KaptStub?>> {
): Pair<KaptContext, Map<KtLightClass, KaptStub?>> {
val standaloneAnalysisAPISession = buildStandaloneAnalysisAPISession(applicationDisposable, projectDisposable) {
(project as MockProject).registerService(
KtLifetimeTokenProvider::class.java,
@@ -76,24 +83,45 @@ private fun run(
val (module, psiFiles) = standaloneAnalysisAPISession.modulesWithFiles.entries.single()
return KtAnalysisSessionProvider.getInstance(module.project).analyze(module) {
val context = Kapt4ContextForStubGeneration(
val context = KaptContext(
options,
withJdk = false,
WriterBackedKaptLogger(isVerbose = false),
this@analyze,
psiFiles.filterIsInstance<KtFile>()
)
val generator = with(context) { Kapt4StubGenerator() }
context to generator.generateStubs()
val onError = { message: String ->
if (context.options[KaptFlag.STRICT]) {
context.reportKaptError(*message.split("\n").toTypedArray())
} else {
context.logger.warn(message)
}
}
context to generateStubs(psiFiles.filterIsInstance<KtFile>(), options, onError,this@analyze, metadataRenderer = { renderMetadata(it) })
}
}
internal data class Kapt4ContextBinaryArtifact(
internal val kaptContext: Kapt4ContextForStubGeneration,
internal val kaptStubs: List<Kapt4StubGenerator.KaptStub>
internal val kaptContext: KaptContext,
internal val kaptStubs: List<KaptStub>
) : ResultingArtifact.Binary<Kapt4ContextBinaryArtifact>() {
object Kind : BinaryKind<Kapt4ContextBinaryArtifact>("KaptArtifact")
override val kind: BinaryKind<Kapt4ContextBinaryArtifact>
get() = Kind
}
private fun Printer.renderMetadata(metadata: Metadata) {
val text = Kotlinp(KotlinpSettings(isVerbose = true, sortDeclarations = true)).renderClassFile(KotlinClassMetadata.read(metadata))
// "/*" and "*/" delimiters are used in kotlinp, for example to render type parameter names. Replace them with something else
// to avoid them being interpreted as Java comments.
val sanitized = text.split('\n')
.dropLast(1)
.map {
it.replace("/*", "(*").replace("*/", "*)")
}
println("/**")
sanitized.forEach {
println(" * ", it)
}
println(" */")
println("@kotlin.Metadata()")
}
@@ -11,6 +11,7 @@ import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.util.JCDiagnostic
import com.sun.tools.javac.util.List
import com.sun.tools.javac.util.Log
import org.jetbrains.kotlin.kapt3.base.KaptContext
import org.jetbrains.kotlin.kapt3.base.javac.KaptJavaLogBase
import org.jetbrains.kotlin.kapt3.base.parseJavaFiles
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.test.utils.withExtension
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import java.io.File
import java.util.*
import org.jetbrains.kotlin.kapt3.test.handlers.renderMetadata
internal class Kapt4Handler(testServices: TestServices) : AnalysisHandler<Kapt4ContextBinaryArtifact>(
testServices,
@@ -70,7 +70,7 @@ internal class Kapt4Handler(testServices: TestServices) : AnalysisHandler<Kapt4C
private fun checkJavaCompilerErrors(
module: TestModule,
kaptContext: Kapt4ContextForStubGeneration,
kaptContext: KaptContext,
actualDump: String
) {
val expectedErrors = (module.directives[EXPECTED_ERROR] + module.directives[Kapt4TestDirectives.EXPECTED_ERROR_K2]).sorted()
@@ -116,8 +116,8 @@ internal class Kapt4Handler(testServices: TestServices) : AnalysisHandler<Kapt4C
): List<JCTree.JCCompilationUnit> {
val (kaptContext, kaptStubs) = info
val convertedFiles = kaptStubs.mapIndexed { index, stub ->
val sourceFile = createTempJavaFile("stub$index.java", stub.file.prettyPrint(kaptContext.context, ::renderMetadata))
stub.writeMetadataIfNeeded(forSource = sourceFile)
val sourceFile = createTempJavaFile("stub$index.java", stub.source)
stub.writeMetadata(forSource = sourceFile)
sourceFile
}