[FIR IDE] Insert ensure resolve into checkers and scopes

This commit is contained in:
Igor Yakovlev
2021-07-12 20:44:39 +02:00
parent 2fd6c55fc8
commit 6869fbbfe5
4 changed files with 25 additions and 8 deletions
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.java.scopes
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
@@ -20,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -140,6 +138,9 @@ class JavaOverrideChecker internal constructor(
overrideCandidate: FirCallableDeclaration, overrideCandidate: FirCallableDeclaration,
baseDeclaration: FirCallableDeclaration baseDeclaration: FirCallableDeclaration
): ConeSubstitutor { ): ConeSubstitutor {
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
if (!overrideCandidate.isTypeParameterDependent() && !baseDeclaration.isTypeParameterDependent()) { if (!overrideCandidate.isTypeParameterDependent() && !baseDeclaration.isTypeParameterDependent()) {
return ConeSubstitutor.Empty return ConeSubstitutor.Empty
} }
@@ -151,6 +152,10 @@ class JavaOverrideChecker internal constructor(
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean { override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
if (overrideCandidate.isStatic != baseDeclaration.isStatic) return false if (overrideCandidate.isStatic != baseDeclaration.isStatic) return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
// NB: overrideCandidate is from Java and has no receiver // NB: overrideCandidate is from Java and has no receiver
val receiverTypeRef = baseDeclaration.receiverTypeRef val receiverTypeRef = baseDeclaration.receiverTypeRef
val baseParameterTypes = listOfNotNull(receiverTypeRef) + baseDeclaration.valueParameters.map { it.returnTypeRef } val baseParameterTypes = listOfNotNull(receiverTypeRef) + baseDeclaration.valueParameters.map { it.returnTypeRef }
@@ -164,6 +169,10 @@ class JavaOverrideChecker internal constructor(
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean { override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean {
if (baseDeclaration.modality == Modality.FINAL) return false if (baseDeclaration.modality == Modality.FINAL) return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
val receiverTypeRef = baseDeclaration.receiverTypeRef val receiverTypeRef = baseDeclaration.receiverTypeRef
return when (overrideCandidate) { return when (overrideCandidate) {
is FirSimpleFunction -> { is FirSimpleFunction -> {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.chain
import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -222,6 +224,7 @@ class FirClassSubstitutionScope(
val receiverType = member.receiverTypeRef?.coneType val receiverType = member.receiverTypeRef?.coneType
val newReceiverType = receiverType?.substitute(substitutor) val newReceiverType = receiverType?.substitute(substitutor)
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>() val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, member.symbol) } val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, member.symbol) }
val newReturnType = returnType?.substitute(substitutor) val newReturnType = returnType?.substitute(substitutor)
@@ -233,6 +236,7 @@ class FirClassSubstitutionScope(
val member = original.fir val member = original.fir
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>() val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
// TODO: do we have fields with implicit type? // TODO: do we have fields with implicit type?
val newReturnType = returnType?.substitute() ?: return original val newReturnType = returnType?.substitute() ?: return original
@@ -245,6 +249,7 @@ class FirClassSubstitutionScope(
val member = original.fir as FirSyntheticProperty val member = original.fir as FirSyntheticProperty
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>() val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, original) } val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, original) }
val newReturnType = returnType?.substitute() val newReturnType = returnType?.substitute()
@@ -108,6 +108,8 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
overrideCandidate: FirCallableDeclaration, overrideCandidate: FirCallableDeclaration,
baseDeclaration: FirCallableDeclaration baseDeclaration: FirCallableDeclaration
): ConeSubstitutor? { ): ConeSubstitutor? {
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
val substitutor = buildSubstitutorForOverridesCheck(overrideCandidate, baseDeclaration, session) ?: return null val substitutor = buildSubstitutorForOverridesCheck(overrideCandidate, baseDeclaration, session) ?: return null
if ( if (
overrideCandidate.typeParameters.isNotEmpty() && overrideCandidate.typeParameters.isNotEmpty() &&
@@ -134,7 +136,6 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
overrideCandidate.ensureResolved(FirResolvePhase.TYPES) overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES) baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
if (!isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)) return false if (!isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)) return false
return overrideCandidate.valueParameters.zip(baseDeclaration.valueParameters).all { (memberParam, selfParam) -> return overrideCandidate.valueParameters.zip(baseDeclaration.valueParameters).all { (memberParam, selfParam) ->
@@ -150,6 +151,8 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
if (overrideCandidate !is FirProperty) return false if (overrideCandidate !is FirProperty) return false
val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration) ?: return false val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration) ?: return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
return isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor) return isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)
} }
} }
@@ -71,7 +71,7 @@ class KtFirOverrideInfoProvider(
override fun getOriginalContainingClassForOverride(symbol: KtCallableSymbol): KtClassOrObjectSymbol? { override fun getOriginalContainingClassForOverride(symbol: KtCallableSymbol): KtClassOrObjectSymbol? {
require(symbol is KtFirSymbol<*>) require(symbol is KtFirSymbol<*>)
return symbol.firRef.withFir { firDeclaration -> return symbol.firRef.withFir(FirResolvePhase.STATUS) { firDeclaration ->
if (firDeclaration !is FirCallableDeclaration) return@withFir null if (firDeclaration !is FirCallableDeclaration) return@withFir null
with(analysisSession) { with(analysisSession) {
getOriginalOverriddenSymbol(firDeclaration)?.containingClass()?.classId?.getCorrespondingToplevelClassOrObjectSymbol() getOriginalOverriddenSymbol(firDeclaration)?.containingClass()?.classId?.getCorrespondingToplevelClassOrObjectSymbol()
@@ -81,7 +81,7 @@ class KtFirOverrideInfoProvider(
override fun getOriginalOverriddenSymbol(symbol: KtCallableSymbol): KtCallableSymbol? { override fun getOriginalOverriddenSymbol(symbol: KtCallableSymbol): KtCallableSymbol? {
require(symbol is KtFirSymbol<*>) require(symbol is KtFirSymbol<*>)
return symbol.firRef.withFir { firDeclaration -> return symbol.firRef.withFir(FirResolvePhase.STATUS) { firDeclaration ->
if (firDeclaration !is FirCallableDeclaration) return@withFir null if (firDeclaration !is FirCallableDeclaration) return@withFir null
with(analysisSession) { with(analysisSession) {
getOriginalOverriddenSymbol(firDeclaration) getOriginalOverriddenSymbol(firDeclaration)
@@ -111,4 +111,4 @@ class KtFirOverrideInfoProvider(
* to call this function inside itself - and it requires write lock, since each layer might want to call resolve and to use write lock. * to call this function inside itself - and it requires write lock, since each layer might want to call resolve and to use write lock.
*/ */
private inline fun <D : FirDeclaration, R> FirRefWithValidityCheck<D>.withFirWithResolveAllowed(crossinline action: (D) -> R): R = private inline fun <D : FirDeclaration, R> FirRefWithValidityCheck<D>.withFirWithResolveAllowed(crossinline action: (D) -> R): R =
withFirWithPossibleResolveInside(phase = FirResolvePhase.RAW_FIR, action) withFirWithPossibleResolveInside(phase = FirResolvePhase.RAW_FIR, action)