From 84bf411cc3a3f49482530b66ef25ff7858d297cf Mon Sep 17 00:00:00 2001 From: Pavel Mikhailovskii Date: Mon, 31 Jul 2023 18:07:40 +0000 Subject: [PATCH] Changes in the compiler needed to run KAPT 4 (KT-51982) --- .../jetbrains/kotlin/cli/common/arguments.kt | 2 -- .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 2 +- .../FirKotlinToJvmBytecodeCompiler.kt | 5 +++++ .../jvm/compiler/pipeline/compilerPipeline.kt | 6 +++++- .../extensions/FirAnalysisHandlerExtension.kt | 21 +++++++++++++++++-- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt index 07c6af28c06..a2a42d07866 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt @@ -77,9 +77,7 @@ private fun switchToFallbackModeIfNecessary(arguments: CommonCompilerArguments, arguments.skipPrereleaseCheck = true arguments.allowUnstableDependencies = true } - isK2 && isKaptUsed && arguments.useKapt4 -> warn("Kapt 4 is still experimental. Use with caution.") arguments.useKapt4 && !isK2 -> warn("-Xuse-kapt4 flag can be only used with language version 2.0+.") - arguments.useKapt4 && !isKaptUsed -> warn("-Xuse-kapt4 flag is present but no Kapt configuration options are provided.") } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index 04cfc182a7c..89bd3510ccf 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -142,7 +142,7 @@ class K2JVMCompiler : CLICompiler() { val targetDescription = chunk.map { input -> input.getModuleName() + "-" + input.getModuleType() }.let { names -> names.singleOrNull() ?: names.joinToString() } - if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR) && configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE)) { + if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR) && configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE)) { val projectEnvironment = createProjectEnvironment(configuration, rootDisposable, EnvironmentConfigFiles.JVM_CONFIG_FILES, messageCollector) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index c021fbc154a..1f9fb3f81e2 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.jvm.* import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.extensions.FirAnalysisHandlerExtension import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.pipeline.* import org.jetbrains.kotlin.fir.session.* @@ -90,6 +91,10 @@ object FirKotlinToJvmBytecodeCompiler { // TODO: run lowerings for all modules in the chunk, then run codegen for all modules. val project = (projectEnvironment as? VfsBasedProjectEnvironment)?.project + if (project != null) { + FirAnalysisHandlerExtension.analyze(project, projectConfiguration)?.let { return it } + } + for (module in chunk) { val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile) val context = CompilationContext( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt index c358fb6914f..ed619d9b50d 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions +import org.jetbrains.kotlin.fir.extensions.FirAnalysisHandlerExtension import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.pipeline.FirResult import org.jetbrains.kotlin.fir.pipeline.buildResolveAndCheckFirViaLightTree @@ -87,6 +88,9 @@ fun compileModulesUsingFrontendIrAndLightTree( performanceManager?.notifyCompilerInitialized(0, 0, targetDescription) + val project = projectEnvironment.project + FirAnalysisHandlerExtension.analyze(project, compilerConfiguration)?.let { return it } + val outputs = mutableListOf() var mainClassFqName: FqName? = null @@ -509,7 +513,7 @@ private fun VirtualFileSystem.findJarRoot(file: File): VirtualFile? = findFileByPath("$file${URLUtil.JAR_SEPARATOR}") private fun VirtualFileSystem.findExistingRoot( - root: JvmContentRoot, rootDescription: String, messageCollector: MessageCollector + root: JvmContentRoot, rootDescription: String, messageCollector: MessageCollector, ): VirtualFile? { return findFileByPath(root.file.absolutePath).also { if (it == null) { diff --git a/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fir/extensions/FirAnalysisHandlerExtension.kt b/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fir/extensions/FirAnalysisHandlerExtension.kt index 3dbcba08006..c2c2fd98788 100644 --- a/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fir/extensions/FirAnalysisHandlerExtension.kt +++ b/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fir/extensions/FirAnalysisHandlerExtension.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.extensions +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor @@ -13,7 +14,22 @@ abstract class FirAnalysisHandlerExtension { companion object : ProjectExtensionDescriptor( "org.jetbrains.kotlin.fir.firAnalyzeCompleteHandlerExtension", FirAnalysisHandlerExtension::class.java - ) + ) { + /** + * Applies [FirAnalysisHandlerExtension] instances to a project + * @receiver the project to analyze + * @param configuration compiler configuration + * @return [null] if no applicable extensions were found, [true] if all applicable extensions returned [true] from [doAnalysis], + * [false] if any applicable extension returned [false] + * + * @see FirAnalysisHandlerExtension.isApplicable + * @see FirAnalysisHandlerExtension.doAnalysis + */ + fun analyze(project: Project, configuration: CompilerConfiguration): Boolean? { + val extensions = FirAnalysisHandlerExtension.getInstances(project).filter { it.isApplicable(configuration) } + return if (extensions.isEmpty()) null else extensions.all { it.doAnalysis(configuration) } + } + } /** * Checks whether [doAnalysis] should be called @@ -25,7 +41,8 @@ abstract class FirAnalysisHandlerExtension { /** * Performs code analysis * @param configuration compiler configuration - * @return true if analysis completed successfully. There can be different causes of failure, an incorrect configuration for example. + * @return [true] if analysis completed successfully, [false] otherwise. + * There can be different causes of failure, an incorrect configuration for example. * A failure means that there's no reason to continue building the project. */ abstract fun doAnalysis(configuration: CompilerConfiguration): Boolean