diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt index 224882e1080..b1d1bf12fa0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt @@ -16,15 +16,43 @@ package org.jetbrains.kotlin.codegen +import com.intellij.openapi.project.Project import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.BindingContext interface CodegenFactory { - fun generateModule(state: GenerationState, files: Collection) + fun convertToIr(input: IrConversionInput): BackendInput + + fun generateModule(state: GenerationState, input: BackendInput) + + class IrConversionInput( + val project: Project, + val files: Collection, + val configuration: CompilerConfiguration, + val module: ModuleDescriptor, + val bindingContext: BindingContext, + val languageVersionSettings: LanguageVersionSettings, + val ignoreErrors: Boolean, + ) { + companion object { + fun fromGenerationState(state: GenerationState): IrConversionInput = + with(state) { + IrConversionInput( + project, files, configuration, module, originalFrontendBindingContext, languageVersionSettings, ignoreErrors + ) + } + } + } + + interface BackendInput companion object { fun doCheckCancelled(state: GenerationState) { @@ -36,11 +64,15 @@ interface CodegenFactory { } object DefaultCodegenFactory : CodegenFactory { - override fun generateModule(state: GenerationState, files: Collection) { + object DummyOldBackendInput : CodegenFactory.BackendInput + + override fun convertToIr(input: CodegenFactory.IrConversionInput): CodegenFactory.BackendInput = DummyOldBackendInput + + override fun generateModule(state: GenerationState, input: CodegenFactory.BackendInput) { val filesInPackages = MultiMap() val filesInMultifileClasses = MultiMap() - for (file in files) { + for (file in state.files) { val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file) if (fileClassInfo.withJvmMultifileClass) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java index bf9d4c7afc1..a51d05134e9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java @@ -32,7 +32,12 @@ public class KotlinCodegenFacade { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - state.getCodegenFactory().generateModule(state, state.getFiles()); + CodegenFactory.IrConversionInput psi2irInput = CodegenFactory.IrConversionInput.Companion.fromGenerationState(state); + CodegenFactory.BackendInput backendInput = state.getCodegenFactory().convertToIr(psi2irInput); + + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + + state.getCodegenFactory().generateModule(state, backendInput); CodegenFactory.Companion.doCheckCancelled(state); state.getFactory().done(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 7c5c2ccf131..5cf29511774 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -67,9 +67,9 @@ class GenerationState private constructor( private val onIndependentPartCompilationEnd: GenerationStateEventCallback, wantsDiagnostics: Boolean, val jvmBackendClassResolver: JvmBackendClassResolver, - val isIrBackend: Boolean + val isIrBackend: Boolean, + val ignoreErrors: Boolean, ) { - class Builder( private val project: Project, private val builderFactory: ClassBuilderFactory, @@ -118,12 +118,16 @@ class GenerationState private constructor( fun isIrBackend(v: Boolean) = apply { isIrBackend = v } + var ignoreErrors: Boolean = false + fun ignoreErrors(v: Boolean): Builder = + apply { ignoreErrors = v } + fun build() = GenerationState( project, builderFactory, module, bindingContext, files, configuration, generateDeclaredClassFilter, codegenFactory, targetId, moduleName, outDirectory, onIndependentPartCompilationEnd, wantsDiagnostics, - jvmBackendClassResolver, isIrBackend + jvmBackendClassResolver, isIrBackend, ignoreErrors ) } diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 5ac85cab269..62b04404e41 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl @@ -45,7 +44,6 @@ open class JvmIrCodegenFactory( private val jvmGeneratorExtensions: JvmGeneratorExtensionsImpl = JvmGeneratorExtensionsImpl(configuration), ) : CodegenFactory { data class JvmIrBackendInput( - val state: GenerationState, val irModuleFragment: IrModuleFragment, val symbolTable: SymbolTable, val phaseConfig: PhaseConfig?, @@ -53,26 +51,20 @@ open class JvmIrCodegenFactory( val extensions: JvmGeneratorExtensionsImpl, val backendExtension: JvmBackendExtension, val notifyCodegenStart: () -> Unit, - ) + ) : CodegenFactory.BackendInput - override fun generateModule(state: GenerationState, files: Collection) { - val input = convertToIr(state, files) - doGenerateFilesInternal(input) - } - - @JvmOverloads - fun convertToIr(state: GenerationState, files: Collection, ignoreErrors: Boolean = false): JvmIrBackendInput { + override fun convertToIr(input: CodegenFactory.IrConversionInput): JvmIrBackendInput { val (mangler, symbolTable) = if (externalSymbolTable != null) externalMangler!! to externalSymbolTable else { - val mangler = JvmDescriptorMangler(MainFunctionDetector(state.bindingContext, state.languageVersionSettings)) + val mangler = JvmDescriptorMangler(MainFunctionDetector(input.bindingContext, input.languageVersionSettings)) val symbolTable = SymbolTable(JvmIdSignatureDescriptor(mangler), IrFactoryImpl, JvmNameProvider) mangler to symbolTable } - val psi2ir = Psi2IrTranslator(state.languageVersionSettings, Psi2IrConfiguration(ignoreErrors)) - val messageLogger = state.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None - val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, symbolTable, jvmGeneratorExtensions) - val pluginExtensions = IrGenerationExtension.getInstances(state.project) + val psi2ir = Psi2IrTranslator(input.languageVersionSettings, Psi2IrConfiguration(input.ignoreErrors)) + val messageLogger = input.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None + val psi2irContext = psi2ir.createGeneratorContext(input.module, input.bindingContext, symbolTable, jvmGeneratorExtensions) + val pluginExtensions = IrGenerationExtension.getInstances(input.project) val stubGenerator = DeclarationStubGeneratorImpl(psi2irContext.moduleDescriptor, symbolTable, psi2irContext.irBuiltIns, jvmGeneratorExtensions) @@ -111,7 +103,7 @@ open class JvmIrCodegenFactory( } } - SourceDeclarationsPreprocessor(psi2irContext).run(files) + SourceDeclarationsPreprocessor(psi2irContext).run(input.files) for (extension in pluginExtensions) { psi2ir.addPostprocessingStep { module -> @@ -143,7 +135,7 @@ open class JvmIrCodegenFactory( val irProviders = listOf(irLinker) val irModuleFragment = - psi2ir.generateModuleFragment(psi2irContext, files, irProviders, pluginExtensions, expectDescriptorToSymbol = null) + psi2ir.generateModuleFragment(psi2irContext, input.files, irProviders, pluginExtensions, expectDescriptorToSymbol = null) irLinker.postProcess() stubGenerator.unboundSymbolGeneration = true @@ -151,13 +143,12 @@ open class JvmIrCodegenFactory( // We need to compile all files we reference in Klibs irModuleFragment.files.addAll(dependencies.flatMap { it.files }) - if (!state.configuration.getBoolean(JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT)) { - val originalBindingContext = state.originalFrontendBindingContext as? CleanableBindingContext - ?: error("BindingContext should be cleanable in JVM IR to avoid leaking memory: ${state.originalFrontendBindingContext}") + if (!input.configuration.getBoolean(JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT)) { + val originalBindingContext = input.bindingContext as? CleanableBindingContext + ?: error("BindingContext should be cleanable in JVM IR to avoid leaking memory: ${input.bindingContext}") originalBindingContext.clear() } return JvmIrBackendInput( - state, irModuleFragment, symbolTable, phaseConfig, @@ -177,8 +168,9 @@ open class JvmIrCodegenFactory( return result.toList() } - fun doGenerateFilesInternal(input: JvmIrBackendInput) { - val (state, irModuleFragment, symbolTable, customPhaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) = input + override fun generateModule(state: GenerationState, input: CodegenFactory.BackendInput) { + val (irModuleFragment, symbolTable, customPhaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) = + input as JvmIrBackendInput val irSerializer = if (state.configuration.getBoolean(JVMConfigurationKeys.SERIALIZE_IR)) JvmIrSerializerImpl(state.configuration) else null @@ -208,9 +200,10 @@ open class JvmIrCodegenFactory( notifyCodegenStart: () -> Unit = {} ) { val irProviders = configureBuiltInsAndGenerateIrProvidersInFrontendIRMode(irModuleFragment, symbolTable, extensions) - doGenerateFilesInternal( + generateModule( + state, JvmIrBackendInput( - state, irModuleFragment, symbolTable, phaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart + irModuleFragment, symbolTable, phaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart ) ) } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt index c9e21b8bc17..ca92efdbb4b 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt @@ -6,11 +6,13 @@ package org.jetbrains.kotlin.test.backend.ir import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory +import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.test.model.BackendKinds import org.jetbrains.kotlin.test.model.ResultingArtifact // IR backend (JVM, JS, Native) data class IrBackendInput( + val state: GenerationState, val backendInput: JvmIrCodegenFactory.JvmIrBackendInput ) : ResultingArtifact.BackendInput() { override val kind: BackendKinds.IrBackend diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/JvmIrBackendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/JvmIrBackendFacade.kt index 1e21f3e79c8..f0a1ce8aeea 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/JvmIrBackendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/JvmIrBackendFacade.kt @@ -22,10 +22,10 @@ class JvmIrBackendFacade( module: TestModule, inputArtifact: IrBackendInput ): BinaryArtifacts.Jvm? { - val state = inputArtifact.backendInput.state + val state = inputArtifact.state val codegenFactory = state.codegenFactory as JvmIrCodegenFactory try { - codegenFactory.doGenerateFilesInternal(inputArtifact.backendInput) + codegenFactory.generateModule(state, inputArtifact.backendInput) } catch (e: BackendException) { if (CodegenTestDirectives.IGNORE_ERRORS in module.directives) { return null diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt index cd3ada99688..9e774194d12 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.frontend.classic import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.codegen.CodegenFactory import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.test.backend.ir.IrBackendInput import org.jetbrains.kotlin.test.directives.CodegenTestDirectives @@ -41,9 +42,9 @@ class ClassicFrontend2IrConverter( files, configuration ).codegenFactory(codegenFactory) .isIrBackend(true) + .ignoreErrors(CodegenTestDirectives.IGNORE_ERRORS in module.directives) .build() - val ignoreErrors = CodegenTestDirectives.IGNORE_ERRORS in module.directives - return IrBackendInput(codegenFactory.convertToIr(state, files, ignoreErrors)) + return IrBackendInput(state, codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationState(state))) } } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt index 5cf9a3e80f9..4a5c50dc91d 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt @@ -75,8 +75,8 @@ class Fir2IrResultsConverter( val irProviders = codegenFactory.configureBuiltInsAndGenerateIrProvidersInFrontendIRMode(irModuleFragment, symbolTable, extensions) return IrBackendInput( + generationState, JvmIrCodegenFactory.JvmIrBackendInput( - generationState, irModuleFragment, symbolTable, phaseConfig, diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt index d3b499358ba..133ed12222d 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollectorBasedReporter import org.jetbrains.kotlin.cli.common.repl.LineId import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.codegen.CodegenFactory import org.jetbrains.kotlin.codegen.KotlinCodegenFacade import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.JVMConfigurationKeys @@ -200,7 +201,10 @@ open class KJvmReplCompilerBase( .codegenFactory(codegenFactory) .build() - generationState.codegenFactory.generateModule(generationState, generationState.files) + codegenFactory.generateModule( + generationState, + codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationState(generationState)), + ) return generationState }