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 0cea42772b6..77226b067f2 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -139,7 +139,11 @@ 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)) { + // K2 works with multi-module chunks only in PSI mode + if (chunk.size == 1 && + configuration.getBoolean(CommonConfigurationKeys.USE_FIR) && + configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE) + ) { if (messageCollector.hasErrors()) return COMPILATION_ERROR 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 1f9fb3f81e2..cb5df2b3a6d 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory @@ -23,6 +24,7 @@ import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.constant.EvaluatedConstTracker +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector import org.jetbrains.kotlin.fir.* @@ -55,16 +57,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.runUnless import java.io.File object FirKotlinToJvmBytecodeCompiler { - fun compileModulesUsingFrontendIR( - projectEnvironment: AbstractProjectEnvironment, + fun checkNotSupportedPlugins( projectConfiguration: CompilerConfiguration, - messageCollector: MessageCollector, - allSources: List, - buildFile: File?, - chunk: List + messageCollector: MessageCollector ): Boolean { - val performanceManager = projectConfiguration.get(CLIConfigurationKeys.PERF_MANAGER) - val notSupportedPlugins = mutableListOf().apply { projectConfiguration.get(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS) .collectIncompatiblePluginNamesTo(this, ComponentRegistrar::supportsK2) @@ -84,10 +80,23 @@ object FirKotlinToJvmBytecodeCompiler { return false } + return true + } + + fun compileModulesUsingFrontendIR( + projectEnvironment: AbstractProjectEnvironment, + projectConfiguration: CompilerConfiguration, + messageCollector: MessageCollector, + allSources: List, + buildFile: File?, + chunk: List + ): Boolean { + val performanceManager = projectConfiguration.get(CLIConfigurationKeys.PERF_MANAGER) + val outputs = ArrayList>(chunk.size) val targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) val incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) - val isMultiModuleChunk = chunk.size > 1 + val isMultiModuleChunk = chunk.size > 1 // Note: should be always false // TODO: run lowerings for all modules in the chunk, then run codegen for all modules. val project = (projectEnvironment as? VfsBasedProjectEnvironment)?.project @@ -141,12 +150,12 @@ object FirKotlinToJvmBytecodeCompiler { performanceManager?.notifyAnalysisStarted() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - if (!checkKotlinPackageUsageForPsi(moduleConfiguration, allSources)) return null + if (!checkKotlinPackageUsageForPsi(configuration, allSources)) return null - val renderDiagnosticNames = moduleConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() - val firResult = runFrontend(allSources, diagnosticsReporter).also { + val firResult = runFrontend(allSources, diagnosticsReporter, module.getModuleName(), module.getFriendPaths()).also { performanceManager?.notifyAnalysisFinished() } if (firResult == null) { @@ -157,20 +166,9 @@ object FirKotlinToJvmBytecodeCompiler { performanceManager?.notifyGenerationStarted() performanceManager?.notifyIRTranslationStarted() - val fir2IrExtensions = JvmFir2IrExtensions(moduleConfiguration, JvmIrDeserializerImpl(), JvmIrMangler) - val fir2IrConfiguration = Fir2IrConfiguration( - languageVersionSettings = moduleConfiguration.languageVersionSettings, - diagnosticReporter = diagnosticsReporter, - linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES), - evaluatedConstTracker = moduleConfiguration - .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), - inlineConstTracker = moduleConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], - allowNonCachedDeclarations = false, - ) - val fir2IrAndIrActualizerResult = firResult.convertToIrAndActualizeForJvm( - fir2IrExtensions, - fir2IrConfiguration, - irGenerationExtensions, + val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler) + val fir2IrAndIrActualizerResult = convertToIrAndActualizeForJvm( + firResult, diagnosticsReporter, fir2IrExtensions, irGenerationExtensions ) performanceManager?.notifyIRTranslationFinished() @@ -191,7 +189,12 @@ object FirKotlinToJvmBytecodeCompiler { return firResult to generationState } - private fun CompilationContext.runFrontend(ktFiles: List, diagnosticsReporter: BaseDiagnosticsCollector): FirResult? { + fun FrontendContext.runFrontend( + ktFiles: List, + diagnosticsReporter: BaseDiagnosticsCollector, + rootModuleName: String, + friendPaths: List, + ): FirResult? { val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile -> AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound } @@ -204,7 +207,7 @@ object FirKotlinToJvmBytecodeCompiler { val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( projectEnvironment, incrementalComponents, - moduleConfiguration, + configuration, targetIds, sourceScope ) @@ -212,10 +215,9 @@ object FirKotlinToJvmBytecodeCompiler { providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { librariesScope -= it } - val rootModuleName = module.getModuleName() - val libraryList = createLibraryListForJvm(rootModuleName, moduleConfiguration, module.getFriendPaths()) + val libraryList = createLibraryListForJvm(rootModuleName, configuration, friendPaths) val sessionsWithSources = prepareJvmSessions( - ktFiles, moduleConfiguration, projectEnvironment, Name.special("<$rootModuleName>"), + ktFiles, configuration, projectEnvironment, Name.special("<$rootModuleName>"), extensionRegistrars, librariesScope, libraryList, isCommonSource = { it.isCommonSource == true }, fileBelongsToModule = { file, moduleName -> file.hmppModuleName == moduleName }, @@ -229,6 +231,28 @@ object FirKotlinToJvmBytecodeCompiler { return runUnless(syntaxErrors || diagnosticsReporter.hasErrors) { FirResult(outputs) } } + fun FrontendContext.convertToIrAndActualizeForJvm( + firResult: FirResult, + diagnosticsReporter: DiagnosticReporter, + fir2IrExtensions: JvmFir2IrExtensions, + irGenerationExtensions: Collection, + ): Fir2IrActualizedResult { + val fir2IrConfiguration = Fir2IrConfiguration( + languageVersionSettings = configuration.languageVersionSettings, + diagnosticReporter = diagnosticsReporter, + linkViaSignatures = configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES), + evaluatedConstTracker = configuration + .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), + inlineConstTracker = configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false, + ) + return firResult.convertToIrAndActualizeForJvm( + fir2IrExtensions, + fir2IrConfiguration, + irGenerationExtensions, + ) + } + private fun CompilationContext.runBackend( ktFiles: List, fir2IrActualizedResult: Fir2IrActualizedResult, @@ -238,17 +262,17 @@ object FirKotlinToJvmBytecodeCompiler { val (moduleFragment, components, pluginContext, irActualizedResult) = fir2IrActualizedResult val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext val codegenFactory = JvmIrCodegenFactory( - moduleConfiguration, - moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG), + configuration, + configuration.get(CLIConfigurationKeys.PHASE_CONFIG), ) val generationState = GenerationState.Builder( (projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, - moduleFragment.descriptor, dummyBindingContext, moduleConfiguration + moduleFragment.descriptor, dummyBindingContext, configuration ).withModule( module ).onIndependentPartCompilationEnd( - createOutputFilesFlushingCallbackIfPossible(moduleConfiguration) + createOutputFilesFlushingCallbackIfPossible(configuration) ).isIrBackend( true ).jvmBackendClassResolver( @@ -290,16 +314,48 @@ object FirKotlinToJvmBytecodeCompiler { private class CompilationContext( val module: Module, val allSources: List, - val projectEnvironment: AbstractProjectEnvironment, - val messageCollector: MessageCollector, + override val projectEnvironment: AbstractProjectEnvironment, + override val messageCollector: MessageCollector, val renderDiagnosticName: Boolean, - val moduleConfiguration: CompilerConfiguration, + override val configuration: CompilerConfiguration, val performanceManager: CommonCompilerPerformanceManager?, - val targetIds: List?, - val incrementalComponents: IncrementalCompilationComponents?, - val extensionRegistrars: List, + override val targetIds: List?, + override val incrementalComponents: IncrementalCompilationComponents?, + override val extensionRegistrars: List, val irGenerationExtensions: Collection - ) + ) : FrontendContext + + class FrontendContextForMultiChunkMode private constructor( + override val projectEnvironment: AbstractProjectEnvironment, + override val messageCollector: MessageCollector, + override val incrementalComponents: IncrementalCompilationComponents?, + override val extensionRegistrars: List, + override val configuration: CompilerConfiguration, + override val targetIds: List? + ) : FrontendContext { + constructor( + projectEnvironment: AbstractProjectEnvironment, + environment: KotlinCoreEnvironment, + projectConfiguration: CompilerConfiguration, + project: Project? + ) : this( + projectEnvironment, + environment.messageCollector, + incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), + extensionRegistrars = project?.let { FirExtensionRegistrar.getInstances(it) } ?: emptyList(), + configuration = projectConfiguration, + targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) + ) + } + + interface FrontendContext { + val projectEnvironment: AbstractProjectEnvironment + val messageCollector: MessageCollector + val incrementalComponents: IncrementalCompilationComponents? + val extensionRegistrars: List + val configuration: CompilerConfiguration + val targetIds: List? + } } fun findMainClass(fir: List): FqName? { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 1a244f76dab..438045a0396 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -13,13 +13,19 @@ import com.intellij.psi.PsiJavaModule import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analyzer.AnalysisResult +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.backend.jvm.JvmBackendExtension +import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory +import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsageForPsi import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.toLogger +import org.jetbrains.kotlin.cli.jvm.compiler.FirKotlinToJvmBytecodeCompiler.convertToIrAndActualizeForJvm +import org.jetbrains.kotlin.cli.jvm.compiler.FirKotlinToJvmBytecodeCompiler.runFrontend import org.jetbrains.kotlin.cli.jvm.config.* import org.jetbrains.kotlin.cli.jvm.config.ClassicFrontendSpecificJvmConfigurationKeys.JAVA_CLASSES_TRACKER import org.jetbrains.kotlin.codegen.ClassBuilderFactories @@ -28,11 +34,18 @@ import org.jetbrains.kotlin.codegen.DefaultCodegenFactory import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.CommonConfigurationKeys.LOOKUP_TRACKER +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector +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.pipeline.Fir2IrActualizedResult import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries +import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager import org.jetbrains.kotlin.modules.Module +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext @@ -69,36 +82,92 @@ object KotlinToJVMBytecodeCompiler { } val projectConfiguration = environment.configuration - if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) { + var mainClassFqName: FqName? = null + val moduleDescriptor: ModuleDescriptor + val bindingContext: BindingContext + var firJvmBackendClassResolver: FirJvmBackendClassResolver? = null + var firJvmBackendExtension: FirJvmBackendExtension? = null + val irResult = if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) { + // K2/PSI: base checks val projectEnvironment = VfsBasedProjectEnvironment( environment.project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) ) { environment.createPackagePartProvider(it) } - return FirKotlinToJvmBytecodeCompiler.compileModulesUsingFrontendIR( - projectEnvironment, - environment.configuration, - environment.messageCollector, - environment.getSourceFiles(), - buildFile, chunk + + if (!FirKotlinToJvmBytecodeCompiler.checkNotSupportedPlugins( + projectConfiguration, environment.messageCollector + ) + ) return false + + // K2/PSI: single chunk mode fallback + if (chunk.size == 1) { + return FirKotlinToJvmBytecodeCompiler.compileModulesUsingFrontendIR( + projectEnvironment, + environment.configuration, + environment.messageCollector, + environment.getSourceFiles(), + buildFile, chunk + ) + } + + val sourceFiles = environment.getSourceFiles() + val project = (projectEnvironment as? VfsBasedProjectEnvironment)?.project + val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() + val frontendContext = FirKotlinToJvmBytecodeCompiler.FrontendContextForMultiChunkMode( + projectEnvironment, environment, projectConfiguration, project ) + + with(frontendContext) { + // K2/PSI: frontend + val firResult = runFrontend( + sourceFiles, diagnosticsReporter, chunk.joinToString(separator = "+") { it.getModuleName() }, + chunk.fold(emptyList()) { paths, m -> paths + m.getFriendPaths() } + ) ?: run { + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector( + diagnosticsReporter, messageCollector, + projectConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + ) + return false + } + // K2/PSI: FIR2IR + val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler) + val irGenerationExtensions = project?.let { IrGenerationExtension.getInstances(it) } ?: emptyList() + val fir2IrAndIrActualizerResult = convertToIrAndActualizeForJvm( + firResult, diagnosticsReporter, fir2IrExtensions, irGenerationExtensions + ) + moduleDescriptor = fir2IrAndIrActualizerResult.irModuleFragment.descriptor + bindingContext = NoScopeRecordCliBindingTrace().bindingContext + firJvmBackendClassResolver = FirJvmBackendClassResolver(fir2IrAndIrActualizerResult.components) + firJvmBackendExtension = FirJvmBackendExtension( + fir2IrAndIrActualizerResult.components, fir2IrAndIrActualizerResult.irActualizedResult + ) + fir2IrAndIrActualizerResult.codegenFactoryWithJvmIrBackendInput(configuration) + } + } else { + // K1: Frontend + val result = repeatAnalysisIfNeeded(analyze(environment), environment) + if (result == null || !result.shouldGenerateCode) return false + moduleDescriptor = result.moduleDescriptor + bindingContext = result.bindingContext + + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + + result.throwIfError() + + if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { + mainClassFqName = findMainClass( + result.bindingContext, projectConfiguration.languageVersionSettings, environment.getSourceFiles() + ) + } + + // K1: PSI2IR + convertToIr(environment, result) } - - val result = repeatAnalysisIfNeeded(analyze(environment), environment) - if (result == null || !result.shouldGenerateCode) return false - - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - - result.throwIfError() - - val mainClassFqName = - if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) - findMainClass(result.bindingContext, projectConfiguration.languageVersionSettings, environment.getSourceFiles()) - else null - + // K1/K2 common multi-chunk part val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) + val (codegenFactory, wholeBackendInput) = irResult - val (codegenFactory, wholeBackendInput) = convertToIr(environment, result) val diagnosticsReporter = DiagnosticReporterFactory.createReporter() val codegenInputs = ArrayList(chunk.size) @@ -110,16 +179,23 @@ object KotlinToJVMBytecodeCompiler { if (!checkKotlinPackageUsageForPsi(environment.configuration, ktFiles)) return false val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile) - val backendInput = codegenFactory.getModuleChunkBackendInput(wholeBackendInput, ktFiles) + val backendInput = codegenFactory.getModuleChunkBackendInput(wholeBackendInput, ktFiles).let { + if (it is JvmIrCodegenFactory.JvmIrBackendInput && firJvmBackendExtension != null) { + it.copy(backendExtension = firJvmBackendExtension!!) + } else it + } + // Lowerings (per module) codegenInputs += runLowerings( - environment, moduleConfiguration, result, ktFiles, module, codegenFactory, backendInput, diagnosticsReporter + environment, moduleConfiguration, moduleDescriptor, bindingContext, + ktFiles, module, codegenFactory, backendInput, diagnosticsReporter, firJvmBackendClassResolver ) } val outputs = ArrayList(chunk.size) for (input in codegenInputs) { - outputs += runCodegen(input, input.state, codegenFactory, result.bindingContext, diagnosticsReporter, environment.configuration) + // Codegen (per module) + outputs += runCodegen(input, input.state, codegenFactory, bindingContext, diagnosticsReporter, environment.configuration) } return writeOutputsIfNeeded(environment.project, projectConfiguration, chunk, outputs, mainClassFqName) @@ -195,8 +271,8 @@ object KotlinToJVMBytecodeCompiler { val (codegenFactory, backendInput) = convertToIr(environment, result) val diagnosticsReporter = DiagnosticReporterFactory.createReporter() val input = runLowerings( - environment, environment.configuration, result, environment.getSourceFiles(), null, codegenFactory, backendInput, - diagnosticsReporter + environment, environment.configuration, result.moduleDescriptor, result.bindingContext, + environment.getSourceFiles(), null, codegenFactory, backendInput, diagnosticsReporter ) return runCodegen(input, input.state, codegenFactory, result.bindingContext, diagnosticsReporter, environment.configuration) } @@ -227,6 +303,22 @@ object KotlinToJVMBytecodeCompiler { return Pair(codegenFactory, backendInput) } + private fun Fir2IrActualizedResult.codegenFactoryWithJvmIrBackendInput( + configuration: CompilerConfiguration + ): Pair { + val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG) + val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig) + return codegenFactory to JvmIrCodegenFactory.JvmIrBackendInput( + irModuleFragment, + components.symbolTable, + phaseConfig, + components.irProviders, + JvmGeneratorExtensionsImpl(configuration), + JvmBackendExtension.Default, + pluginContext, + ) {} + } + fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? { val collector = environment.messageCollector val sourceFiles = environment.getSourceFiles() @@ -296,26 +388,32 @@ object KotlinToJVMBytecodeCompiler { private fun runLowerings( environment: KotlinCoreEnvironment, configuration: CompilerConfiguration, - result: AnalysisResult, + moduleDescriptor: ModuleDescriptor, + bindingContext: BindingContext, sourceFiles: List, module: Module?, codegenFactory: CodegenFactory, backendInput: CodegenFactory.BackendInput, diagnosticsReporter: BaseDiagnosticsCollector, + firJvmBackendClassResolver: FirJvmBackendClassResolver? = null, ): CodegenFactory.CodegenInput { val performanceManager = environment.configuration[CLIConfigurationKeys.PERF_MANAGER] val state = GenerationState.Builder( environment.project, ClassBuilderFactories.BINARIES, - result.moduleDescriptor, - result.bindingContext, + moduleDescriptor, + bindingContext, configuration ) .withModule(module) .onIndependentPartCompilationEnd(createOutputFilesFlushingCallbackIfPossible(configuration)) .diagnosticReporter(diagnosticsReporter) - .build() + .apply { + if (firJvmBackendClassResolver != null) { + jvmBackendClassResolver(firJvmBackendClassResolver) + } + }.build() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()