[FIR] FirFakeOverrideGenerator: generate fake declaration with STATUS phase

The requirement for original declarations is to have resolved status,
so we can set at least `STATUS` phase for copied ones. This fixes the
problem that fake declarations for local declarations can have `RAW_FIR`
phase due to the copy from the original declarations, as during body
resolution all local declarations have only this phase.
Another issue: we cannot set the phase from the original declaration
as it is not guaranteed that we will have everything in the resolved
state. E.g., we can have the original declaration in `BODY_RESOLVE`
phase, but at the same time a containing class for fake declaration
can be in `STATUS` phase, for example. This means that the fake
declaration can have unresolved type annotation as it has them
from both places – from the original declaration and from the class
super type.
To simplify the code, we can just always set STATUS phase to be sure
that everything is resolved correctly.

Also, so we can optimize the logic for all phases above on Low Level FIR
level

^KT-64243
This commit is contained in:
Dmitrii Gridin
2023-12-14 16:45:32 +01:00
committed by Space Team
parent 835a9632b9
commit c3e6dd12a2
6 changed files with 206 additions and 181 deletions
@@ -59,37 +59,27 @@ internal object LLFirResolveMultiDesignationCollector {
else -> throwUnexpectedFirElementError(this) else -> throwUnexpectedFirElementError(this)
} }
private fun FirDeclaration.shouldBeResolved(): Boolean = when (origin) { private fun FirDeclaration.shouldBeResolved(): Boolean {
is FirDeclarationOrigin.Source, if (!origin.isLazyResolvable) {
is FirDeclarationOrigin.ImportedFromObjectOrStatic,
is FirDeclarationOrigin.Delegated,
is FirDeclarationOrigin.Synthetic,
is FirDeclarationOrigin.SubstitutionOverride,
is FirDeclarationOrigin.SamConstructor,
is FirDeclarationOrigin.WrappedIntegerOperator,
is FirDeclarationOrigin.IntersectionOverride,
is FirDeclarationOrigin.ScriptCustomization,
-> {
when (this) {
is FirFile -> true
is FirSyntheticProperty, is FirSyntheticPropertyAccessor -> false
is FirSimpleFunction,
is FirProperty,
is FirPropertyAccessor,
is FirField,
is FirTypeAlias,
is FirConstructor,
-> true
else -> true
}
}
else -> {
@OptIn(ResolveStateAccess::class) @OptIn(ResolveStateAccess::class)
check(resolvePhase == FirResolvePhase.BODY_RESOLVE) { check(resolvePhase == FirResolvePhase.BODY_RESOLVE) {
"Expected body resolve phase for origin $origin but found $resolveState" "Expected body resolve phase for origin $origin but found $resolveState"
} }
false return false
}
return when (this) {
is FirFile -> true
is FirSyntheticProperty, is FirSyntheticPropertyAccessor -> false
is FirSimpleFunction,
is FirProperty,
is FirPropertyAccessor,
is FirField,
is FirTypeAlias,
is FirConstructor,
-> true
else -> true
} }
} }
} }
@@ -153,6 +153,9 @@ private class LLFirAnnotationArgumentsTargetResolver(
} }
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) { override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
// There is no sense to resolve such declarations as they do not have their own annotations
if (target is FirCallableDeclaration && target.isCopyCreatedInScope) return
resolveWithKeeper( resolveWithKeeper(
target, target,
target.llFirSession, target.llFirSession,
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.contracts.FirRawContractDescription import org.jetbrains.kotlin.fir.contracts.FirRawContractDescription
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.isCopyCreatedInScope
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
@@ -64,6 +65,9 @@ private class LLFirContractsTargetResolver(
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) { override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
collectTowerDataContext(target) collectTowerDataContext(target)
// There is no sense to resolve such declarations as they do not have contracts
if (target is FirCallableDeclaration && target.isCopyCreatedInScope) return
when (target) { when (target) {
is FirPrimaryConstructor, is FirErrorPrimaryConstructor -> { is FirPrimaryConstructor, is FirErrorPrimaryConstructor -> {
// No contracts here // No contracts here
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.isCopyCreatedInScope
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
@@ -73,12 +74,14 @@ private class LLFirExpectActualMatchingTargetResolver(
} }
} }
private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when (this) { private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when {
is FirEnumEntry -> true // We shouldn't try to calculate expect/actual mapping for fake declarations
is FirProperty -> true this is FirCallableDeclaration && isCopyCreatedInScope -> false
is FirConstructor -> true this is FirEnumEntry -> true
is FirSimpleFunction -> true this is FirProperty -> true
is FirRegularClass -> true this is FirConstructor -> true
is FirTypeAlias -> true this is FirSimpleFunction -> true
this is FirRegularClass -> true
this is FirTypeAlias -> true
else -> false else -> false
} }
@@ -120,28 +120,24 @@ object FirFakeOverrideGenerator {
newModality: Modality? = null, newModality: Modality? = null,
newVisibility: Visibility? = null, newVisibility: Visibility? = null,
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null,
): FirSimpleFunction { ): FirSimpleFunction = buildSimpleFunction {
checkStatusIsResolved(baseFunction) source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseFunction.source
moduleData = session.nullableModuleData ?: baseFunction.moduleData
this.origin = origin
name = baseFunction.name
status = baseFunction.status.copy(newVisibility, newModality, isExpect = isExpect)
symbol = newSymbol
resolvePhase = origin.resolvePhaseForCopy
return buildSimpleFunction { dispatchReceiverType = newDispatchReceiverType
source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseFunction.source attributes = baseFunction.attributes.copy()
moduleData = session.nullableModuleData ?: baseFunction.moduleData typeParameters += configureAnnotationsTypeParametersAndSignature(
this.origin = origin session, baseFunction, newParameterTypes, newTypeParameters,
name = baseFunction.name newReceiverType, newContextReceiverTypes, newReturnType, callableCopySubstitutionForTypeUpdater, newSymbol
status = baseFunction.status.copy(newVisibility, newModality, isExpect = isExpect) ).filterIsInstance<FirTypeParameter>()
symbol = newSymbol deprecationsProvider = baseFunction.deprecationsProvider
resolvePhase = baseFunction.resolvePhase }.apply {
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) }
dispatchReceiverType = newDispatchReceiverType
attributes = baseFunction.attributes.copy()
typeParameters += configureAnnotationsTypeParametersAndSignature(
session, baseFunction, newParameterTypes, newTypeParameters,
newReceiverType, newContextReceiverTypes, newReturnType, callableCopySubstitutionForTypeUpdater, newSymbol
).filterIsInstance<FirTypeParameter>()
deprecationsProvider = baseFunction.deprecationsProvider
}.apply {
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) }
}
} }
fun createCopyForFirConstructor( fun createCopyForFirConstructor(
@@ -157,46 +153,42 @@ object FirFakeOverrideGenerator {
newTypeParameters: List<FirTypeParameterRef>?, newTypeParameters: List<FirTypeParameterRef>?,
isExpect: Boolean, isExpect: Boolean,
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?,
): FirConstructor { ): FirConstructor = buildConstructor {
checkStatusIsResolved(baseConstructor)
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl // TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
// As second alternative, we can invent some light-weight kind of FirRegularClass // As second alternative, we can invent some light-weight kind of FirRegularClass
return buildConstructor { annotations += baseConstructor.annotations
annotations += baseConstructor.annotations source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseConstructor.source
source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseConstructor.source moduleData = session.nullableModuleData ?: baseConstructor.moduleData
moduleData = session.nullableModuleData ?: baseConstructor.moduleData this.origin = origin
this.origin = origin receiverParameter = baseConstructor.receiverParameter?.let { receiverParameter ->
receiverParameter = baseConstructor.receiverParameter?.let { receiverParameter -> buildReceiverParameterCopy(receiverParameter) {
buildReceiverParameterCopy(receiverParameter) { typeRef = receiverParameter.typeRef.withReplacedConeType(null)
typeRef = receiverParameter.typeRef.withReplacedConeType(null)
}
} }
status = baseConstructor.status.copy(isExpect = isExpect)
symbol = fakeOverrideSymbol
typeParameters += configureAnnotationsTypeParametersAndSignature(
session,
baseConstructor,
newParameterTypes,
newTypeParameters,
newReceiverType = null,
newContextReceiverTypes,
newReturnType,
callableCopySubstitutionForTypeUpdater,
fakeOverrideSymbol
)
dispatchReceiverType = newDispatchReceiverType
resolvePhase = baseConstructor.resolvePhase
attributes = baseConstructor.attributes.copy()
deprecationsProvider = baseConstructor.deprecationsProvider
}.apply {
originalForSubstitutionOverrideAttr = baseConstructor
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseConstructor) }
} }
status = baseConstructor.status.copy(isExpect = isExpect)
symbol = fakeOverrideSymbol
typeParameters += configureAnnotationsTypeParametersAndSignature(
session,
baseConstructor,
newParameterTypes,
newTypeParameters,
newReceiverType = null,
newContextReceiverTypes,
newReturnType,
callableCopySubstitutionForTypeUpdater,
fakeOverrideSymbol
)
dispatchReceiverType = newDispatchReceiverType
resolvePhase = origin.resolvePhaseForCopy
attributes = baseConstructor.attributes.copy()
deprecationsProvider = baseConstructor.deprecationsProvider
}.apply {
originalForSubstitutionOverrideAttr = baseConstructor
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseConstructor) }
} }
private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature( private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature(
@@ -277,6 +269,7 @@ object FirFakeOverrideGenerator {
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?,
origin: FirDeclarationOrigin, origin: FirDeclarationOrigin,
) { ) {
checkStatusIsResolved(baseFunction)
annotations += baseFunction.annotations annotations += baseFunction.annotations
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
@@ -338,6 +331,8 @@ object FirFakeOverrideGenerator {
coneTypeOrNull = returnTypeRef.coneTypeOrNull coneTypeOrNull = returnTypeRef.coneTypeOrNull
} }
} }
resolvePhase = origin.resolvePhaseForCopy
}.apply { }.apply {
addOverrideAttributeIfNeeded(original) addOverrideAttributeIfNeeded(original)
} }
@@ -397,55 +392,51 @@ object FirFakeOverrideGenerator {
newModality: Modality? = null, newModality: Modality? = null,
newVisibility: Visibility? = null, newVisibility: Visibility? = null,
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null,
): FirProperty { ): FirProperty = buildProperty {
checkStatusIsResolved(baseProperty) source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseProperty.source
moduleData = session.nullableModuleData ?: baseProperty.moduleData
this.origin = origin
name = baseProperty.name
isVar = baseProperty.isVar
this.symbol = newSymbol
isLocal = false
status = baseProperty.status.copy(newVisibility, newModality, isExpect = isExpect)
return buildProperty { resolvePhase = origin.resolvePhaseForCopy
source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseProperty.source dispatchReceiverType = newDispatchReceiverType
moduleData = session.nullableModuleData ?: baseProperty.moduleData attributes = baseProperty.attributes.copy()
this.origin = origin typeParameters += configureAnnotationsTypeParametersAndSignature(
name = baseProperty.name session,
isVar = baseProperty.isVar baseProperty,
this.symbol = newSymbol newTypeParameters,
isLocal = false newReceiverType,
status = baseProperty.status.copy(newVisibility, newModality, isExpect = isExpect) newContextReceiverTypes,
newReturnType,
callableCopySubstitutionForTypeUpdater
)
deprecationsProvider = baseProperty.deprecationsProvider
resolvePhase = baseProperty.resolvePhase getter = baseProperty.getter?.buildCopyIfNeeded(
dispatchReceiverType = newDispatchReceiverType moduleData = session.nullableModuleData ?: baseProperty.moduleData,
attributes = baseProperty.attributes.copy() origin = origin,
typeParameters += configureAnnotationsTypeParametersAndSignature( propertyReturnTypeRef = this@buildProperty.returnTypeRef,
session, propertySymbol = newSymbol,
baseProperty, dispatchReceiverType = dispatchReceiverType,
newTypeParameters, derivedClassLookupTag = derivedClassLookupTag,
newReceiverType, baseProperty = baseProperty,
newContextReceiverTypes, )
newReturnType,
callableCopySubstitutionForTypeUpdater
)
deprecationsProvider = baseProperty.deprecationsProvider
getter = baseProperty.getter?.buildCopyIfNeeded( setter = baseProperty.setter?.buildCopyIfNeeded(
moduleData = session.nullableModuleData ?: baseProperty.moduleData, moduleData = session.nullableModuleData ?: baseProperty.moduleData,
origin = origin, origin = origin,
propertyReturnTypeRef = this@buildProperty.returnTypeRef, propertyReturnTypeRef = this@buildProperty.returnTypeRef,
propertySymbol = newSymbol, propertySymbol = newSymbol,
dispatchReceiverType = dispatchReceiverType, dispatchReceiverType = dispatchReceiverType,
derivedClassLookupTag = derivedClassLookupTag, derivedClassLookupTag = derivedClassLookupTag,
baseProperty = baseProperty, baseProperty = baseProperty,
) )
}.apply {
setter = baseProperty.setter?.buildCopyIfNeeded( containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
moduleData = session.nullableModuleData ?: baseProperty.moduleData,
origin = origin,
propertyReturnTypeRef = this@buildProperty.returnTypeRef,
propertySymbol = newSymbol,
dispatchReceiverType = dispatchReceiverType,
derivedClassLookupTag = derivedClassLookupTag,
baseProperty = baseProperty,
)
}.apply {
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
}
} }
private fun FirPropertyAccessor.buildCopyIfNeeded( private fun FirPropertyAccessor.buildCopyIfNeeded(
@@ -487,7 +478,7 @@ object FirFakeOverrideGenerator {
propertySymbol = propertySymbol, propertySymbol = propertySymbol,
modality = modality ?: Modality.FINAL, modality = modality ?: Modality.FINAL,
effectiveVisibility = effectiveVisibility, effectiveVisibility = effectiveVisibility,
resolvePhase = resolvePhase, resolvePhase = origin.resolvePhaseForCopy,
).apply { ).apply {
replaceAnnotations(this@buildCopy.annotations) replaceAnnotations(this@buildCopy.annotations)
} }
@@ -500,7 +491,7 @@ object FirFakeOverrideGenerator {
propertySymbol = propertySymbol, propertySymbol = propertySymbol,
modality = modality ?: Modality.FINAL, modality = modality ?: Modality.FINAL,
effectiveVisibility = effectiveVisibility, effectiveVisibility = effectiveVisibility,
resolvePhase = resolvePhase, resolvePhase = origin.resolvePhaseForCopy,
).apply { ).apply {
replaceAnnotations(this@buildCopy.annotations) replaceAnnotations(this@buildCopy.annotations)
} }
@@ -511,6 +502,7 @@ object FirFakeOverrideGenerator {
this.propertySymbol = propertySymbol this.propertySymbol = propertySymbol
this.dispatchReceiverType = dispatchReceiverType this.dispatchReceiverType = dispatchReceiverType
this.body = null this.body = null
resolvePhase = origin.resolvePhaseForCopy
}.also { }.also {
if (it.isSetter) { if (it.isSetter) {
val originalParameter = it.valueParameters.first() val originalParameter = it.valueParameters.first()
@@ -547,27 +539,25 @@ object FirFakeOverrideGenerator {
newModality: Modality? = null, newModality: Modality? = null,
newVisibility: Visibility? = null, newVisibility: Visibility? = null,
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null,
): FirField { ): FirField = buildField {
return buildField { source = baseField.source
source = baseField.source moduleData = session.nullableModuleData ?: baseField.moduleData
moduleData = session.nullableModuleData ?: baseField.moduleData this.origin = origin
this.origin = origin name = baseField.name
name = baseField.name isVar = baseField.isVar
isVar = baseField.isVar this.symbol = newSymbol
this.symbol = newSymbol status = baseField.status.copy(newVisibility, newModality, isExpect = isExpect)
status = baseField.status.copy(newVisibility, newModality, isExpect = isExpect)
resolvePhase = baseField.resolvePhase resolvePhase = origin.resolvePhaseForCopy
dispatchReceiverType = newDispatchReceiverType dispatchReceiverType = newDispatchReceiverType
attributes = baseField.attributes.copy() attributes = baseField.attributes.copy()
configureAnnotationsAndSignature( configureAnnotationsAndSignature(
baseField, newReceiverType, newContextReceiverTypes, newReturnType, baseField, newReceiverType, newContextReceiverTypes, newReturnType,
callableCopySubstitutionForTypeUpdater, updateReceiver = false callableCopySubstitutionForTypeUpdater, updateReceiver = false
) )
deprecationsProvider = baseField.deprecationsProvider deprecationsProvider = baseField.deprecationsProvider
}.apply { }.apply {
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) }
}
} }
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature( private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
@@ -652,6 +642,7 @@ object FirFakeOverrideGenerator {
callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?,
updateReceiver: Boolean = true, updateReceiver: Boolean = true,
) { ) {
checkStatusIsResolved(baseVariable)
annotations += baseVariable.annotations annotations += baseVariable.annotations
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
@@ -690,29 +681,25 @@ object FirFakeOverrideGenerator {
derivedClassLookupTag: ConeClassLikeLookupTag, derivedClassLookupTag: ConeClassLikeLookupTag,
newReturnType: ConeKotlinType?, newReturnType: ConeKotlinType?,
origin: FirDeclarationOrigin.SubstitutionOverride, origin: FirDeclarationOrigin.SubstitutionOverride,
): FirFieldSymbol { ): FirFieldSymbol = buildField {
val symbol = FirFieldSymbol(CallableId(derivedClassLookupTag.classId, baseField.name)) val symbol = FirFieldSymbol(CallableId(derivedClassLookupTag.classId, baseField.name))
buildField { moduleData = session.nullableModuleData ?: baseField.moduleData
moduleData = session.nullableModuleData ?: baseField.moduleData this.symbol = symbol
this.symbol = symbol this.origin = origin
this.origin = origin returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType)
returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType)
source = baseField.source source = baseField.source
resolvePhase = baseField.resolvePhase name = baseField.name
name = baseField.name isVar = baseField.isVar
isVar = baseField.isVar status = baseField.status
status = baseField.status resolvePhase = origin.resolvePhaseForCopy
resolvePhase = baseField.resolvePhase annotations += baseField.annotations
annotations += baseField.annotations attributes = baseField.attributes.copy()
attributes = baseField.attributes.copy() dispatchReceiverType = baseField.dispatchReceiverType
dispatchReceiverType = baseField.dispatchReceiverType }.apply {
}.apply { originalForSubstitutionOverrideAttr = baseField
originalForSubstitutionOverrideAttr = baseField containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) }
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } }.symbol
}
return symbol
}
// Returns a list of type parameters, and a substitutor that should be used for all other types // Returns a list of type parameters, and a substitutor that should be used for all other types
fun createNewTypeParametersAndSubstitutor( fun createNewTypeParametersAndSubstitutor(
@@ -730,7 +717,7 @@ object FirFakeOverrideGenerator {
source = typeParameter.source source = typeParameter.source
moduleData = typeParameter.moduleData moduleData = typeParameter.moduleData
this.origin = origin this.origin = origin
resolvePhase = FirResolvePhase.DECLARATIONS resolvePhase = origin.resolvePhaseForCopy
name = typeParameter.name name = typeParameter.name
symbol = FirTypeParameterSymbol() symbol = FirTypeParameterSymbol()
variance = typeParameter.variance variance = typeParameter.variance
@@ -794,4 +781,24 @@ object FirFakeOverrideGenerator {
withEntry("declarationStatus", member.status) { it.toString() } withEntry("declarationStatus", member.status) { it.toString() }
} }
} }
/**
* In Low Level FIR we cannot be sure that all copied elements are already resolved,
* so we play safe with [FirResolvePhase.STATUS] phase in such cases.
* Example:
* ```kotlin
* class MyClass : BaseClass<@Anno("super $constant") Int>()
*
* abstract class BaseClass<T : @Anno("bound $constant") Number> {
* var property: SCHEME
* }
* ```
* here we can have `BaseClass.property` already in [FirResolvePhase.BODY_RESOLVE] phase,
* but `MyClass` in [FirResolvePhase.STATUS].
* So [FirResolvePhase.BODY_RESOLVE] on the fake override will lead to the problem because
* effectively we will have unresolved `@Anno("super $constant")` annotation inside "fully resolve"
* function
*/
private val FirDeclarationOrigin.resolvePhaseForCopy: FirResolvePhase
get() = if (isLazyResolvable) FirResolvePhase.STATUS else FirResolvePhase.BODY_RESOLVE
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -63,3 +63,21 @@ sealed class FirDeclarationOrigin(
val GeneratedDeclarationKey.origin: FirDeclarationOrigin val GeneratedDeclarationKey.origin: FirDeclarationOrigin
get() = FirDeclarationOrigin.Plugin(this) get() = FirDeclarationOrigin.Plugin(this)
/**
* @return **true** if a declaration with [this] origin can be in not fully resolved state
*/
val FirDeclarationOrigin.isLazyResolvable: Boolean
get() = when (this) {
is FirDeclarationOrigin.Source,
is FirDeclarationOrigin.ImportedFromObjectOrStatic,
is FirDeclarationOrigin.Delegated,
is FirDeclarationOrigin.Synthetic,
is FirDeclarationOrigin.SubstitutionOverride,
is FirDeclarationOrigin.SamConstructor,
is FirDeclarationOrigin.WrappedIntegerOperator,
is FirDeclarationOrigin.IntersectionOverride,
is FirDeclarationOrigin.ScriptCustomization,
-> true
else -> false
}