[FIR IDE] Ensure resolve to CONTRACTS phase in ReturnTypeCalculator

If we want to analyse some function's call, we need to know about its
contracts, otherwise resolving the following code would be broken.
Computing return type of function is a prerequisite to using it in any
sensible way, so it's the best place to resolve it to CONTRACTS

KT-50733
This commit is contained in:
Roman Golyshev
2022-05-27 13:30:19 +04:00
committed by Space
parent e14ac2a062
commit 166c771e1b
59 changed files with 260 additions and 64 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.resolve.FirRegularTowerDataContexts
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.TransformImplicitType
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
@@ -225,6 +227,8 @@ private class ReturnTypeCalculatorWithJump(
)
}
resolvedToContractsIfNecessary(declaration)
val returnTypeRef = declaration.returnTypeRef
if (returnTypeRef is FirResolvedTypeRef) return returnTypeRef
@@ -257,6 +261,20 @@ private class ReturnTypeCalculatorWithJump(
}
}
private fun resolvedToContractsIfNecessary(declaration: FirCallableDeclaration) {
if (declaration.resolvePhase >= FirResolvePhase.CONTRACTS) return
val canHaveContracts = when {
declaration is FirProperty && !declaration.isLocal -> true
declaration is FirSimpleFunction && !declaration.isLocal -> true
else -> false
}
if (canHaveContracts) {
declaration.ensureResolved(FirResolvePhase.CONTRACTS)
}
}
@OptIn(PrivateForInline::class)
private fun computeReturnTypeRef(declaration: FirCallableDeclaration): FirResolvedTypeRef {
// To properly transform and resolve declaration's type, we need to use its module's session