[FIR2IR] Remove incorrect usages of Fir2IrDeclarationStorage.getOrCreateIrFunction
`getOrCreateXxx` methods have not very safe semantics: they sometimes create an IR declaration if it was missing in caches before. For all source declarations, this is not very good semantic, because we have strict rules in which order source declarations should be created, and usage of `getOrCreateXxx` may break this order. So it's important to be able to track all invocations of such methods to ensure that it's appropriate in each case. To achieve that, a new `@GetOrCreateSensitiveAPI ` opt-in is introduced
This commit is contained in:
committed by
Space Team
parent
af6b71ca2d
commit
bced604b57
@@ -458,6 +458,9 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function creates IR declarations for callable members without filling their body
|
||||||
|
*/
|
||||||
private fun processMemberDeclaration(
|
private fun processMemberDeclaration(
|
||||||
declaration: FirDeclaration,
|
declaration: FirDeclaration,
|
||||||
containingClass: FirClass?,
|
containingClass: FirClass?,
|
||||||
@@ -508,7 +511,7 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirSimpleFunction -> {
|
is FirSimpleFunction -> {
|
||||||
declarationStorage.getOrCreateIrFunction(declaration, parent, isLocal = isInLocalClass)
|
declarationStorage.createAndCacheIrFunction(declaration, parent, isLocal = isInLocalClass)
|
||||||
}
|
}
|
||||||
is FirProperty -> {
|
is FirProperty -> {
|
||||||
if (
|
if (
|
||||||
|
|||||||
+10
-1
@@ -269,6 +269,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
return cachedIrCallable
|
return cachedIrCallable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetOrCreateSensitiveAPI
|
||||||
fun getOrCreateIrFunction(
|
fun getOrCreateIrFunction(
|
||||||
function: FirFunction,
|
function: FirFunction,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
@@ -279,6 +280,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
return getOrCreateIrFunction(function, { irParent }, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
return getOrCreateIrFunction(function, { irParent }, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetOrCreateSensitiveAPI
|
||||||
private fun getOrCreateIrFunction(
|
private fun getOrCreateIrFunction(
|
||||||
function: FirFunction,
|
function: FirFunction,
|
||||||
irParent: () -> IrDeclarationParent?,
|
irParent: () -> IrDeclarationParent?,
|
||||||
@@ -301,7 +303,6 @@ class Fir2IrDeclarationStorage(
|
|||||||
return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@LeakedDeclarationCaches
|
|
||||||
fun createAndCacheIrFunction(
|
fun createAndCacheIrFunction(
|
||||||
function: FirFunction,
|
function: FirFunction,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
@@ -874,6 +875,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
getIrConstructorSymbol(fir.symbol)
|
getIrConstructorSymbol(fir.symbol)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
getOrCreateIrFunction(
|
getOrCreateIrFunction(
|
||||||
fir,
|
fir,
|
||||||
{ findIrParent(fir, fakeOverrideOwnerLookupTag) },
|
{ findIrParent(fir, fakeOverrideOwnerLookupTag) },
|
||||||
@@ -1177,6 +1179,13 @@ internal var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationD
|
|||||||
@RequiresOptIn
|
@RequiresOptIn
|
||||||
annotation class LeakedDeclarationCaches
|
annotation class LeakedDeclarationCaches
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation indicates that an annotated method can create a declaration in ad-hock way, so it should be used with caution
|
||||||
|
* In most cases, it's recommended to use method which return symbol or which forcefully creates a declaration
|
||||||
|
*/
|
||||||
|
@RequiresOptIn
|
||||||
|
annotation class GetOrCreateSensitiveAPI
|
||||||
|
|
||||||
@OptIn(UnsafeDuringIrConstructionAPI::class)
|
@OptIn(UnsafeDuringIrConstructionAPI::class)
|
||||||
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
|
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
|
||||||
return runIf(isBound) { owner }
|
return runIf(isBound) { owner }
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(session, simpleFunction) {
|
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(session, simpleFunction) {
|
||||||
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
|
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
|
||||||
declarationStorage.getOrCreateIrFunction(
|
declarationStorage.createAndCacheIrFunction(
|
||||||
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
|
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -424,7 +424,7 @@ class Fir2IrVisitor(
|
|||||||
data: Any?
|
data: Any?
|
||||||
): IrElement = whileAnalysing(session, anonymousFunction) {
|
): IrElement = whileAnalysing(session, anonymousFunction) {
|
||||||
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
|
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
|
||||||
val irFunction = declarationStorage.getOrCreateIrFunction(
|
val irFunction = declarationStorage.createAndCacheIrFunction(
|
||||||
anonymousFunction,
|
anonymousFunction,
|
||||||
irParent = conversionScope.parent(),
|
irParent = conversionScope.parent(),
|
||||||
predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION,
|
predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION,
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
|
|||||||
}
|
}
|
||||||
SymbolKind.FUNCTION_SYMBOL -> {
|
SymbolKind.FUNCTION_SYMBOL -> {
|
||||||
val firSimpleFunction = firDeclaration as FirSimpleFunction
|
val firSimpleFunction = firDeclaration as FirSimpleFunction
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
declarationStorage.getOrCreateIrFunction(firSimpleFunction, parent)
|
declarationStorage.getOrCreateIrFunction(firSimpleFunction, parent)
|
||||||
}
|
}
|
||||||
SymbolKind.PROPERTY_SYMBOL -> {
|
SymbolKind.PROPERTY_SYMBOL -> {
|
||||||
|
|||||||
@@ -698,6 +698,7 @@ class IrBuiltInsOverFir(
|
|||||||
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
||||||
|
|
||||||
val irParent = findIrParent(functionSymbol)
|
val irParent = findIrParent(functionSymbol)
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
|
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -214,7 +214,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
firSubClass: FirClass,
|
firSubClass: FirClass,
|
||||||
delegateOverride: FirSimpleFunction
|
delegateOverride: FirSimpleFunction
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
val delegateFunction = declarationStorage.getOrCreateIrFunction(
|
val delegateFunction = declarationStorage.createAndCacheIrFunction(
|
||||||
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
|
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||||
fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
|
fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ class Fir2IrLazyClass(
|
|||||||
symbol.containingClassLookupTag() != ownerLookupTag -> {}
|
symbol.containingClassLookupTag() != ownerLookupTag -> {}
|
||||||
symbol.isAbstractMethodOfAny() -> {}
|
symbol.isAbstractMethodOfAny() -> {}
|
||||||
else -> {
|
else -> {
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
result += declarationStorage.getOrCreateIrFunction(symbol.fir, this, origin)
|
result += declarationStorage.getOrCreateIrFunction(symbol.fir, this, origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ class Fir2IrLazyPropertyAccessor(
|
|||||||
|
|
||||||
override val initialSignatureFunction: IrFunction? by lazy {
|
override val initialSignatureFunction: IrFunction? by lazy {
|
||||||
val originalFirFunction = (fir as? FirSyntheticPropertyAccessor)?.delegate ?: return@lazy null
|
val originalFirFunction = (fir as? FirSyntheticPropertyAccessor)?.delegate ?: return@lazy null
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
declarationStorage.getOrCreateIrFunction(originalFirFunction, parent)
|
declarationStorage.getOrCreateIrFunction(originalFirFunction, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.lazy
|
package org.jetbrains.kotlin.fir.lazy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
|
import org.jetbrains.kotlin.fir.backend.GetOrCreateSensitiveAPI
|
||||||
import org.jetbrains.kotlin.fir.backend.contextReceiversForFunctionOrContainingProperty
|
import org.jetbrains.kotlin.fir.backend.contextReceiversForFunctionOrContainingProperty
|
||||||
import org.jetbrains.kotlin.fir.backend.generators.Fir2IrCallableDeclarationsGenerator
|
import org.jetbrains.kotlin.fir.backend.generators.Fir2IrCallableDeclarationsGenerator
|
||||||
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenFunctionSymbols
|
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenFunctionSymbols
|
||||||
@@ -110,6 +111,7 @@ class Fir2IrLazySimpleFunction(
|
|||||||
|
|
||||||
override val initialSignatureFunction: IrFunction? by lazy {
|
override val initialSignatureFunction: IrFunction? by lazy {
|
||||||
val originalFunction = fir.initialSignatureAttr as? FirFunction ?: return@lazy null
|
val originalFunction = fir.initialSignatureAttr as? FirFunction ?: return@lazy null
|
||||||
|
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||||
declarationStorage.getOrCreateIrFunction(originalFunction, parent).also {
|
declarationStorage.getOrCreateIrFunction(originalFunction, parent).also {
|
||||||
check(it !== this) { "Initial function can not be the same as remapped function" }
|
check(it !== this) { "Initial function can not be the same as remapped function" }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user