[FIR2IR] Properly compute parent for fake overrides

^KT-61637
This commit is contained in:
Dmitriy Novozhilov
2023-08-31 12:56:55 +03:00
committed by Space Team
parent 954ef58d35
commit 7ea54ee87f
2 changed files with 36 additions and 29 deletions
@@ -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)
@@ -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)
}
}
}