[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.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
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.*
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.modality
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.substitutorByMap
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.types.*
import org.jetbrains.kotlin.name.StandardClassIds
@@ -140,6 +138,9 @@ class JavaOverrideChecker internal constructor(
overrideCandidate: FirCallableDeclaration,
baseDeclaration: FirCallableDeclaration
): ConeSubstitutor {
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
if (!overrideCandidate.isTypeParameterDependent() && !baseDeclaration.isTypeParameterDependent()) {
return ConeSubstitutor.Empty
}
@@ -151,6 +152,10 @@ class JavaOverrideChecker internal constructor(
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
if (overrideCandidate.isStatic != baseDeclaration.isStatic) return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
// NB: overrideCandidate is from Java and has no receiver
val receiverTypeRef = baseDeclaration.receiverTypeRef
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 {
if (baseDeclaration.modality == Modality.FINAL) return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
val receiverTypeRef = baseDeclaration.receiverTypeRef
return when (overrideCandidate) {
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.FirTypeParameterRef
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.utils.visibility
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.FirTypeScope
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.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -222,6 +224,7 @@ class FirClassSubstitutionScope(
val receiverType = member.receiverTypeRef?.coneType
val newReceiverType = receiverType?.substitute(substitutor)
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, member.symbol) }
val newReturnType = returnType?.substitute(substitutor)
@@ -233,6 +236,7 @@ class FirClassSubstitutionScope(
val member = original.fir
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
// TODO: do we have fields with implicit type?
val newReturnType = returnType?.substitute() ?: return original
@@ -245,6 +249,7 @@ class FirClassSubstitutionScope(
val member = original.fir as FirSyntheticProperty
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
member.symbol.ensureResolved(FirResolvePhase.STATUS)
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, original) }
val newReturnType = returnType?.substitute()
@@ -108,6 +108,8 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
overrideCandidate: FirCallableDeclaration,
baseDeclaration: FirCallableDeclaration
): ConeSubstitutor? {
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
val substitutor = buildSubstitutorForOverridesCheck(overrideCandidate, baseDeclaration, session) ?: return null
if (
overrideCandidate.typeParameters.isNotEmpty() &&
@@ -134,7 +136,6 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
if (!isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)) return false
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
val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration) ?: return false
overrideCandidate.ensureResolved(FirResolvePhase.TYPES)
baseDeclaration.ensureResolved(FirResolvePhase.TYPES)
return isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)
}
}
@@ -71,7 +71,7 @@ class KtFirOverrideInfoProvider(
override fun getOriginalContainingClassForOverride(symbol: KtCallableSymbol): KtClassOrObjectSymbol? {
require(symbol is KtFirSymbol<*>)
return symbol.firRef.withFir { firDeclaration ->
return symbol.firRef.withFir(FirResolvePhase.STATUS) { firDeclaration ->
if (firDeclaration !is FirCallableDeclaration) return@withFir null
with(analysisSession) {
getOriginalOverriddenSymbol(firDeclaration)?.containingClass()?.classId?.getCorrespondingToplevelClassOrObjectSymbol()
@@ -81,7 +81,7 @@ class KtFirOverrideInfoProvider(
override fun getOriginalOverriddenSymbol(symbol: KtCallableSymbol): KtCallableSymbol? {
require(symbol is KtFirSymbol<*>)
return symbol.firRef.withFir { firDeclaration ->
return symbol.firRef.withFir(FirResolvePhase.STATUS) { firDeclaration ->
if (firDeclaration !is FirCallableDeclaration) return@withFir null
with(analysisSession) {
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.
*/
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)