[FIR] fix resolve contract violation from scopes
We cannot call lazy resolve to STATUS phase from scopes as scopes may be accessed on a STATUS phase or earlier ^KT-54890 ^KTIJ-23587 fixed
This commit is contained in:
@@ -28,14 +28,21 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
fun FirSmartCastExpression.smartcastScope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
scopeSession: ScopeSession,
|
||||
requiredPhase: FirResolvePhase? = null,
|
||||
): FirTypeScope? {
|
||||
val smartcastType = smartcastTypeWithoutNullableNothing?.coneType ?: smartcastType.coneType
|
||||
val smartcastScope = smartcastType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
val smartcastScope = smartcastType.scope(
|
||||
useSiteSession,
|
||||
scopeSession,
|
||||
FakeOverrideTypeCalculator.DoNothing,
|
||||
requiredPhase = FirResolvePhase.STATUS
|
||||
)
|
||||
if (isStable) {
|
||||
return smartcastScope
|
||||
}
|
||||
val originalScope = originalExpression.typeRef.coneType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
val originalScope = originalExpression.typeRef.coneType
|
||||
.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase)
|
||||
?: return smartcastScope
|
||||
|
||||
if (smartcastScope == null) {
|
||||
@@ -55,14 +62,15 @@ fun ConeClassLikeType.delegatingConstructorScope(
|
||||
fun ConeKotlinType.scope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
fakeOverrideTypeCalculator: FakeOverrideTypeCalculator
|
||||
fakeOverrideTypeCalculator: FakeOverrideTypeCalculator,
|
||||
requiredPhase: FirResolvePhase?,
|
||||
): FirTypeScope? {
|
||||
val scope = scope(useSiteSession, scopeSession, FirResolvePhase.DECLARATIONS) ?: return null
|
||||
val scope = scope(useSiteSession, scopeSession, requiredPhase) ?: return null
|
||||
if (fakeOverrideTypeCalculator == FakeOverrideTypeCalculator.DoNothing) return scope
|
||||
return FirScopeWithFakeOverrideTypeCalculator(scope, fakeOverrideTypeCalculator)
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession, requiredPhase: FirResolvePhase): FirTypeScope? {
|
||||
private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession, requiredPhase: FirResolvePhase?): FirTypeScope? {
|
||||
return when (this) {
|
||||
is ConeErrorType -> null
|
||||
is ConeClassLikeType -> classScope(useSiteSession, scopeSession, requiredPhase, lookupTag)
|
||||
@@ -99,13 +107,15 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
private fun ConeClassLikeType.classScope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
requiredPhase: FirResolvePhase,
|
||||
requiredPhase: FirResolvePhase?,
|
||||
memberOwnerLookupTag: ConeClassLikeLookupTag
|
||||
): FirTypeScope? {
|
||||
val fullyExpandedType = fullyExpandedType(useSiteSession)
|
||||
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null
|
||||
|
||||
fir.symbol.lazyResolveToPhase(requiredPhase)
|
||||
if (requiredPhase != null) {
|
||||
fir.symbol.lazyResolveToPhase(requiredPhase)
|
||||
}
|
||||
|
||||
val substitutor = when {
|
||||
attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession)
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fakeElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildSmartCastExpression
|
||||
@@ -41,7 +42,7 @@ interface ReceiverValue : Receiver {
|
||||
val receiverExpression: FirExpression
|
||||
|
||||
fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? =
|
||||
type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
|
||||
}
|
||||
|
||||
// TODO: should inherit just Receiver, not ReceiverValue
|
||||
@@ -70,9 +71,9 @@ open class ExpressionReceiverValue(
|
||||
receiverExpr = receiverExpr.arguments.firstOrNull()
|
||||
}
|
||||
if (receiverExpr is FirSmartCastExpression) {
|
||||
return receiverExpr.smartcastScope(useSiteSession, scopeSession)
|
||||
return receiverExpr.smartcastScope(useSiteSession, scopeSession, requiredPhase = FirResolvePhase.STATUS)
|
||||
}
|
||||
return type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
return type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +92,8 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
|
||||
|
||||
val originalType: ConeKotlinType = type
|
||||
|
||||
var implicitScope: FirTypeScope? = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
var implicitScope: FirTypeScope? =
|
||||
type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
|
||||
private set
|
||||
|
||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? = implicitScope
|
||||
@@ -132,7 +134,8 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
|
||||
typeRef = smartcastType.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||
}
|
||||
}
|
||||
implicitScope = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
implicitScope =
|
||||
type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
|
||||
}
|
||||
|
||||
abstract fun createSnapshot(): ImplicitReceiverValue<S>
|
||||
|
||||
@@ -8,16 +8,14 @@ package org.jetbrains.kotlin.fir.scopes
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
fun ConeClassLikeLookupTag.getNestedClassifierScope(session: FirSession, scopeSession: ScopeSession): FirContainingNamesAwareScope? {
|
||||
val klass = toSymbol(session)?.fir as? FirRegularClass ?: return null
|
||||
@@ -29,7 +27,12 @@ fun ConeClassLikeLookupTag.getNestedClassifierScope(session: FirSession, scopeSe
|
||||
*/
|
||||
@TestOnly
|
||||
fun debugCollectOverrides(symbol: FirCallableSymbol<*>, session: FirSession, scopeSession: ScopeSession): Map<Any, Any> {
|
||||
val scope = symbol.dispatchReceiverType?.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing) ?: return emptyMap()
|
||||
val scope = symbol.dispatchReceiverType?.scope(
|
||||
session,
|
||||
scopeSession,
|
||||
FakeOverrideTypeCalculator.DoNothing,
|
||||
requiredPhase = FirResolvePhase.STATUS
|
||||
) ?: return emptyMap()
|
||||
return debugCollectOverrides(symbol, scope)
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -116,6 +116,7 @@ class FirClassSubstitutionScope(
|
||||
|
||||
fun createSubstitutionOverrideFunction(original: FirNamedFunctionSymbol): FirNamedFunctionSymbol {
|
||||
if (substitutor == ConeSubstitutor.Empty) return original
|
||||
original.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val member = original.fir
|
||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||
|
||||
@@ -175,6 +176,7 @@ class FirClassSubstitutionScope(
|
||||
|
||||
fun createSubstitutionOverrideConstructor(original: FirConstructorSymbol): FirConstructorSymbol {
|
||||
if (substitutor == ConeSubstitutor.Empty) return original
|
||||
original.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val constructor = original.fir
|
||||
|
||||
val symbolForOverride = FirConstructorSymbol(original.callableId)
|
||||
@@ -221,6 +223,7 @@ class FirClassSubstitutionScope(
|
||||
|
||||
fun createSubstitutionOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
||||
if (substitutor == ConeSubstitutor.Empty) return original
|
||||
original.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val member = original.fir
|
||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||
|
||||
@@ -279,7 +282,6 @@ class FirClassSubstitutionScope(
|
||||
)
|
||||
|
||||
private fun createSubstitutedData(member: FirCallableDeclaration, symbolForOverride: FirBasedSymbol<*>): SubstitutedData {
|
||||
member.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val (newTypeParameters, substitutor) = FirFakeOverrideGenerator.createNewTypeParametersAndSubstitutor(
|
||||
session,
|
||||
member as FirTypeParameterRefsOwner,
|
||||
@@ -293,7 +295,6 @@ class FirClassSubstitutionScope(
|
||||
|
||||
val newDispatchReceiverType = dispatchReceiverTypeForSubstitutedMembers.substitute(substitutor)
|
||||
|
||||
member.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, member.symbol) }
|
||||
val newReturnType = returnType?.substitute(substitutor)
|
||||
@@ -309,10 +310,10 @@ class FirClassSubstitutionScope(
|
||||
|
||||
fun createSubstitutionOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
||||
if (substitutor == ConeSubstitutor.Empty) return original
|
||||
original.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val member = original.fir
|
||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||
|
||||
member.symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
// TODO: do we have fields with implicit type?
|
||||
val newReturnType = returnType?.substitute() ?: return original
|
||||
@@ -322,10 +323,10 @@ class FirClassSubstitutionScope(
|
||||
|
||||
fun createSubstitutionOverrideSyntheticProperty(original: FirSyntheticPropertySymbol): FirSyntheticPropertySymbol {
|
||||
if (substitutor == ConeSubstitutor.Empty) return original
|
||||
original.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
val member = original.fir as FirSyntheticProperty
|
||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||
|
||||
member.symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, original) }
|
||||
val newReturnType = returnType?.substitute()
|
||||
|
||||
+2
-3
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
|
||||
@@ -49,8 +48,8 @@ class FirDelegatedMemberScope(
|
||||
}
|
||||
|
||||
private fun buildScope(delegateField: FirField): FirTypeScope? {
|
||||
delegateField.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
return delegateField.returnTypeRef.coneType.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
return delegateField.returnTypeRef.coneType
|
||||
.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = null)
|
||||
}
|
||||
|
||||
private fun collectFunctionsFromSpecificField(
|
||||
|
||||
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirOperationNameConventions
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
@@ -59,7 +61,7 @@ class FirDynamicScope @FirDynamicScopeConstructor constructor(
|
||||
override fun getClassifierNames(): Set<Name> = emptySet()
|
||||
|
||||
private val anyTypeScope by lazy {
|
||||
session.builtinTypes.anyType.type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
session.builtinTypes.anyType.type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = null)
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ class FirIntegerConstantOperatorScope(
|
||||
true -> session.builtinTypes.uIntType
|
||||
false -> session.builtinTypes.intType
|
||||
}.type
|
||||
baseType.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing) ?: error("Scope for $baseType not found")
|
||||
baseType.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = null)
|
||||
?: error("Scope for $baseType not found")
|
||||
}
|
||||
|
||||
private val mappedFunctions = mutableMapOf<Name, FirNamedFunctionSymbol>()
|
||||
|
||||
@@ -192,7 +192,7 @@ fun ConeKotlinType.findContributedInvokeSymbol(
|
||||
} else {
|
||||
FakeOverrideTypeCalculator.DoNothing
|
||||
}
|
||||
val scope = scope(session, scopeSession, fakeOverrideTypeCalculator) ?: return null
|
||||
val scope = scope(session, scopeSession, fakeOverrideTypeCalculator, requiredPhase = null) ?: return null
|
||||
var declaredInvoke: FirNamedFunctionSymbol? = null
|
||||
scope.processFunctionsByName(OperatorNameConventions.INVOKE) { functionSymbol ->
|
||||
if (functionSymbol.fir.valueParameters.size == baseInvokeSymbol.fir.valueParameters.size) {
|
||||
|
||||
Reference in New Issue
Block a user