From 989d4350b14d0100e60c635245103d4d8018f0db Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Fri, 27 Nov 2020 17:31:03 +0300 Subject: [PATCH] IR: make descriptor optional in IrSymbol --- .../ir/descriptors/IrBasedDescriptors.kt | 29 +++++++++++++++---- .../ir/symbols/impl/IrPrivateSymbolBase.kt | 9 +++++- .../ir/symbols/impl/IrPublicSymbolBase.kt | 11 +++++-- .../kotlin/ir/util/DescriptorsToIrRemapper.kt | 16 +++++----- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt index 0fc45178264..e8f71236372 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt @@ -14,9 +14,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol -import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name @@ -34,7 +32,8 @@ import org.jetbrains.kotlin.types.* /* Descriptors that serve purely as a view into IR structures. Created each time at the borderline between IR-based and descriptor-based code (such as inliner). - Compared to WrappedDescriptors, no method calls ever return true descriptors. + Compared to WrappedDescriptors, no method calls ever return true descriptors, except when + unbound symbols are encountered (see `Ir...Symbol.toIrBasedDescriptorIfPossible()`). */ abstract class IrBasedDeclarationDescriptor(val owner: T) : DeclarationDescriptor { @@ -108,6 +107,7 @@ fun IrDeclaration.toIrBasedDescriptor(): DeclarationDescriptor = when (this) { is IrLocalDelegatedProperty -> toIrBasedDescriptor() is IrFunction -> toIrBasedDescriptor() is IrClass -> toIrBasedDescriptor() + is IrAnonymousInitializer -> parentAsClass.toIrBasedDescriptor() is IrEnumEntry -> toIrBasedDescriptor() is IrProperty -> toIrBasedDescriptor() is IrField -> toIrBasedDescriptor() @@ -1060,9 +1060,9 @@ private fun makeKotlinType( hasQuestionMark: Boolean ): SimpleType = when (classifier) { - is IrTypeParameterSymbol -> classifier.owner.toIrBasedDescriptor().defaultType + is IrTypeParameterSymbol -> classifier.toIrBasedDescriptorIfPossible().defaultType is IrClassSymbol -> { - val classDescriptor = classifier.owner.toIrBasedDescriptor() + val classDescriptor = classifier.toIrBasedDescriptorIfPossible() val kotlinTypeArguments = arguments.mapIndexed { index, it -> when (it) { is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toIrBasedKotlinType()) @@ -1094,3 +1094,20 @@ private fun makeKotlinType( } else -> error("unknown classifier kind $classifier") } + +/* When IR-based descriptors are used from Psi2Ir, symbols may be unbound, thus we may need to resort to real descriptors. */ +@OptIn(ObsoleteDescriptorBasedAPI::class) +private fun IrClassSymbol.toIrBasedDescriptorIfPossible(): ClassDescriptor = + if (isBound) owner.toIrBasedDescriptor() else descriptor + +@OptIn(ObsoleteDescriptorBasedAPI::class) +private fun IrTypeParameterSymbol.toIrBasedDescriptorIfPossible(): TypeParameterDescriptor = + if (isBound) owner.toIrBasedDescriptor() else descriptor + +@OptIn(ObsoleteDescriptorBasedAPI::class) +private fun IrSimpleFunctionSymbol.toIrBasedDescriptorIfPossible(): FunctionDescriptor = + if (isBound) owner.toIrBasedDescriptor() else descriptor + +@OptIn(ObsoleteDescriptorBasedAPI::class) +private fun IrPropertySymbol.toIrBasedDescriptorIfPossible(): PropertyDescriptor = + if (isBound) owner.toIrBasedDescriptor() else descriptor \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPrivateSymbolBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPrivateSymbolBase.kt index 1edb264ed7e..3523b6f5e8f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPrivateSymbolBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPrivateSymbolBase.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor +import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.IdSignature @@ -27,9 +28,15 @@ import org.jetbrains.kotlin.ir.util.render @OptIn(ObsoleteDescriptorBasedAPI::class) abstract class IrSymbolBase( + private val _descriptor: D +) : IrSymbol { @ObsoleteDescriptorBasedAPI override val descriptor: D -) : IrSymbol { + get() = if (isBound && _descriptor is WrappedDeclarationDescriptor<*>) + (owner as IrDeclaration).toIrBasedDescriptor() as D + else + _descriptor + override fun toString(): String { if (isBound) return owner.render() return "Unbound private symbol ${super.toString()}" diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPublicSymbolBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPublicSymbolBase.kt index db54edf7a70..fed78f2bd98 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPublicSymbolBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrPublicSymbolBase.kt @@ -9,15 +9,22 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor +import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.render abstract class IrPublicSymbolBase @OptIn(ObsoleteDescriptorBasedAPI::class) constructor( - @ObsoleteDescriptorBasedAPI - override val descriptor: D, + private val _descriptor: D, override val signature: IdSignature ) : IrSymbol { + @ObsoleteDescriptorBasedAPI + override val descriptor: D + get() = if (isBound && _descriptor is WrappedDeclarationDescriptor<*>) + (owner as IrDeclaration).toIrBasedDescriptor() as D + else + _descriptor + override fun toString(): String { if (isBound) return owner.render() return "Unbound public symbol for $signature" diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorsToIrRemapper.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorsToIrRemapper.kt index 8a2299dbbf5..9f8c5ecda0d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorsToIrRemapper.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorsToIrRemapper.kt @@ -58,34 +58,34 @@ object WrappedDescriptorPatcher : IrElementVisitorVoid { } override fun visitClass(declaration: IrClass) { - (declaration.descriptor as WrappedClassDescriptor).bind(declaration) + (declaration.descriptor as? WrappedClassDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } override fun visitConstructor(declaration: IrConstructor) { - (declaration.descriptor as WrappedClassConstructorDescriptor).bind(declaration) + (declaration.descriptor as? WrappedClassConstructorDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } override fun visitEnumEntry(declaration: IrEnumEntry) { - (declaration.descriptor as WrappedClassDescriptor).bind( + (declaration.descriptor as? WrappedClassDescriptor)?.bind( declaration.correspondingClass ?: declaration.parentAsClass ) declaration.acceptChildrenVoid(this) } override fun visitField(declaration: IrField) { - (declaration.descriptor as WrappedFieldDescriptor).bind(declaration) + (declaration.descriptor as? WrappedFieldDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } override fun visitProperty(declaration: IrProperty) { - (declaration.descriptor as WrappedPropertyDescriptor).bind(declaration) + (declaration.descriptor as? WrappedPropertyDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } override fun visitFunction(declaration: IrFunction) { - (declaration.descriptor as WrappedSimpleFunctionDescriptor).bind(declaration as IrSimpleFunction) + (declaration.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(declaration as IrSimpleFunction) declaration.acceptChildrenVoid(this) } @@ -96,12 +96,12 @@ object WrappedDescriptorPatcher : IrElementVisitorVoid { } override fun visitTypeParameter(declaration: IrTypeParameter) { - (declaration.descriptor as WrappedTypeParameterDescriptor).bind(declaration) + (declaration.descriptor as? WrappedTypeParameterDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } override fun visitVariable(declaration: IrVariable) { - (declaration.descriptor as WrappedVariableDescriptor).bind(declaration) + (declaration.descriptor as? WrappedVariableDescriptor)?.bind(declaration) declaration.acceptChildrenVoid(this) } }