JVM_IR: generate facade classes for imported toplevel declarations
This commit is contained in:
@@ -5,16 +5,23 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object JvmBackendFacade {
|
||||
fun doGenerateFiles(
|
||||
@@ -23,7 +30,7 @@ object JvmBackendFacade {
|
||||
errorHandler: CompilationErrorHandler,
|
||||
phaseConfig: PhaseConfig
|
||||
) {
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings)
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, facadeClassGenerator = ::facadeClassGenerator)
|
||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
|
||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
|
||||
|
||||
@@ -59,7 +66,8 @@ object JvmBackendFacade {
|
||||
irModuleFragment.descriptor,
|
||||
symbolTable,
|
||||
irModuleFragment.irBuiltins,
|
||||
JvmGeneratorExtensions.externalDeclarationOrigin
|
||||
JvmGeneratorExtensions.externalDeclarationOrigin,
|
||||
facadeClassGenerator = ::facadeClassGenerator
|
||||
).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
val jvmBackend = JvmBackend(jvmBackendContext)
|
||||
@@ -81,4 +89,15 @@ object JvmBackendFacade {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun facadeClassGenerator(source: DeserializedContainerSource): IrClass? {
|
||||
val jvmPackagePartSource = source.safeAs<JvmPackagePartSource>() ?: return null
|
||||
val facadeName = jvmPackagePartSource.facadeClassName ?: jvmPackagePartSource.className
|
||||
return buildClass {
|
||||
origin = IrDeclarationOrigin.FILE_CLASS
|
||||
name = facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName()
|
||||
}.also {
|
||||
it.createParameterDeclarations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory {
|
||||
|
||||
override fun generateModule(state: GenerationState, files: Collection<KtFile>, errorHandler: CompilationErrorHandler) {
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings)
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, facadeClassGenerator = JvmBackendFacade::facadeClassGenerator)
|
||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
|
||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
|
||||
JvmBackendFacade.doGenerateFilesInternal(state, errorHandler, irModuleFragment, psi2irContext, phaseConfig)
|
||||
|
||||
+10
-5
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -209,8 +206,16 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
private val EQUALS = Equals(KtTokens.EQEQ)
|
||||
|
||||
private fun IrFunctionSymbol.toKey(): Key? {
|
||||
val parent = owner.parent
|
||||
val ownerFqName = when {
|
||||
parent is IrClass && parent.origin == IrDeclarationOrigin.FILE_CLASS ->
|
||||
(parent.parent as IrPackageFragment).fqName
|
||||
parent is IrClass -> parent.fqNameWhenAvailable ?: return null
|
||||
parent is IrPackageFragment -> parent.fqName
|
||||
else -> return null
|
||||
}
|
||||
return Key(
|
||||
owner.parent.safeAs<IrClass>()?.fqNameWhenAvailable ?: owner.parent.safeAs<IrPackageFragment>()?.fqName ?: return null,
|
||||
ownerFqName,
|
||||
getParameterFqName(owner.extensionReceiverParameter),
|
||||
owner.name.asString(),
|
||||
owner.valueParameters.map(::getParameterFqName)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
@@ -31,11 +32,13 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class Psi2IrTranslator(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration()
|
||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration(),
|
||||
val facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
|
||||
) {
|
||||
interface PostprocessingStep {
|
||||
fun postprocess(context: GeneratorContext, irElement: IrElement)
|
||||
@@ -78,7 +81,7 @@ class Psi2IrTranslator(
|
||||
irModule.patchDeclarationParents()
|
||||
|
||||
postprocess(context, irModule)
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer)
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, facadeClassGenerator)
|
||||
return irModule
|
||||
}
|
||||
|
||||
|
||||
+13
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.MetadataSource
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
@@ -43,9 +45,18 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
irModule.files.addAll(generateFiles(ktFiles))
|
||||
}
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment, deserializer: IrDeserializer? = null) {
|
||||
fun generateUnboundSymbolsAsDependencies(
|
||||
irModule: IrModuleFragment,
|
||||
deserializer: IrDeserializer? = null,
|
||||
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
|
||||
) {
|
||||
ExternalDependenciesGenerator(
|
||||
irModule.descriptor, context.symbolTable, context.irBuiltIns, context.extensions.externalDeclarationOrigin, deserializer
|
||||
irModule.descriptor,
|
||||
context.symbolTable,
|
||||
context.irBuiltIns,
|
||||
context.extensions.externalDeclarationOrigin,
|
||||
deserializer,
|
||||
facadeClassGenerator
|
||||
).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -7,13 +7,9 @@ package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
@@ -68,8 +64,12 @@ abstract class IrLazyDeclarationBase(
|
||||
((currentDescriptor as? PropertyAccessorDescriptor)?.correspondingProperty ?: currentDescriptor).containingDeclaration
|
||||
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(containingDeclaration).also {
|
||||
it.declarations.add(this)
|
||||
is PackageFragmentDescriptor -> run {
|
||||
val parent = this.takeUnless { it is IrClass }?.let {
|
||||
stubGenerator.generateOrGetFacadeClass(descriptor)
|
||||
} ?: stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(containingDeclaration)
|
||||
parent.declarations.add(this)
|
||||
parent
|
||||
}
|
||||
is ClassDescriptor -> stubGenerator.generateClassStub(containingDeclaration)
|
||||
is FunctionDescriptor -> stubGenerator.generateFunctionStub(containingDeclaration)
|
||||
|
||||
@@ -26,14 +26,18 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class DeclarationStubGenerator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
val symbolTable: SymbolTable,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
private val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
|
||||
private val deserializer: IrDeserializer? = null
|
||||
private val deserializer: IrDeserializer? = null,
|
||||
private val facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
|
||||
) {
|
||||
private val lazyTable = symbolTable.lazyWrapper
|
||||
|
||||
@@ -47,6 +51,8 @@ class DeclarationStubGenerator(
|
||||
private val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable)
|
||||
|
||||
private val facadeClassMap = mutableMapOf<DeserializedContainerSource, IrClass?>()
|
||||
|
||||
init {
|
||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||
constantValueGenerator.typeTranslator = typeTranslator
|
||||
@@ -60,6 +66,19 @@ class DeclarationStubGenerator(
|
||||
return symbolTable.declareExternalPackageFragment(descriptor)
|
||||
}
|
||||
|
||||
fun generateOrGetFacadeClass(descriptor: DeclarationDescriptor): IrClass? {
|
||||
val packageFragment = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return null
|
||||
val containerSource = descriptor.safeAs<DescriptorWithContainerSource>()?.containerSource ?: return null
|
||||
return facadeClassMap.getOrPut(containerSource) {
|
||||
facadeClassGenerator(containerSource)?.also { facade ->
|
||||
val packageStub = generateOrGetEmptyExternalPackageFragmentStub(packageFragment)
|
||||
facade.parent = packageStub
|
||||
packageStub.declarations.add(facade)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun generateMemberStub(descriptor: DeclarationDescriptor): IrDeclaration =
|
||||
when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
|
||||
+5
-2
@@ -18,9 +18,11 @@ package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import kotlin.math.min
|
||||
|
||||
class ExternalDependenciesGenerator(
|
||||
@@ -28,10 +30,11 @@ class ExternalDependenciesGenerator(
|
||||
val symbolTable: SymbolTable,
|
||||
val irBuiltIns: IrBuiltIns,
|
||||
externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
|
||||
private val deserializer: IrDeserializer? = null
|
||||
private val deserializer: IrDeserializer? = null,
|
||||
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
|
||||
) {
|
||||
private val stubGenerator = DeclarationStubGenerator(
|
||||
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, externalDeclarationOrigin, deserializer
|
||||
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, externalDeclarationOrigin, deserializer, facadeClassGenerator
|
||||
)
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies() {
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// TODO: muted automatically, investigate should it be ran for JVM_IR or not
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// TODO: muted automatically, investigate should it be ran for JVM_IR or not
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
Reference in New Issue
Block a user