Analysis API: Fix issues related to implicit invoke calls:

- Correctly set explicit receiver value.
- Restore original function call from FirImplicitFunctionCall (i.e.,
calls implicitly resolved to `invoke`) to get the correct name for
getting all candidates.
- Collect candidates at all tower levels.

Also make order of candidate calls in tests deterministic.
This commit is contained in:
Mark Punzalan
2022-01-31 17:58:32 +00:00
committed by Ilya Kirillov
parent ace826c570
commit 9b9da94a09
30 changed files with 763 additions and 109 deletions
@@ -178,6 +178,9 @@ class FirCallResolver(
return super.consumeCandidate(group, candidate, context)
}
// We want to get candidates at all tower levels.
override fun shouldStopAtTheLevel(group: TowerGroup): Boolean = false
val allCandidates: List<Candidate>
get() = allCandidatesSet.toList()
}
@@ -322,6 +322,11 @@ private inline fun <T : FirExpression> BodyResolveComponents.transformExpression
smartcastBuilder: () -> FirWrappedExpressionWithSmartcastBuilder<T>,
smartcastToNullBuilder: () -> FirWrappedExpressionWithSmartcastToNullBuilder<T>
): FirWrappedExpressionWithSmartcastBuilder<T>? {
// No need to check for smartcast if the expression was already resolved.
containingDeclarations.lastOrNull()?.let { closestDeclaration ->
if (closestDeclaration.resolvePhase >= FirResolvePhase.BODY_RESOLVE) return null
}
val (stability, typesFromSmartCast) = smartcastExtractor(expression) ?: return null
val smartcastStability = stability.impliedSmartcastStability
?: if (dataFlowAnalyzer.isAccessToUnstableLocalVariable(expression)) {
@@ -48,7 +48,7 @@ open class CandidateCollector(
fun bestCandidates(): List<Candidate> = candidates
fun shouldStopAtTheLevel(group: TowerGroup): Boolean =
open fun shouldStopAtTheLevel(group: TowerGroup): Boolean =
currentApplicability.shouldStopResolve && bestGroup < group
fun isSuccess(): Boolean {