[Analysis API FIR] fix candidate collection for delegatedConstructor call

^KTIJ-20446
This commit is contained in:
Ilya Kirillov
2022-07-20 19:20:49 +02:00
parent 2c48d25c96
commit a0f0fa5a47
19 changed files with 457 additions and 39 deletions
@@ -79,6 +79,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated ext
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousWithInferredTypeParameters.kt");
}
@Test
@TestMetadata("delegatedConstructor.kt")
public void testDelegatedConstructor() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/delegatedConstructor.kt");
}
@Test
@TestMetadata("implicitInvoke.kt")
public void testImplicitInvoke() throws Exception {
@@ -207,6 +213,24 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated ext
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.kt");
}
@Test
@TestMetadata("delegatedConstructorApplicable.kt")
public void testDelegatedConstructorApplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorApplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicable.kt")
public void testDelegatedConstructorInapplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicableDifferentParametersCount.kt")
public void testDelegatedConstructorInapplicableDifferentParametersCount() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicableDifferentParametersCount.kt");
}
@Test
@TestMetadata("eqEqCall_fromAny.kt")
public void testEqEqCall_fromAny() throws Exception {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.expandedClass
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
@@ -843,6 +842,7 @@ internal class KtFirCallResolver(
resolveFragmentOfCall
).toKtCallCandidateInfos()
is FirResolvedQualifier -> toKtCallCandidateInfos()
is FirDelegatedConstructorCall -> collectCallCandidatesForDelegatedConstructorCall(psi, resolveFragmentOfCall)
else -> toKtCallInfo(psi, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall).toKtCallCandidateInfos()
}
}
@@ -912,6 +912,26 @@ internal class KtFirCallResolver(
}
}
private fun FirDelegatedConstructorCall.collectCallCandidatesForDelegatedConstructorCall(
psi: KtElement,
resolveFragmentOfCall: Boolean
): List<KtCallCandidateInfo> {
val candidates = AllCandidatesResolver(analysisSession.useSiteSession).getAllCandidatesForDelegatedConstructor(
analysisSession.firResolveSession,
this,
psi
)
return candidates.mapNotNull {
convertToKtCallCandidateInfo(
this,
psi,
it.candidate,
it.isInBestCandidates,
resolveFragmentOfCall
)
}
}
private fun KtCallInfo?.toKtCallCandidateInfos(): List<KtCallCandidateInfo> {
return when (this) {
is KtSuccessCallInfo -> listOf(KtApplicableCallCandidateInfo(call, isInBestCandidates = true))
@@ -921,13 +941,13 @@ internal class KtFirCallResolver(
}
private fun convertToKtCallCandidateInfo(
functionCall: FirFunctionCall,
resolvable: FirResolvable,
element: KtElement,
candidate: Candidate,
isInBestCandidates: Boolean,
resolveFragmentOfCall: Boolean
): KtCallCandidateInfo? {
val call = createKtCall(element, functionCall, candidate, resolveFragmentOfCall)
val call = createKtCall(element, resolvable, candidate, resolveFragmentOfCall)
?: error("expect `createKtCall` to succeed for candidate")
if (candidate.isSuccessful) {
return KtApplicableCallCandidateInfo(call, isInBestCandidates)
@@ -936,7 +956,7 @@ internal class KtFirCallResolver(
val diagnostic = createConeDiagnosticForCandidateWithError(candidate.currentApplicability, candidate)
if (diagnostic is ConeHiddenCandidateError) return null
val ktDiagnostic =
functionCall.source?.let { diagnostic.asKtDiagnostic(it, element.toKtPsiSourceElement()) }
resolvable.source?.let { diagnostic.asKtDiagnostic(it, element.toKtPsiSourceElement()) }
?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token)
return KtInapplicableCallCandidateInfo(call, isInBestCandidates, ktDiagnostic)
}
@@ -79,6 +79,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated exte
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousWithInferredTypeParameters.kt");
}
@Test
@TestMetadata("delegatedConstructor.kt")
public void testDelegatedConstructor() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/delegatedConstructor.kt");
}
@Test
@TestMetadata("implicitInvoke.kt")
public void testImplicitInvoke() throws Exception {
@@ -207,6 +213,24 @@ public class FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated exte
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.kt");
}
@Test
@TestMetadata("delegatedConstructorApplicable.kt")
public void testDelegatedConstructorApplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorApplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicable.kt")
public void testDelegatedConstructorInapplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicableDifferentParametersCount.kt")
public void testDelegatedConstructorInapplicableDifferentParametersCount() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicableDifferentParametersCount.kt");
}
@Test
@TestMetadata("eqEqCall_fromAny.kt")
public void testEqEqCall_fromAny() throws Exception {
@@ -79,6 +79,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerat
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousWithInferredTypeParameters.kt");
}
@Test
@TestMetadata("delegatedConstructor.kt")
public void testDelegatedConstructor() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/delegatedConstructor.kt");
}
@Test
@TestMetadata("implicitInvoke.kt")
public void testImplicitInvoke() throws Exception {
@@ -207,6 +213,24 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerat
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.kt");
}
@Test
@TestMetadata("delegatedConstructorApplicable.kt")
public void testDelegatedConstructorApplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorApplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicable.kt")
public void testDelegatedConstructorInapplicable() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicable.kt");
}
@Test
@TestMetadata("delegatedConstructorInapplicableDifferentParametersCount.kt")
public void testDelegatedConstructorInapplicableDifferentParametersCount() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/delegatedConstructorInapplicableDifferentParametersCount.kt");
}
@Test
@TestMetadata("eqEqCall_fromAny.kt")
public void testEqEqCall_fromAny() throws Exception {
@@ -0,0 +1,77 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with <init>>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(): A
valueParameters = []
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
isInBestCandidates = false
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with <init>>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(p: kotlin.String): A
valueParameters = [
KtVariableLikeSignature:
name = p
receiverType = null
returnType = kotlin.String
symbol = p: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = p
receiverType = null
returnType = kotlin.String
symbol = p: kotlin.String
callableIdIfNonLocal = null)
}
isInBestCandidates = false
KtApplicableCallCandidateInfo:
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(x: kotlin.Int): A
valueParameters = [
KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,6 @@
open class A(x: Int) {
protected constructor() : this(1) {}
private constructor(p: String) : this(2) {}
}
class B(): <expr>A</expr>(5)
@@ -0,0 +1,70 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<TOO_MANY_ARGUMENTS: Too many arguments for protected constructor(): R|A|>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(): A
valueParameters = []
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
isInBestCandidates = false
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<INVISIBLE_REFERENCE: Symbol constructor(p: String): A is invisible>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(p: kotlin.String): A
valueParameters = [
KtVariableLikeSignature:
name = p
receiverType = null
returnType = kotlin.String
symbol = p: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
isInBestCandidates = false
KtApplicableCallCandidateInfo:
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(x: kotlin.Int): A
valueParameters = [
KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,4 @@
open class A(x: Int) {
}
class B(): <expr>A</expr>(5)
@@ -0,0 +1,29 @@
KtApplicableCallCandidateInfo:
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(x: kotlin.Int): A
valueParameters = [
KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.Int
symbol = x: kotlin.Int
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,30 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with <init>>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(x: kotlin.String): A
valueParameters = [
KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.String
symbol = x: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.String
symbol = x: kotlin.String
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,4 @@
open class A(x: String) {
}
class B(): <expr>A</expr>(5)
@@ -0,0 +1,30 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Int but kotlin/String was expected>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(x: kotlin.String): A
valueParameters = [
KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.String
symbol = x: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = x
receiverType = null
returnType = kotlin.String
symbol = x: kotlin.String
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,16 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with <init>>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(): A
valueParameters = []
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
isInBestCandidates = true
@@ -0,0 +1,4 @@
open class A() {
}
class B(): <expr>A</expr>(5)
@@ -0,0 +1,16 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<TOO_MANY_ARGUMENTS: Too many arguments for public constructor(): R|A|>
candidate = KtDelegatedConstructorCall:
kind = SUPER_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = A
symbol = <constructor>(): A
valueParameters = []
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
isInBestCandidates = true
@@ -9,18 +9,48 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.OverloadCandidate
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
class AllCandidatesResolver(firSession: FirSession) {
private val bodyResolveComponents = createStubBodyResolveComponents(firSession)
class AllCandidatesResolver(private val firSession: FirSession) {
private val scopeSession = ScopeSession()
// This transformer is not intended for actual transformations and created here only to simplify access to resolve components
private val stubBodyResolveTransformer = FirBodyResolveTransformer(
session = firSession,
phase = FirResolvePhase.BODY_RESOLVE,
implicitTypeOnly = false,
scopeSession = scopeSession,
)
private val bodyResolveComponents = object : StubBodyResolveTransformerComponents(
firSession,
scopeSession,
stubBodyResolveTransformer,
stubBodyResolveTransformer.context,
) {
val collector = AllCandidatesCollector(this, resolutionStageRunner)
val towerResolver = FirTowerResolver(this, resolutionStageRunner, collector)
override val callResolver = FirCallResolver(this, towerResolver)
init {
callResolver.initTransformer(FirExpressionsResolveTransformer(stubBodyResolveTransformer))
}
}
private val resolutionContext = ResolutionContext(firSession, bodyResolveComponents, bodyResolveComponents.transformer.context)
fun getAllCandidates(
@@ -33,12 +63,25 @@ class AllCandidatesResolver(firSession: FirSession) {
val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession)
return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
bodyResolveComponents.callResolver.collectAllCandidates(
functionCall,
calleeName,
bodyResolveComponents.context.containers,
resolutionContext
)
bodyResolveComponents.callResolver
.collectAllCandidates(functionCall, calleeName, bodyResolveComponents.context.containers, resolutionContext)
}
}
fun getAllCandidatesForDelegatedConstructor(
firResolveSession: LLFirResolveSession,
delegatedConstructorCall: FirDelegatedConstructorCall,
element: KtElement
): List<OverloadCandidate> {
initializeBodyResolveContext(firResolveSession, element)
val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession)
val constructedType = delegatedConstructorCall.constructedTypeRef.coneType as ConeClassLikeType
return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
bodyResolveComponents.callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType)
bodyResolveComponents.collector.allCandidates.map {
OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates())
}
}
}
@@ -38,7 +38,7 @@ internal fun createStubBodyResolveComponents(firSession: FirSession): FirAbstrac
)
}
private class StubBodyResolveTransformerComponents(
internal open class StubBodyResolveTransformerComponents(
session: FirSession,
scopeSession: ScopeSession,
transformer: FirBodyResolveTransformer,
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class FirCallResolver(
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
private val towerResolver: FirTowerResolver = FirTowerResolver(components, components.resolutionStageRunner)
) {
private val session = components.session
private val overloadByLambdaReturnTypeResolver = FirOverloadByLambdaReturnTypeResolver(components)
@@ -63,10 +64,6 @@ class FirCallResolver(
this.transformer = transformer
}
private val towerResolver = FirTowerResolver(
components, components.resolutionStageRunner,
)
val conflictResolver: ConeCallConflictResolver =
session.callConflictResolverFactory.create(TypeSpecificityComparator.NONE, session.inferenceComponents, components)
@@ -168,24 +165,6 @@ class FirCallResolver(
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
resolutionContext: ResolutionContext = transformer.resolutionContext
): List<OverloadCandidate> {
class AllCandidatesCollector(
components: BodyResolveComponents,
resolutionStageRunner: ResolutionStageRunner
) : CandidateCollector(components, resolutionStageRunner) {
private val allCandidatesSet = mutableSetOf<Candidate>()
override fun consumeCandidate(group: TowerGroup, candidate: Candidate, context: ResolutionContext): CandidateApplicability {
allCandidatesSet += candidate
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()
}
val collector = AllCandidatesCollector(components, components.resolutionStageRunner)
val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular
val result =
@@ -843,3 +822,21 @@ class FirCallResolver(
/** A candidate in the overload candidate set. */
data class OverloadCandidate(val candidate: Candidate, val isInBestCandidates: Boolean)
class AllCandidatesCollector(
components: BodyResolveComponents,
resolutionStageRunner: ResolutionStageRunner
) : CandidateCollector(components, resolutionStageRunner) {
private val allCandidatesSet = mutableSetOf<Candidate>()
override fun consumeCandidate(group: TowerGroup, candidate: Candidate, context: ResolutionContext): CandidateApplicability {
allCandidatesSet += candidate
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()
}
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
class FirTowerResolver(
private val components: BodyResolveComponents,
resolutionStageRunner: ResolutionStageRunner,
private val collector: CandidateCollector = CandidateCollector(components, resolutionStageRunner)
) {
private val collector = CandidateCollector(components, resolutionStageRunner)
private val manager = TowerResolveManager(collector)
fun runResolver(