JVM IR, FIR: add JvmBackendExtension instead of MetadataSerializerFactory

This might be a better place for future behavior that should be
abstracted between FE 1.0 and FIR, in JVM IR.
This commit is contained in:
Alexander Udalov
2020-12-01 19:04:25 +01:00
parent a5ddb1fdf1
commit 7d37030095
12 changed files with 85 additions and 37 deletions
@@ -52,10 +52,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
@@ -389,10 +389,8 @@ object KotlinToJVMBytecodeCompiler {
performanceManager?.notifyIRGenerationStarted() performanceManager?.notifyIRGenerationStarted()
generationState.beforeCompile() generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode( codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, symbolTable, sourceManager, extensions generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components)
) { context, irClass, _, serializationBindings, parent -> )
FirMetadataSerializer(session, context, irClass, serializationBindings, components, parent)
}
CodegenFactory.doCheckCancelled(generationState) CodegenFactory.doCheckCancelled(generationState)
generationState.factory.done() generationState.factory.done()
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.backend.jvm
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmBackendExtension
import org.jetbrains.kotlin.backend.jvm.codegen.MetadataSerializer
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.org.objectweb.asm.Type
class FirJvmBackendExtension(private val session: FirSession, private val components: Fir2IrComponents) : JvmBackendExtension {
override fun createSerializer(
context: JvmBackendContext,
klass: IrClass,
type: Type,
bindings: JvmSerializationBindings,
parentSerializer: MetadataSerializer?
): MetadataSerializer {
return FirMetadataSerializer(session, context, klass, bindings, components, parentSerializer)
}
}
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.backend.jvm.lower.CollectionStubComputer
import org.jetbrains.kotlin.backend.jvm.lower.JvmInnerClassesSupport import org.jetbrains.kotlin.backend.jvm.lower.JvmInnerClassesSupport
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.MemoizedInlineClassReplacements import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.MemoizedInlineClassReplacements
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
@@ -41,8 +40,6 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
typealias MetadataSerializerFactory = (JvmBackendContext, IrClass, Type, JvmSerializationBindings, MetadataSerializer?) -> MetadataSerializer
class JvmBackendContext( class JvmBackendContext(
val state: GenerationState, val state: GenerationState,
val psiSourceManager: PsiSourceManager, val psiSourceManager: PsiSourceManager,
@@ -51,7 +48,7 @@ class JvmBackendContext(
private val symbolTable: SymbolTable, private val symbolTable: SymbolTable,
val phaseConfig: PhaseConfig, val phaseConfig: PhaseConfig,
val generatorExtensions: JvmGeneratorExtensions, val generatorExtensions: JvmGeneratorExtensions,
val serializerFactory: MetadataSerializerFactory val backendExtension: JvmBackendExtension,
) : CommonBackendContext { ) : CommonBackendContext {
// If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class // If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class
// annotated with @JvmPackageName, the correct name is recorded here. // annotated with @JvmPackageName, the correct name is recorded here.
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.jvm.codegen.DescriptorMetadataSerializer
import org.jetbrains.kotlin.backend.jvm.codegen.MetadataSerializer
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.org.objectweb.asm.Type
interface JvmBackendExtension {
fun createSerializer(
context: JvmBackendContext, klass: IrClass, type: Type, bindings: JvmSerializationBindings, parentSerializer: MetadataSerializer?
): MetadataSerializer
object Default : JvmBackendExtension {
override fun createSerializer(
context: JvmBackendContext,
klass: IrClass,
type: Type,
bindings: JvmSerializationBindings,
parentSerializer: MetadataSerializer?
): MetadataSerializer {
return DescriptorMetadataSerializer(context, klass, type, bindings, parentSerializer)
}
}
}
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.DescriptorMetadataSerializer
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
import org.jetbrains.kotlin.codegen.CodegenFactory import org.jetbrains.kotlin.codegen.CodegenFactory
@@ -120,7 +119,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
doGenerateFilesInternal( doGenerateFilesInternal(
state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig,
irProviders, extensions, ::DescriptorMetadataSerializer irProviders, extensions, JvmBackendExtension.Default,
) )
} }
@@ -132,11 +131,11 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
phaseConfig: PhaseConfig, phaseConfig: PhaseConfig,
irProviders: List<IrProvider>, irProviders: List<IrProvider>,
extensions: JvmGeneratorExtensions, extensions: JvmGeneratorExtensions,
serializerFactory: MetadataSerializerFactory, backendExtension: JvmBackendExtension,
) { ) {
val context = JvmBackendContext( val context = JvmBackendContext(
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment,
symbolTable, phaseConfig, extensions, serializerFactory symbolTable, phaseConfig, extensions, backendExtension
) )
/* JvmBackendContext creates new unbound symbols, have to resolve them. */ /* JvmBackendContext creates new unbound symbols, have to resolve them. */
ExternalDependenciesGenerator(symbolTable, irProviders, state.languageVersionSettings).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, irProviders, state.languageVersionSettings).generateUnboundSymbolsAsDependencies()
@@ -178,7 +177,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
symbolTable: SymbolTable, symbolTable: SymbolTable,
sourceManager: PsiSourceManager, sourceManager: PsiSourceManager,
extensions: JvmGeneratorExtensions, extensions: JvmGeneratorExtensions,
serializerFactory: MetadataSerializerFactory backendExtension: JvmBackendExtension,
) { ) {
irModuleFragment.irBuiltins.functionFactory = IrFunctionFactory(irModuleFragment.irBuiltins, symbolTable) irModuleFragment.irBuiltins.functionFactory = IrFunctionFactory(irModuleFragment.irBuiltins, symbolTable)
val irProviders = generateTypicalIrProviderList( val irProviders = generateTypicalIrProviderList(
@@ -186,7 +185,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
) )
doGenerateFilesInternal( doGenerateFilesInternal(
state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, serializerFactory state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension,
) )
} }
} }
@@ -190,7 +190,9 @@ class ClassCodegen private constructor(
} }
private val metadataSerializer: MetadataSerializer = private val metadataSerializer: MetadataSerializer =
context.serializerFactory(context, irClass, type, visitor.serializationBindings, parentClassCodegen?.metadataSerializer) context.backendExtension.createSerializer(
context, irClass, type, visitor.serializationBindings, parentClassCodegen?.metadataSerializer
)
private fun generateKotlinMetadataAnnotation() { private fun generateKotlinMetadataAnnotation() {
// TODO: if `-Xmultifile-parts-inherit` is enabled, write the corresponding flag for parts and facades to [Metadata.extraInt]. // TODO: if `-Xmultifile-parts-inherit` is enabled, write the corresponding flag for parts and facades to [Metadata.extraInt].
@@ -190,7 +190,9 @@ class ClassCodegen private constructor(
} }
private val metadataSerializer: MetadataSerializer = private val metadataSerializer: MetadataSerializer =
context.serializerFactory(context, irClass, type, visitor.serializationBindings, parentClassCodegen?.metadataSerializer) context.backendExtension.createSerializer(
context, irClass, type, visitor.serializationBindings, parentClassCodegen?.metadataSerializer
)
private fun generateKotlinMetadataAnnotation() { private fun generateKotlinMetadataAnnotation() {
// TODO: if `-Xmultifile-parts-inherit` is enabled, write the corresponding flag for parts and facades to [Metadata.extraInt]. // TODO: if `-Xmultifile-parts-inherit` is enabled, write the corresponding flag for parts and facades to [Metadata.extraInt].
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.test.backend.ir package org.jetbrains.kotlin.test.backend.ir
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.JvmBackendExtension
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
import org.jetbrains.kotlin.backend.jvm.MetadataSerializerFactory
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.linkage.IrProvider
@@ -25,7 +25,7 @@ data class IrBackendInput(
val phaseConfig: PhaseConfig, val phaseConfig: PhaseConfig,
val irProviders: List<IrProvider>, val irProviders: List<IrProvider>,
val extensions: JvmGeneratorExtensions, val extensions: JvmGeneratorExtensions,
val serializerFactory: MetadataSerializerFactory val backendExtension: JvmBackendExtension,
) : ResultingArtifact.BackendInput<IrBackendInput>() { ) : ResultingArtifact.BackendInput<IrBackendInput>() {
override val kind: BackendKinds.IrBackend override val kind: BackendKinds.IrBackend
get() = BackendKinds.IrBackend get() = BackendKinds.IrBackend
@@ -16,7 +16,7 @@ class JvmIrBackendFacade(
module: TestModule, module: TestModule,
inputArtifact: IrBackendInput inputArtifact: IrBackendInput
): BinaryArtifacts.Jvm { ): BinaryArtifacts.Jvm {
val (state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, serializerFactory) = inputArtifact val (state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension) = inputArtifact
val codegenFactory = state.codegenFactory as JvmIrCodegenFactory val codegenFactory = state.codegenFactory as JvmIrCodegenFactory
codegenFactory.doGenerateFilesInternal( codegenFactory.doGenerateFilesInternal(
@@ -27,7 +27,7 @@ class JvmIrBackendFacade(
phaseConfig, phaseConfig,
irProviders, irProviders,
extensions, extensions,
serializerFactory backendExtension,
) )
state.factory.done() state.factory.done()
@@ -9,11 +9,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.JvmNameProvider
import org.jetbrains.kotlin.backend.jvm.codegen.DescriptorMetadataSerializer
import org.jetbrains.kotlin.backend.jvm.jvmPhases
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.ClassBuilderFactories
@@ -152,7 +148,7 @@ class ClassicFrontend2IrConverter(
phaseConfig, phaseConfig,
irProviders, irProviders,
extensions, extensions,
::DescriptorMetadataSerializer JvmBackendExtension.Default,
) )
} }
} }
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
@@ -89,8 +89,7 @@ class Fir2IrResultsConverter(
phaseConfig, phaseConfig,
irProviders, irProviders,
extensions, extensions,
) { context, irClass, _, serializationBindings, parent -> FirJvmBackendExtension(inputArtifact.session, components)
FirMetadataSerializer(inputArtifact.session, context, irClass, serializationBindings, components, parent) )
}
} }
} }
@@ -42,7 +42,7 @@ import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.createSession import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
@@ -142,10 +142,8 @@ object GenerationUtils {
generationState.beforeCompile() generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode( codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, symbolTable, sourceManager, extensions generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components),
) { context, irClass, _, serializationBindings, parent -> )
FirMetadataSerializer(session, context, irClass, serializationBindings, components, parent)
}
generationState.factory.done() generationState.factory.done()
return generationState return generationState