From fa3e9c615ba8677e469812f37a23fe8cb3bcedb4 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 21 Aug 2023 12:48:02 +0300 Subject: [PATCH] [FIR2IR] Get rid of all usages of IrSymbol.owner from ConversionUtils ^KT-60924 --- .../kotlin/fir/backend/ConversionUtils.kt | 28 +++++++------------ .../fir/backend/Fir2IrConversionScope.kt | 16 ++++++++--- .../kotlin/fir/backend/Fir2IrVisitor.kt | 3 +- .../backend/generators/AdapterGenerator.kt | 20 ++++++++++++- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 3d13b76469d..5e3ff75cd2e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -16,11 +16,13 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.ValueClassRepresentation import org.jetbrains.kotlin.diagnostics.startOffsetSkippingComments import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.backend.unsubstitutedScope import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer import org.jetbrains.kotlin.fir.builder.buildPackageDirective import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildFile import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty +import org.jetbrains.kotlin.fir.declarations.utils.isAbstract import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isJava import org.jetbrains.kotlin.fir.declarations.utils.isStatic @@ -39,11 +41,8 @@ import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider -import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope -import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -187,7 +186,6 @@ private fun FirBasedSymbol<*>.toSymbolForCall( } context(Fir2IrComponents) -@OptIn(IrSymbolInternals::class) fun FirReference.toSymbolForCall( dispatchReceiver: FirExpression, conversionScope: Fir2IrConversionScope, @@ -215,11 +213,14 @@ fun FirReference.toSymbolForCall( is FirThisReference -> { when (val boundSymbol = boundSymbol) { - is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol - is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner.extensionReceiverParameter?.symbol + is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol) + is FirFunctionSymbol -> { + val firClassSymbol = boundSymbol.receiverParameter?.typeRef?.coneType?.toRegularClassSymbol(session) + firClassSymbol?.let { classifierStorage.getIrClassSymbol(it) } + } is FirPropertySymbol -> { - val property = declarationStorage.getIrPropertySymbol(boundSymbol).owner as? IrProperty - property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) }?.symbol + val propertySymbol = declarationStorage.getIrPropertySymbol(boundSymbol) as? IrPropertySymbol + propertySymbol?.let { conversionScope.parentAccessorOfPropertyFromStack(it).symbol } } is FirScriptSymbol -> declarationStorage.getCachedIrScript(boundSymbol.fir)?.thisReceiver?.symbol else -> null @@ -561,15 +562,6 @@ fun FirClass.irOrigin(firProvider: FirProvider): IrDeclarationOrigin = when { } } -@OptIn(IrSymbolInternals::class) -val IrType.isSamType: Boolean - get() { - val irClass = classOrNull ?: return false - if (irClass.owner.kind != ClassKind.INTERFACE) return false - val am = irClass.functions.singleOrNull { it.owner.modality == Modality.ABSTRACT } - return am != null - } - fun Fir2IrComponents.createSafeCallConstruction( receiverVariable: IrVariable, receiverVariableSymbol: IrValueSymbol, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index a8355f0f714..a291dff59cc 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -11,8 +11,11 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.util.isSetter import org.jetbrains.kotlin.ir.util.parentClassOrNull +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.util.PrivateForInline @OptIn(PrivateForInline::class) @@ -63,14 +66,19 @@ class Fir2IrConversionScope { fun parentFromStack(): IrDeclarationParent = parentStack.last() - fun parentAccessorOfPropertyFromStack(property: IrProperty): IrSimpleFunction? { + fun parentAccessorOfPropertyFromStack(propertySymbol: IrPropertySymbol): IrSimpleFunction { + // It is safe to access an owner of property symbol here, because this function may be called + // only from property accessor of corresponding property + // We inside accessor -> accessor is built -> property is built + @OptIn(IrSymbolInternals::class) + val property = propertySymbol.owner for (parent in parentStack.asReversed()) { when (parent) { - property.getter -> return property.getter - property.setter -> return property.setter + property.getter -> return parent as IrSimpleFunction + property.setter -> return parent as IrSimpleFunction } } - return null + error("Accessor of property ${property.render()} not found on parent stack") } fun applyParentFromStackTo(declaration: T): T { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index a79560997c6..563e8a2601a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* @@ -741,7 +742,7 @@ class Fir2IrVisitor( val irFunction = when (boundSymbol) { is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner is FirPropertySymbol -> { - val property = declarationStorage.getIrPropertySymbol(boundSymbol).owner as? IrProperty + val property = declarationStorage.getIrPropertySymbol(boundSymbol) as? IrPropertySymbol property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) } } else -> null diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index d7e20ade57b..d8376e1e96e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.backend.generators +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.backend.* @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve +import org.jetbrains.kotlin.fir.scopes.processAllCallables import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol @@ -36,6 +38,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* @@ -446,9 +449,9 @@ internal class AdapterGenerator( } val samFirType = substitutedParameterType.removeExternalProjections() ?: substitutedParameterType + if (!samFirType.isSamType) return this val samType = samFirType.toIrType(ConversionTypeOrigin.DEFAULT) // Make sure the converted IrType owner indeed has a single abstract method, since FunctionReferenceLowering relies on it. - if (!samType.isSamType) return this return IrTypeOperatorCallImpl( this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, castArgumentToFunctionalInterfaceForSamType(this, argument.resolvedType, samFirType) @@ -836,4 +839,19 @@ internal class AdapterGenerator( irAdapterFunction.parent = conversionScope.parent()!! } } + + context(Fir2IrComponents) + private val ConeKotlinType.isSamType: Boolean + get() { + val classSymbol = this.lowerBoundIfFlexible().toRegularClassSymbol(session) ?: return false + if (!classSymbol.isInterface) return false + val scope = classSymbol.unsubstitutedScope() + var abstractNumber = 0 + scope.processAllCallables { + if (it.isAbstract) { + abstractNumber++ + } + } + return abstractNumber == 1 + } }