[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(
|
||||
declaration: FirDeclaration,
|
||||
containingClass: FirClass?,
|
||||
@@ -508,7 +511,7 @@ class Fir2IrConverter(
|
||||
}
|
||||
}
|
||||
is FirSimpleFunction -> {
|
||||
declarationStorage.getOrCreateIrFunction(declaration, parent, isLocal = isInLocalClass)
|
||||
declarationStorage.createAndCacheIrFunction(declaration, parent, isLocal = isInLocalClass)
|
||||
}
|
||||
is FirProperty -> {
|
||||
if (
|
||||
|
||||
+10
-1
@@ -269,6 +269,7 @@ class Fir2IrDeclarationStorage(
|
||||
return cachedIrCallable
|
||||
}
|
||||
|
||||
@GetOrCreateSensitiveAPI
|
||||
fun getOrCreateIrFunction(
|
||||
function: FirFunction,
|
||||
irParent: IrDeclarationParent?,
|
||||
@@ -279,6 +280,7 @@ class Fir2IrDeclarationStorage(
|
||||
return getOrCreateIrFunction(function, { irParent }, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
||||
}
|
||||
|
||||
@GetOrCreateSensitiveAPI
|
||||
private fun getOrCreateIrFunction(
|
||||
function: FirFunction,
|
||||
irParent: () -> IrDeclarationParent?,
|
||||
@@ -301,7 +303,6 @@ class Fir2IrDeclarationStorage(
|
||||
return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
|
||||
}
|
||||
|
||||
@LeakedDeclarationCaches
|
||||
fun createAndCacheIrFunction(
|
||||
function: FirFunction,
|
||||
irParent: IrDeclarationParent?,
|
||||
@@ -874,6 +875,7 @@ class Fir2IrDeclarationStorage(
|
||||
getIrConstructorSymbol(fir.symbol)
|
||||
}
|
||||
else -> {
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
getOrCreateIrFunction(
|
||||
fir,
|
||||
{ findIrParent(fir, fakeOverrideOwnerLookupTag) },
|
||||
@@ -1177,6 +1179,13 @@ internal var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationD
|
||||
@RequiresOptIn
|
||||
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)
|
||||
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
|
||||
return runIf(isBound) { owner }
|
||||
|
||||
@@ -401,7 +401,7 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(session, simpleFunction) {
|
||||
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
|
||||
declarationStorage.getOrCreateIrFunction(
|
||||
declarationStorage.createAndCacheIrFunction(
|
||||
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
|
||||
)
|
||||
} else {
|
||||
@@ -424,7 +424,7 @@ class Fir2IrVisitor(
|
||||
data: Any?
|
||||
): IrElement = whileAnalysing(session, anonymousFunction) {
|
||||
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
|
||||
val irFunction = declarationStorage.getOrCreateIrFunction(
|
||||
val irFunction = declarationStorage.createAndCacheIrFunction(
|
||||
anonymousFunction,
|
||||
irParent = conversionScope.parent(),
|
||||
predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION,
|
||||
|
||||
@@ -173,6 +173,7 @@ class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
|
||||
}
|
||||
SymbolKind.FUNCTION_SYMBOL -> {
|
||||
val firSimpleFunction = firDeclaration as FirSimpleFunction
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
declarationStorage.getOrCreateIrFunction(firSimpleFunction, parent)
|
||||
}
|
||||
SymbolKind.PROPERTY_SYMBOL -> {
|
||||
|
||||
@@ -698,6 +698,7 @@ class IrBuiltInsOverFir(
|
||||
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
||||
|
||||
val irParent = findIrParent(functionSymbol)
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
||||
firSubClass: FirClass,
|
||||
delegateOverride: FirSimpleFunction
|
||||
): IrSimpleFunction {
|
||||
val delegateFunction = declarationStorage.getOrCreateIrFunction(
|
||||
val delegateFunction = declarationStorage.createAndCacheIrFunction(
|
||||
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
|
||||
)
|
||||
|
||||
@@ -195,6 +195,7 @@ class Fir2IrLazyClass(
|
||||
symbol.containingClassLookupTag() != ownerLookupTag -> {}
|
||||
symbol.isAbstractMethodOfAny() -> {}
|
||||
else -> {
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
result += declarationStorage.getOrCreateIrFunction(symbol.fir, this, origin)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ class Fir2IrLazyPropertyAccessor(
|
||||
|
||||
override val initialSignatureFunction: IrFunction? by lazy {
|
||||
val originalFirFunction = (fir as? FirSyntheticPropertyAccessor)?.delegate ?: return@lazy null
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
declarationStorage.getOrCreateIrFunction(originalFirFunction, parent)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.lazy
|
||||
|
||||
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.generators.Fir2IrCallableDeclarationsGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenFunctionSymbols
|
||||
@@ -110,6 +111,7 @@ class Fir2IrLazySimpleFunction(
|
||||
|
||||
override val initialSignatureFunction: IrFunction? by lazy {
|
||||
val originalFunction = fir.initialSignatureAttr as? FirFunction ?: return@lazy null
|
||||
@OptIn(GetOrCreateSensitiveAPI::class)
|
||||
declarationStorage.getOrCreateIrFunction(originalFunction, parent).also {
|
||||
check(it !== this) { "Initial function can not be the same as remapped function" }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user