[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
@@ -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,