FIR: Avoid redundant calls to ensureResolved during call resolution

Call ensureResolved only once when creating a candidate
This commit is contained in:
Denis Zharkov
2020-08-26 13:29:41 +03:00
parent bf2fc10cd6
commit 67cc85e02b
8 changed files with 13 additions and 23 deletions
@@ -21,13 +21,11 @@ import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.transformers.phasedFir
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
@@ -521,7 +519,7 @@ class FirCallResolver(
if (explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null) {
if (coneSymbol is FirVariableSymbol) {
if (coneSymbol !is FirPropertySymbol ||
(coneSymbol.phasedFir() as FirMemberDeclaration).typeParameters.isEmpty()
(coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty()
) {
return buildResolvedNamedReference {
this.source = source
@@ -208,7 +208,7 @@ fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirReso
private fun BodyResolveComponents.typeFromSymbol(symbol: AbstractFirBasedSymbol<*>, makeNullable: Boolean): FirResolvedTypeRef {
return when (symbol) {
is FirCallableSymbol<*> -> {
val returnTypeRef = returnTypeCalculator.tryCalculateReturnType(symbol.phasedFir)
val returnTypeRef = returnTypeCalculator.tryCalculateReturnType(symbol.fir)
if (makeNullable) {
returnTypeRef.withReplacedConeType(
returnTypeRef.type.withNullability(ConeNullability.NULLABLE, session.typeContext),
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypePa
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructor
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.FirScope
@@ -68,16 +67,10 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
processConstructorsByName(
name, session, bodyResolveComponents,
includeInnerConstructors = includeInnerConstructors,
processor = {
with(bodyResolveComponents) { it.phasedFir }
processor(it)
}
processor
)
processFunctionsByName(name) {
with(bodyResolveComponents) { it.phasedFir }
processor(it)
}
processFunctionsByName(name, processor)
}
private fun FirScope.getFirstClassifierOrNull(name: Name): Pair<FirClassifierSymbol<*>, ConeSubstitutor>? {
@@ -15,7 +15,6 @@ import kotlin.coroutines.resume
class ResolutionStageRunner(val components: InferenceComponents) {
fun processCandidate(candidate: Candidate, stopOnFirstError: Boolean = true): CandidateApplicability {
val sink = CheckerSinkImpl(components, stopOnFirstError = stopOnFirstError)
with (candidate.bodyResolveComponents) { candidate.symbol.phasedFir }
var finished = false
sink.continuation = suspend {
candidate.callInfo.callKind.resolutionSequence.forEachIndexed { index, stage ->
@@ -89,7 +89,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
override fun Candidate.getReceiverType(): ConeKotlinType? {
val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null
val callable = with(bodyResolveComponents) { callableSymbol.phasedFir }
val callable = callableSymbol.fir
val receiverType = callable.receiverTypeRef?.coneType
if (receiverType != null) return receiverType
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
@@ -152,7 +152,7 @@ private fun FirExpression.isSuperReferenceExpression(): Boolean {
internal object MapArguments : ResolutionStage() {
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportApplicability(CandidateApplicability.HIDDEN)
val function = with(candidate.bodyResolveComponents) { symbol.phasedFir }
val function = symbol.fir
val mapping = mapArguments(callInfo.arguments, function)
candidate.argumentMapping = mapping.toArgumentToParameterMapping()
@@ -212,9 +212,7 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
else -> null
}
val fir: FirCallableDeclaration<*> = with(candidate.bodyResolveComponents) {
candidateSymbol.phasedFir
}
val fir: FirCallableDeclaration<*> = candidate.symbol.fir
val returnTypeRef = candidate.bodyResolveComponents.returnTypeCalculator.tryCalculateReturnType(fir)
// If the expected type is a suspend function type and the current argument of interest is a function reference, we need to do
@@ -5,9 +5,11 @@
package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -148,7 +150,7 @@ private class TowerScopeLevelProcessor(
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
builtInExtensionFunctionReceiverValue: ReceiverValue?
) {
with(candidateFactory.bodyResolveComponents) { symbol.phasedFir }
symbol.ensureResolved(FirResolvePhase.CONTRACTS, candidateFactory.bodyResolveComponents.session)
// Check explicit extension receiver for default package members
if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null &&
(implicitExtensionReceiverValue == null) != (explicitReceiver == null) &&
@@ -87,7 +87,7 @@ class MemberScopeTowerLevel(
if (candidate is FirCallableSymbol<*> &&
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
) {
val fir = with(bodyResolveComponents) { candidate.phasedFir }
val fir = candidate.fir
if ((fir as? FirConstructor)?.isInner == false) {
return@processScopeMembers
}
@@ -71,7 +71,7 @@ class FirCallCompletionResultsWriterTransformer(
qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate
): T {
val subCandidate = calleeReference.candidate
val declaration: FirDeclaration = subCandidate.symbol.phasedFir
val declaration: FirDeclaration = subCandidate.symbol.fir as FirDeclaration
val typeArguments = computeTypeArguments(qualifiedAccessExpression, subCandidate)
val typeRef = if (declaration is FirTypedDeclaration) {
val calculated = typeCalculator.tryCalculateReturnType(declaration)
@@ -417,7 +417,7 @@ class FirCallCompletionResultsWriterTransformer(
private fun computeTypeArgumentTypes(
candidate: Candidate,
): List<ConeKotlinType> {
val declaration = candidate.symbol.phasedFir as? FirCallableMemberDeclaration<*> ?: return emptyList()
val declaration = candidate.symbol.fir as? FirCallableMemberDeclaration<*> ?: return emptyList()
return declaration.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }
.map { candidate.substitutor.substituteOrSelf(it) }