JVM IR: Create package private synthetic multi file part classes

This commit is contained in:
Steven Schäfer
2020-02-07 10:20:46 +01:00
committed by Alexander Udalov
parent 6584df3e01
commit 9db82bfcc8
11 changed files with 16 additions and 10 deletions
@@ -393,7 +393,7 @@ val IrDeclaration.isTopLevel: Boolean
get() { get() {
if (parent is IrPackageFragment) return true if (parent is IrPackageFragment) return true
val parentClass = parent as? IrClass val parentClass = parent as? IrClass
return parentClass?.origin == IrDeclarationOrigin.FILE_CLASS && parentClass.parent is IrPackageFragment return parentClass?.isFileClass == true && parentClass.parent is IrPackageFragment
} }
fun Scope.createTemporaryVariableWithWrappedDescriptor( fun Scope.createTemporaryVariableWithWrappedDescriptor(
@@ -65,7 +65,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
abstract fun getSuperTypeForWrapper(typeOperand: IrType): IrType abstract fun getSuperTypeForWrapper(typeOperand: IrType): IrType
override fun lower(irFile: IrFile) { override fun lower(irFile: IrFile) {
enclosingContainer = irFile.declarations.filterIsInstance<IrClass>().find { it.origin == IrDeclarationOrigin.FILE_CLASS } enclosingContainer = irFile.declarations.filterIsInstance<IrClass>().find { it.isFileClass }
?: irFile ?: irFile
irFile.transformChildrenVoid() irFile.transformChildrenVoid()
@@ -266,7 +266,7 @@ open class ClassCodegen protected constructor(
val entry = irClass.fileParent.fileEntry val entry = irClass.fileParent.fileEntry
if (entry is MultifileFacadeFileEntry) { if (entry is MultifileFacadeFileEntry) {
val partInternalNames = entry.partFiles.mapNotNull { partFile -> val partInternalNames = entry.partFiles.mapNotNull { partFile ->
val fileClass = partFile.declarations.singleOrNull { it.origin == IrDeclarationOrigin.FILE_CLASS } as IrClass? val fileClass = partFile.declarations.singleOrNull { it.isFileClass } as IrClass?
if (fileClass != null) typeMapper.mapClass(fileClass).internalName else null if (fileClass != null) typeMapper.mapClass(fileClass).internalName else null
} }
MultifileClassCodegenImpl.writeMetadata( MultifileClassCodegenImpl.writeMetadata(
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isFileClass
import org.jetbrains.kotlin.lexer.KtSingleValueToken import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -209,7 +210,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
private fun IrFunctionSymbol.toKey(): Key? { private fun IrFunctionSymbol.toKey(): Key? {
val parent = owner.parent val parent = owner.parent
val ownerFqName = when { val ownerFqName = when {
parent is IrClass && parent.origin == IrDeclarationOrigin.FILE_CLASS -> parent is IrClass && parent.isFileClass ->
(parent.parent as IrPackageFragment).fqName (parent.parent as IrPackageFragment).fqName
parent is IrClass -> parent.fqNameWhenAvailable ?: return null parent is IrClass -> parent.fqNameWhenAvailable ?: return null
parent is IrPackageFragment -> parent.fqName parent is IrPackageFragment -> parent.fqName
@@ -374,7 +374,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
// The non-IR backend generates equally meaningless "kotlin/KotlinPackage" in this case (see KT-17151). // The non-IR backend generates equally meaningless "kotlin/KotlinPackage" in this case (see KT-17151).
val kClass = kClassReference((irContainer as? IrClass)?.defaultType ?: context.irBuiltIns.anyNType) val kClass = kClassReference((irContainer as? IrClass)?.defaultType ?: context.irBuiltIns.anyNType)
if ((irContainer as? IrClass)?.origin != IrDeclarationOrigin.FILE_CLASS && irContainer !is IrPackageFragment) if ((irContainer as? IrClass)?.isFileClass != true && irContainer !is IrPackageFragment)
return kClass return kClass
return irCall(context.ir.symbols.getOrCreateKotlinPackage).apply { return irCall(context.ir.symbols.getOrCreateKotlinPackage).apply {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
@@ -96,11 +97,11 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
} }
return IrClassImpl( return IrClassImpl(
0, fileEntry.maxOffset, 0, fileEntry.maxOffset,
IrDeclarationOrigin.FILE_CLASS, if (!fileClassInfo.withJvmMultifileClass) IrDeclarationOrigin.FILE_CLASS else IrDeclarationOrigin.MULTIFILE_PART_CLASS,
symbol = IrClassSymbolImpl(descriptor), symbol = IrClassSymbolImpl(descriptor),
name = fileClassInfo.fileClassFqName.shortName(), name = fileClassInfo.fileClassFqName.shortName(),
kind = ClassKind.CLASS, kind = ClassKind.CLASS,
visibility = Visibilities.PUBLIC, visibility = if (!fileClassInfo.withJvmMultifileClass) Visibilities.PUBLIC else Visibilities.PRIVATE,
modality = Modality.FINAL, modality = Modality.FINAL,
isCompanion = false, isCompanion = false,
isInner = false, isInner = false,
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isFileClass
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
@@ -40,7 +41,7 @@ internal class MainMethodGenerationLowering(val context: JvmBackendContext) : Cl
override fun lower(irClass: IrClass) { override fun lower(irClass: IrClass) {
if (!context.configuration.languageVersionSettings.supportsFeature(LanguageFeature.ExtendedMainConvention)) return if (!context.configuration.languageVersionSettings.supportsFeature(LanguageFeature.ExtendedMainConvention)) return
if (irClass.origin != IrDeclarationOrigin.FILE_CLASS) return if (!irClass.isFileClass) return
val parameterlessMain = irClass.functions.find { it.isParameterlessMainMethod() } ?: return val parameterlessMain = irClass.functions.find { it.isParameterlessMainMethod() } ?: return
@@ -37,6 +37,7 @@ interface IrDeclarationOrigin {
object MOVED_EXTENSION_RECEIVER : IrDeclarationOriginImpl("MOVED_EXTENSION_RECEIVER") object MOVED_EXTENSION_RECEIVER : IrDeclarationOriginImpl("MOVED_EXTENSION_RECEIVER")
object FILE_CLASS : IrDeclarationOriginImpl("FILE_CLASS") object FILE_CLASS : IrDeclarationOriginImpl("FILE_CLASS")
object MULTIFILE_PART_CLASS : IrDeclarationOriginImpl("MULTIFILE_PART_CLASS", isSynthetic = true)
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER") object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER") object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER")
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA") object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
@@ -1069,7 +1069,7 @@ open class WrappedFieldDescriptor(
private fun getContainingDeclaration(declaration: IrDeclarationWithName): DeclarationDescriptor { private fun getContainingDeclaration(declaration: IrDeclarationWithName): DeclarationDescriptor {
val parent = declaration.parent val parent = declaration.parent
val parentDescriptor = (parent as IrSymbolOwner).symbol.descriptor val parentDescriptor = (parent as IrSymbolOwner).symbol.descriptor
return if (parent is IrClass && parent.origin == IrDeclarationOrigin.FILE_CLASS) { return if (parent is IrClass && parent.isFileClass) {
// JVM IR adds facade classes for IR of functions/properties loaded both from sources and dependencies. However, these shouldn't // JVM IR adds facade classes for IR of functions/properties loaded both from sources and dependencies. However, these shouldn't
// exist in the descriptor hierarchy, since this is what the old backend (dealing with descriptors) expects. // exist in the descriptor hierarchy, since this is what the old backend (dealing with descriptors) expects.
parentDescriptor.containingDeclaration!! parentDescriptor.containingDeclaration!!
@@ -670,3 +670,6 @@ fun SymbolTable.findOrDeclareExternalPackageFragment(descriptor: PackageFragment
declareExternalPackageFragment(descriptor) declareExternalPackageFragment(descriptor)
} }
}.owner }.owner
val IrDeclaration.isFileClass: Boolean
get() = origin == IrDeclarationOrigin.FILE_CLASS || origin == IrDeclarationOrigin.MULTIFILE_PART_CLASS
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
@file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("Test") @file:kotlin.jvm.JvmName("Test")