diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt index c1313b42926..74b77d7bc06 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt @@ -59,37 +59,27 @@ internal object LLFirResolveMultiDesignationCollector { else -> throwUnexpectedFirElementError(this) } - private fun FirDeclaration.shouldBeResolved(): Boolean = when (origin) { - 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, - -> { - 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 -> { + private fun FirDeclaration.shouldBeResolved(): Boolean { + if (!origin.isLazyResolvable) { @OptIn(ResolveStateAccess::class) check(resolvePhase == FirResolvePhase.BODY_RESOLVE) { "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 } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt index 48b1a96b0ec..59bb8f3193d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt @@ -153,6 +153,9 @@ private class LLFirAnnotationArgumentsTargetResolver( } 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( target, target.llFirSession, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirContractsLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirContractsLazyResolver.kt index b747581fbef..cb3bdcaa0f6 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirContractsLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirContractsLazyResolver.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.contracts.FirRawContractDescription import org.jetbrains.kotlin.fir.declarations.* 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.transformers.body.resolve.BodyResolveContext import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector @@ -64,6 +65,9 @@ private class LLFirContractsTargetResolver( override fun doLazyResolveUnderLock(target: FirElementWithResolveState) { 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) { is FirPrimaryConstructor, is FirErrorPrimaryConstructor -> { // No contracts here diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt index 1cb8a471f3b..d738eb108bc 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.isCopyCreatedInScope import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector @@ -73,12 +74,14 @@ private class LLFirExpectActualMatchingTargetResolver( } } -private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when (this) { - is FirEnumEntry -> true - is FirProperty -> true - is FirConstructor -> true - is FirSimpleFunction -> true - is FirRegularClass -> true - is FirTypeAlias -> true +private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when { + // We shouldn't try to calculate expect/actual mapping for fake declarations + this is FirCallableDeclaration && isCopyCreatedInScope -> false + this is FirEnumEntry -> true + this is FirProperty -> true + this is FirConstructor -> true + this is FirSimpleFunction -> true + this is FirRegularClass -> true + this is FirTypeAlias -> true else -> false } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt index 4106516066c..3c5e67dea85 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt @@ -120,28 +120,24 @@ object FirFakeOverrideGenerator { newModality: Modality? = null, newVisibility: Visibility? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, - ): FirSimpleFunction { - checkStatusIsResolved(baseFunction) + ): FirSimpleFunction = buildSimpleFunction { + 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 { - 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 = baseFunction.resolvePhase - - dispatchReceiverType = newDispatchReceiverType - attributes = baseFunction.attributes.copy() - typeParameters += configureAnnotationsTypeParametersAndSignature( - session, baseFunction, newParameterTypes, newTypeParameters, - newReceiverType, newContextReceiverTypes, newReturnType, callableCopySubstitutionForTypeUpdater, newSymbol - ).filterIsInstance() - deprecationsProvider = baseFunction.deprecationsProvider - }.apply { - containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) } - } + dispatchReceiverType = newDispatchReceiverType + attributes = baseFunction.attributes.copy() + typeParameters += configureAnnotationsTypeParametersAndSignature( + session, baseFunction, newParameterTypes, newTypeParameters, + newReceiverType, newContextReceiverTypes, newReturnType, callableCopySubstitutionForTypeUpdater, newSymbol + ).filterIsInstance() + deprecationsProvider = baseFunction.deprecationsProvider + }.apply { + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) } } fun createCopyForFirConstructor( @@ -157,46 +153,42 @@ object FirFakeOverrideGenerator { newTypeParameters: List?, isExpect: Boolean, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, - ): FirConstructor { - checkStatusIsResolved(baseConstructor) - + ): FirConstructor = buildConstructor { // 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 - return buildConstructor { - annotations += baseConstructor.annotations - source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseConstructor.source - moduleData = session.nullableModuleData ?: baseConstructor.moduleData - this.origin = origin - receiverParameter = baseConstructor.receiverParameter?.let { receiverParameter -> - buildReceiverParameterCopy(receiverParameter) { - typeRef = receiverParameter.typeRef.withReplacedConeType(null) - } + annotations += baseConstructor.annotations + source = derivedClassLookupTag?.toSymbol(session)?.source ?: baseConstructor.source + moduleData = session.nullableModuleData ?: baseConstructor.moduleData + this.origin = origin + receiverParameter = baseConstructor.receiverParameter?.let { receiverParameter -> + buildReceiverParameterCopy(receiverParameter) { + 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( @@ -277,6 +269,7 @@ object FirFakeOverrideGenerator { callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, origin: FirDeclarationOrigin, ) { + checkStatusIsResolved(baseFunction) annotations += baseFunction.annotations @Suppress("NAME_SHADOWING") @@ -338,6 +331,8 @@ object FirFakeOverrideGenerator { coneTypeOrNull = returnTypeRef.coneTypeOrNull } } + + resolvePhase = origin.resolvePhaseForCopy }.apply { addOverrideAttributeIfNeeded(original) } @@ -397,55 +392,51 @@ object FirFakeOverrideGenerator { newModality: Modality? = null, newVisibility: Visibility? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, - ): FirProperty { - checkStatusIsResolved(baseProperty) + ): FirProperty = buildProperty { + 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 { - 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) + resolvePhase = origin.resolvePhaseForCopy + dispatchReceiverType = newDispatchReceiverType + attributes = baseProperty.attributes.copy() + typeParameters += configureAnnotationsTypeParametersAndSignature( + session, + baseProperty, + newTypeParameters, + newReceiverType, + newContextReceiverTypes, + newReturnType, + callableCopySubstitutionForTypeUpdater + ) + deprecationsProvider = baseProperty.deprecationsProvider - resolvePhase = baseProperty.resolvePhase - dispatchReceiverType = newDispatchReceiverType - attributes = baseProperty.attributes.copy() - typeParameters += configureAnnotationsTypeParametersAndSignature( - session, - baseProperty, - newTypeParameters, - newReceiverType, - newContextReceiverTypes, - newReturnType, - callableCopySubstitutionForTypeUpdater - ) - deprecationsProvider = baseProperty.deprecationsProvider + getter = baseProperty.getter?.buildCopyIfNeeded( + moduleData = session.nullableModuleData ?: baseProperty.moduleData, + origin = origin, + propertyReturnTypeRef = this@buildProperty.returnTypeRef, + propertySymbol = newSymbol, + dispatchReceiverType = dispatchReceiverType, + derivedClassLookupTag = derivedClassLookupTag, + baseProperty = baseProperty, + ) - getter = baseProperty.getter?.buildCopyIfNeeded( - moduleData = session.nullableModuleData ?: baseProperty.moduleData, - origin = origin, - propertyReturnTypeRef = this@buildProperty.returnTypeRef, - propertySymbol = newSymbol, - dispatchReceiverType = dispatchReceiverType, - derivedClassLookupTag = derivedClassLookupTag, - baseProperty = baseProperty, - ) - - setter = baseProperty.setter?.buildCopyIfNeeded( - 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) } - } + setter = baseProperty.setter?.buildCopyIfNeeded( + 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( @@ -487,7 +478,7 @@ object FirFakeOverrideGenerator { propertySymbol = propertySymbol, modality = modality ?: Modality.FINAL, effectiveVisibility = effectiveVisibility, - resolvePhase = resolvePhase, + resolvePhase = origin.resolvePhaseForCopy, ).apply { replaceAnnotations(this@buildCopy.annotations) } @@ -500,7 +491,7 @@ object FirFakeOverrideGenerator { propertySymbol = propertySymbol, modality = modality ?: Modality.FINAL, effectiveVisibility = effectiveVisibility, - resolvePhase = resolvePhase, + resolvePhase = origin.resolvePhaseForCopy, ).apply { replaceAnnotations(this@buildCopy.annotations) } @@ -511,6 +502,7 @@ object FirFakeOverrideGenerator { this.propertySymbol = propertySymbol this.dispatchReceiverType = dispatchReceiverType this.body = null + resolvePhase = origin.resolvePhaseForCopy }.also { if (it.isSetter) { val originalParameter = it.valueParameters.first() @@ -547,27 +539,25 @@ object FirFakeOverrideGenerator { newModality: Modality? = null, newVisibility: Visibility? = null, callableCopySubstitutionForTypeUpdater: CallableCopySubstitution? = null, - ): FirField { - return buildField { - source = baseField.source - moduleData = session.nullableModuleData ?: baseField.moduleData - this.origin = origin - name = baseField.name - isVar = baseField.isVar - this.symbol = newSymbol - status = baseField.status.copy(newVisibility, newModality, isExpect = isExpect) + ): FirField = buildField { + source = baseField.source + moduleData = session.nullableModuleData ?: baseField.moduleData + this.origin = origin + name = baseField.name + isVar = baseField.isVar + this.symbol = newSymbol + status = baseField.status.copy(newVisibility, newModality, isExpect = isExpect) - resolvePhase = baseField.resolvePhase - dispatchReceiverType = newDispatchReceiverType - attributes = baseField.attributes.copy() - configureAnnotationsAndSignature( - baseField, newReceiverType, newContextReceiverTypes, newReturnType, - callableCopySubstitutionForTypeUpdater, updateReceiver = false - ) - deprecationsProvider = baseField.deprecationsProvider - }.apply { - containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } - } + resolvePhase = origin.resolvePhaseForCopy + dispatchReceiverType = newDispatchReceiverType + attributes = baseField.attributes.copy() + configureAnnotationsAndSignature( + baseField, newReceiverType, newContextReceiverTypes, newReturnType, + callableCopySubstitutionForTypeUpdater, updateReceiver = false + ) + deprecationsProvider = baseField.deprecationsProvider + }.apply { + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } } private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature( @@ -652,6 +642,7 @@ object FirFakeOverrideGenerator { callableCopySubstitutionForTypeUpdater: CallableCopySubstitution?, updateReceiver: Boolean = true, ) { + checkStatusIsResolved(baseVariable) annotations += baseVariable.annotations @Suppress("NAME_SHADOWING") @@ -690,29 +681,25 @@ object FirFakeOverrideGenerator { derivedClassLookupTag: ConeClassLikeLookupTag, newReturnType: ConeKotlinType?, origin: FirDeclarationOrigin.SubstitutionOverride, - ): FirFieldSymbol { + ): FirFieldSymbol = buildField { val symbol = FirFieldSymbol(CallableId(derivedClassLookupTag.classId, baseField.name)) - buildField { - moduleData = session.nullableModuleData ?: baseField.moduleData - this.symbol = symbol - this.origin = origin - returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType) + moduleData = session.nullableModuleData ?: baseField.moduleData + this.symbol = symbol + this.origin = origin + returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType) - source = baseField.source - resolvePhase = baseField.resolvePhase - name = baseField.name - isVar = baseField.isVar - status = baseField.status - resolvePhase = baseField.resolvePhase - annotations += baseField.annotations - attributes = baseField.attributes.copy() - dispatchReceiverType = baseField.dispatchReceiverType - }.apply { - originalForSubstitutionOverrideAttr = baseField - containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } - } - return symbol - } + source = baseField.source + name = baseField.name + isVar = baseField.isVar + status = baseField.status + resolvePhase = origin.resolvePhaseForCopy + annotations += baseField.annotations + attributes = baseField.attributes.copy() + dispatchReceiverType = baseField.dispatchReceiverType + }.apply { + originalForSubstitutionOverrideAttr = baseField + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } + }.symbol // Returns a list of type parameters, and a substitutor that should be used for all other types fun createNewTypeParametersAndSubstitutor( @@ -730,7 +717,7 @@ object FirFakeOverrideGenerator { source = typeParameter.source moduleData = typeParameter.moduleData this.origin = origin - resolvePhase = FirResolvePhase.DECLARATIONS + resolvePhase = origin.resolvePhaseForCopy name = typeParameter.name symbol = FirTypeParameterSymbol() variance = typeParameter.variance @@ -794,4 +781,24 @@ object FirFakeOverrideGenerator { 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 { + * 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 } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt index 26075b7cf86..6ce4c311772 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt @@ -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. */ @@ -63,3 +63,21 @@ sealed class FirDeclarationOrigin( val GeneratedDeclarationKey.origin: FirDeclarationOrigin 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 + } \ No newline at end of file