JVM_IR: remember facade fqnames of imported classes

Necessary to support importing file classes annotated @JvmPackageName,
since the actual package fragment they are a part of has the name from
the `package` declaration.
This commit is contained in:
pyos
2019-11-08 10:13:54 +01:00
committed by Alexander Udalov
parent 42cb53a380
commit 433e0e4740
10 changed files with 28 additions and 36 deletions
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -87,6 +86,10 @@ class JvmBackendContext(
internal val localDelegatedProperties = mutableMapOf<IrClass, List<IrLocalDelegatedPropertySymbol>>()
// 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.
internal lateinit var classNameOverride: MutableMap<IrClass, JvmClassName>
internal val multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
internal val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
internal val multifileFacadeMemberToPartMember = mutableMapOf<IrFunctionSymbol, IrFunctionSymbol>()
@@ -24,7 +24,7 @@ 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.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -35,22 +35,12 @@ object JvmBackendFacade {
errorHandler: CompilationErrorHandler,
phaseConfig: PhaseConfig
) {
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, facadeClassGenerator = ::facadeClassGenerator)
val facadeGenerator = FacadeClassGenerator()
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, facadeClassGenerator = facadeGenerator::generate)
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
doGenerateFilesInternal(state, errorHandler, irModuleFragment, psi2irContext, phaseConfig)
}
internal fun doGenerateFilesInternal(
state: GenerationState,
errorHandler: CompilationErrorHandler,
irModuleFragment: IrModuleFragment,
psi2irContext: GeneratorContext,
phaseConfig: PhaseConfig
) {
doGenerateFilesInternal(
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, facadeGenerator
)
}
@@ -60,7 +50,8 @@ object JvmBackendFacade {
irModuleFragment: IrModuleFragment,
symbolTable: SymbolTable,
sourceManager: PsiSourceManager,
phaseConfig: PhaseConfig
phaseConfig: PhaseConfig,
facadeGenerator: FacadeClassGenerator = FacadeClassGenerator()
) {
val context = JvmBackendContext(
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig
@@ -77,8 +68,9 @@ object JvmBackendFacade {
symbolTable,
irModuleFragment.irBuiltins,
JvmGeneratorExtensions.externalDeclarationOrigin,
facadeClassGenerator = ::facadeClassGenerator
facadeClassGenerator = facadeGenerator::generate
).generateUnboundSymbolsAsDependencies()
context.classNameOverride = facadeGenerator.classNameOverride
for (irFile in irModuleFragment.files) {
for (extension in IrGenerationExtension.getInstances(context.state.project)) {
@@ -116,14 +108,19 @@ 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()
internal class FacadeClassGenerator {
val classNameOverride = mutableMapOf<IrClass, JvmClassName>()
fun generate(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()
classNameOverride[it] = facadeName
}
}
}
}
@@ -24,16 +24,12 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
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, 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)
JvmBackendFacade.doGenerateFiles(files, state, errorHandler, phaseConfig)
}
fun generateModuleInFrontendIRMode(
@@ -51,6 +51,7 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
fun classInternalName(irClass: IrClass): String {
context.getLocalClassInfo(irClass)?.internalName?.let { return it }
context.classNameOverride[irClass]?.let { return it.internalName }
val className = SpecialNames.safeIdentifier(irClass.name).identifier
val internalName = when (val parent = irClass.parent) {
is IrPackageFragment -> {
@@ -112,6 +112,7 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
if (fileClassInfo.withJvmMultifileClass) AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.facadeClassFqName)
else null
context.state.factory.packagePartRegistry.addPart(irFile.fqName, partClassType.internalName, facadeClassType?.internalName)
context.classNameOverride[this] = JvmClassName.byInternalName(partClassType.internalName)
if (facadeClassType != null) {
val jvmClassName = JvmClassName.byInternalName(facadeClassType.internalName)
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: 1.kt
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: A.kt
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: A.kt
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: A.kt