From 7ea54ee87f0876814c3cf938457b7e9652898fba Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 31 Aug 2023 12:56:55 +0300 Subject: [PATCH] [FIR2IR] Properly compute parent for fake overrides ^KT-61637 --- .../fir/backend/Fir2IrDeclarationStorage.kt | 27 +++++++++---- .../Fir2IrLazyDeclarationsGenerator.kt | 38 ++++++++----------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 8e80ea17cb7..e00544f9327 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -654,7 +654,7 @@ class Fir2IrDeclarationStorage( return fieldStaticOverrideCache[staticFakeOverrideKey]!!.symbol } // In case of type parameters from the parent as the field's return type, find the parent ahead to cache type parameters. - val irParent = findIrParent(fir) + val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag) val unwrapped = fir.unwrapFakeOverrides() if (unwrapped !== fir) { @@ -695,7 +695,7 @@ class Fir2IrDeclarationStorage( return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir) } propertyCache[fir]?.let { return it.backingField!!.symbol } - val irParent = findIrParent(fir) + val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag = null) val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED createAndCacheIrProperty(fir, irParent, predefinedOrigin = parentOrigin).backingField!!.symbol } @@ -906,7 +906,7 @@ class Fir2IrDeclarationStorage( return when (val fir = firFunctionSymbol.fir) { is FirAnonymousFunction -> { getCachedIrFunction(fir)?.let { return it.symbol } - val irParent = findIrParent(fir) + val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag) val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin) createAndCacheIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol @@ -929,7 +929,7 @@ class Fir2IrDeclarationStorage( }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> lazyDeclarationsGenerator.createIrLazyFunction(fir, signature, lazyParent, declarationOrigin).also { - cacheIrFunction(fir, it, fakeOverrideOwnerLookupTag = null) + cacheIrFunction(fir, it, fakeOverrideOwnerLookupTag) } }, ) as IrFunctionSymbol @@ -1019,7 +1019,7 @@ class Fir2IrDeclarationStorage( createIrLazyDeclaration: (signature: IdSignature, lazyOwner: IrDeclarationParent, origin: IrDeclarationOrigin) -> I, ): IrSymbol { val fir = firSymbol.fir as F - val irParent by lazy { findIrParent(fir) } + val irParent by lazy { findIrParent(fir, fakeOverrideOwnerLookupTag) } val signature by lazy { signatureComposer.composeSignature( fir, @@ -1185,11 +1185,24 @@ class Fir2IrDeclarationStorage( return parentPackage } - private fun findIrParent(callableDeclaration: FirCallableDeclaration): IrDeclarationParent? { + private fun findIrParent( + callableDeclaration: FirCallableDeclaration, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, + ): IrDeclarationParent? { val firBasedSymbol = callableDeclaration.symbol val callableId = firBasedSymbol.callableId val callableOrigin = callableDeclaration.origin - return findIrParent(callableId.packageName, callableDeclaration.containingClassLookupTag(), firBasedSymbol, callableOrigin) + val parentLookupTag = when { + // non-static fields can not be fake overrides + firBasedSymbol is FirFieldSymbol && !firBasedSymbol.isStatic -> callableDeclaration.containingClassLookupTag() + else -> fakeOverrideOwnerLookupTag ?: callableDeclaration.containingClassLookupTag() + } + return findIrParent( + callableId.packageName, + parentLookupTag, + firBasedSymbol, + callableOrigin + ) } @OptIn(IrSymbolInternals::class) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt index 79d73ec96ac..3342961e3c1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt @@ -5,24 +5,18 @@ package org.jetbrains.kotlin.fir.backend.generators +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.convertWithOffsets import org.jetbrains.kotlin.fir.backend.irOrigin import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField -import org.jetbrains.kotlin.fir.declarations.FirConstructor -import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction -import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull -import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction -import org.jetbrains.kotlin.fir.originalForSubstitutionOverride import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrPropertyPublicSymbolImpl import org.jetbrains.kotlin.ir.util.IdSignature @@ -38,10 +32,11 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir val symbol = symbolTable.referenceSimpleFunction(signature) val irFunction = fir.convertWithOffsets { startOffset, endOffset -> symbolTable.declareSimpleFunction(signature, { symbol }) { - val isFakeOverride = fir.isSubstitutionOrIntersectionOverride + val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir + val isFakeOverride = fir.isFakeOverride(firContainingClass) Fir2IrLazySimpleFunction( components, startOffset, endOffset, declarationOrigin, - fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride + fir, firContainingClass, symbol, isFakeOverride ).apply { this.parent = lazyParent } @@ -52,7 +47,11 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir return irFunction } - @OptIn(IrSymbolInternals::class) + private fun FirCallableDeclaration.isFakeOverride(firContainingClass: FirRegularClass?): Boolean { + val declaration = unwrapUseSiteSubstitutionOverrides() + return declaration.isSubstitutionOrIntersectionOverride || firContainingClass?.symbol?.toLookupTag() != declaration.containingClassLookupTag() + } + internal fun createIrLazyProperty( fir: FirProperty, signature: IdSignature, @@ -60,16 +59,12 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir declarationOrigin: IrDeclarationOrigin ): IrProperty { val symbol = IrPropertyPublicSymbolImpl(signature) - val firPropertySymbol = fir.symbol - - fun create(startOffset: Int, endOffset: Int): Fir2IrLazyProperty { - val isFakeOverride = - fir.isSubstitutionOrIntersectionOverride && - firPropertySymbol.dispatchReceiverClassLookupTagOrNull() != - firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassLookupTagOrNull() + fun create(startOffset: Int, endOffset: Int, isPropertyForField: Boolean): Fir2IrLazyProperty { + val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir + val isFakeOverride = !isPropertyForField && fir.isFakeOverride(firContainingClass) return Fir2IrLazyProperty( components, startOffset, endOffset, declarationOrigin, - fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride + fir, firContainingClass, symbol, isFakeOverride ).apply { this.parent = lazyParent } @@ -80,11 +75,10 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir // Very special case when two similar properties can exist so conflicts in SymbolTable are possible. // See javaCloseFieldAndKotlinProperty.kt in BB tests symbolTable.declarePropertyWithSignature(signature, symbol) - create(startOffset, endOffset) - symbol.owner + create(startOffset, endOffset, isPropertyForField = true) } else { symbolTable.declareProperty(signature, { symbol }) { - create(startOffset, endOffset) + create(startOffset, endOffset, isPropertyForField = false) } } }