K2: Pass resolution mode to CallInfo

It's going to be used for PCLA implementation in later commits

^KT-59791 In Progress
This commit is contained in:
Denis.Zharkov
2023-12-19 14:41:31 +01:00
committed by Space Team
parent 3b2bc49c4d
commit 9ae5287df8
10 changed files with 151 additions and 53 deletions
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate
import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
@@ -1068,7 +1069,8 @@ internal class KtFirCallResolver(
analysisSession.firResolveSession, analysisSession.firResolveSession,
originalFunctionCall, originalFunctionCall,
calleeName, calleeName,
psi psi,
ResolutionMode.ContextIndependent,
) )
return candidates.mapNotNull { return candidates.mapNotNull {
convertToKtCallCandidateInfo( convertToKtCallCandidateInfo(
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.FirSamResolver import org.jetbrains.kotlin.fir.resolve.FirSamResolver
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
@@ -50,12 +51,8 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsEr
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.PackageResolutionResult import org.jetbrains.kotlin.fir.resolve.transformers.PackageResolutionResult
import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.scopes.getProperties
import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -1005,7 +1002,7 @@ private class ElementsToShortenCollector(
} }
} }
val candidates = AllCandidatesResolver(shorteningContext.analysisSession.useSiteSession).getAllCandidates( val candidates = AllCandidatesResolver(shorteningContext.analysisSession.useSiteSession).getAllCandidates(
firResolveSession, fakeFirQualifiedAccess, name, expressionInScope firResolveSession, fakeFirQualifiedAccess, name, expressionInScope, ResolutionMode.ContextIndependent,
) )
return candidates.filter { overloadCandidate -> return candidates.filter { overloadCandidate ->
when (overloadCandidate.candidate.currentApplicability) { when (overloadCandidate.candidate.currentApplicability) {
@@ -1029,7 +1026,7 @@ private class ElementsToShortenCollector(
calleeReference = fakeCalleeReference calleeReference = fakeCalleeReference
} }
val candidates = AllCandidatesResolver(shorteningContext.analysisSession.useSiteSession).getAllCandidates( val candidates = AllCandidatesResolver(shorteningContext.analysisSession.useSiteSession).getAllCandidates(
firResolveSession, fakeFirQualifiedAccess, name, elementInScope firResolveSession, fakeFirQualifiedAccess, name, elementInScope, ResolutionMode.ContextIndependent,
) )
return candidates.filter { overloadCandidate -> return candidates.filter { overloadCandidate ->
overloadCandidate.candidate.currentApplicability == CandidateApplicability.RESOLVED overloadCandidate.candidate.currentApplicability == CandidateApplicability.RESOLVED
@@ -10,14 +10,17 @@ 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.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.AllCandidatesCollector
import org.jetbrains.kotlin.fir.FirCallResolver
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.OverloadCandidate
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.calleeReference import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
@@ -67,12 +70,19 @@ class AllCandidatesResolver(private val firSession: FirSession) {
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
calleeName: Name, calleeName: Name,
element: KtElement, element: KtElement,
resolutionMode: ResolutionMode,
): List<OverloadCandidate> { ): List<OverloadCandidate> {
initializeBodyResolveContext(firResolveSession, element) initializeBodyResolveContext(firResolveSession, element)
return run { return run {
bodyResolveComponents.callResolver bodyResolveComponents.callResolver
.collectAllCandidates(qualifiedAccess, calleeName, bodyResolveComponents.context.containers, resolutionContext) .collectAllCandidates(
qualifiedAccess,
calleeName,
bodyResolveComponents.context.containers,
resolutionContext,
resolutionMode,
)
.apply { postProcessCandidates() } .apply { postProcessCandidates() }
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.resolver
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.receiverType import org.jetbrains.kotlin.fir.types.receiverType
@@ -48,6 +49,7 @@ abstract class AbstractCandidateInfoProvider(
containingDeclarations = emptyList(), // TODO - maybe we should pass declarations from context here (no visible differences atm) containingDeclarations = emptyList(), // TODO - maybe we should pass declarations from context here (no visible differences atm)
containingFile = firFile, containingFile = firFile,
isImplicitInvoke = false, isImplicitInvoke = false,
resolutionMode = ResolutionMode.ContextIndependent,
isUsedAsGetClassReceiver = false, isUsedAsGetClassReceiver = false,
session = firSession, session = firSession,
) )
@@ -74,13 +74,19 @@ class FirCallResolver(
val conflictResolver: ConeCallConflictResolver = val conflictResolver: ConeCallConflictResolver =
session.callConflictResolverFactory.create(TypeSpecificityComparator.NONE, session.inferenceComponents, components) session.callConflictResolverFactory.create(TypeSpecificityComparator.NONE, session.inferenceComponents, components)
fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall): FirFunctionCall { fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, resolutionMode: ResolutionMode): FirFunctionCall {
val name = functionCall.calleeReference.name val name = functionCall.calleeReference.name
val result = collectCandidates(functionCall, name, origin = functionCall.origin) val result = collectCandidates(functionCall, name, origin = functionCall.origin, resolutionMode = resolutionMode)
var forceCandidates: Collection<Candidate>? = null var forceCandidates: Collection<Candidate>? = null
if (result.candidates.isEmpty()) { if (result.candidates.isEmpty()) {
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess, origin = functionCall.origin) val newResult = collectCandidates(
functionCall,
name,
CallKind.VariableAccess,
origin = functionCall.origin,
resolutionMode = resolutionMode
)
if (newResult.candidates.isNotEmpty()) { if (newResult.candidates.isNotEmpty()) {
forceCandidates = newResult.candidates forceCandidates = newResult.candidates
} }
@@ -139,14 +145,23 @@ class FirCallResolver(
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
name: Name, name: Name,
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations, containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
resolutionContext: ResolutionContext = transformer.resolutionContext resolutionContext: ResolutionContext = transformer.resolutionContext,
resolutionMode: ResolutionMode,
): List<OverloadCandidate> { ): List<OverloadCandidate> {
val collector = AllCandidatesCollector(components, components.resolutionStageRunner) val collector = AllCandidatesCollector(components, components.resolutionStageRunner)
val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular
val result = collectCandidates( val result =
qualifiedAccess, name, forceCallKind = null, isUsedAsGetClassReceiver = false, collectCandidates(
origin, containingDeclarations, resolutionContext, collector qualifiedAccess,
) name,
forceCallKind = null,
isUsedAsGetClassReceiver = false,
origin,
containingDeclarations,
resolutionContext,
collector,
resolutionMode = resolutionMode
)
return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) } return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) }
} }
@@ -160,6 +175,7 @@ class FirCallResolver(
resolutionContext: ResolutionContext = transformer.resolutionContext, resolutionContext: ResolutionContext = transformer.resolutionContext,
collector: CandidateCollector? = null, collector: CandidateCollector? = null,
callSite: FirElement = qualifiedAccess, callSite: FirElement = qualifiedAccess,
resolutionMode: ResolutionMode,
): ResolutionResult { ): ResolutionResult {
val explicitReceiver = qualifiedAccess.explicitReceiver val explicitReceiver = qualifiedAccess.explicitReceiver
val argumentList = (qualifiedAccess as? FirFunctionCall)?.argumentList ?: FirEmptyArgumentList val argumentList = (qualifiedAccess as? FirFunctionCall)?.argumentList ?: FirEmptyArgumentList
@@ -177,7 +193,8 @@ class FirCallResolver(
session, session,
components.file, components.file,
containingDeclarations, containingDeclarations,
origin = origin origin = origin,
resolutionMode = resolutionMode,
) )
towerResolver.reset() towerResolver.reset()
val result = towerResolver.runResolver(info, resolutionContext, collector) val result = towerResolver.runResolver(info, resolutionContext, collector)
@@ -228,15 +245,23 @@ class FirCallResolver(
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean, isUsedAsGetClassReceiver: Boolean,
callSite: FirElement, callSite: FirElement,
resolutionMode: ResolutionMode,
): FirStatement { ): FirStatement {
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite) { true } return resolveVariableAccessAndSelectCandidateImpl(
qualifiedAccess,
isUsedAsReceiver,
resolutionMode,
isUsedAsGetClassReceiver,
callSite
) { true }
} }
private fun resolveVariableAccessAndSelectCandidateImpl( private fun resolveVariableAccessAndSelectCandidateImpl(
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
resolutionMode: ResolutionMode,
isUsedAsGetClassReceiver: Boolean, isUsedAsGetClassReceiver: Boolean,
callSite: FirElement, callSite: FirElement = qualifiedAccess,
acceptCandidates: (Collection<Candidate>) -> Boolean, acceptCandidates: (Collection<Candidate>) -> Boolean,
): FirStatement { ): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
@@ -246,7 +271,7 @@ class FirCallResolver(
val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
val basicResult by lazy(LazyThreadSafetyMode.NONE) { val basicResult by lazy(LazyThreadSafetyMode.NONE) {
collectCandidates(qualifiedAccess, callee.name, isUsedAsGetClassReceiver = isUsedAsGetClassReceiver, callSite = callSite) collectCandidates(qualifiedAccess, callee.name, isUsedAsGetClassReceiver = isUsedAsGetClassReceiver, callSite = callSite, resolutionMode = resolutionMode)
} }
// Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful // Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful
@@ -286,7 +311,7 @@ class FirCallResolver(
var functionCallExpected = false var functionCallExpected = false
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) { if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) {
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function) val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function, resolutionMode = resolutionMode)
if (newResult.candidates.isNotEmpty()) { if (newResult.candidates.isNotEmpty()) {
result = newResult result = newResult
functionCallExpected = true functionCallExpected = true
@@ -488,6 +513,7 @@ class FirCallResolver(
session, session,
components.file, components.file,
components.containingDeclarations, components.containingDeclarations,
resolutionMode = ResolutionMode.ContextIndependent,
) )
towerResolver.reset() towerResolver.reset()
@@ -623,7 +649,8 @@ class FirCallResolver(
typeArguments = annotation.typeArguments, typeArguments = annotation.typeArguments,
session, session,
components.file, components.file,
components.containingDeclarations components.containingDeclarations,
resolutionMode = ResolutionMode.ContextIndependent,
) )
private fun getConstructorSymbol(annotationClassSymbol: FirRegularClassSymbol): FirConstructorSymbol? { private fun getConstructorSymbol(annotationClassSymbol: FirRegularClassSymbol): FirConstructorSymbol? {
@@ -700,6 +727,7 @@ class FirCallResolver(
components.file, components.file,
transformer.components.containingDeclarations, transformer.components.containingDeclarations,
candidateForCommonInvokeReceiver = null, candidateForCommonInvokeReceiver = null,
resolutionMode = ResolutionMode.ContextIndependent,
// Additional things for callable reference resolve // Additional things for callable reference resolve
expectedType, expectedType,
outerConstraintSystemBuilder, outerConstraintSystemBuilder,
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -37,6 +38,8 @@ data class CallInfo(
val candidateForCommonInvokeReceiver: Candidate? = null, val candidateForCommonInvokeReceiver: Candidate? = null,
val resolutionMode: ResolutionMode,
// Five properties for callable references only // Five properties for callable references only
val expectedType: ConeKotlinType? = null, val expectedType: ConeKotlinType? = null,
val outerCSBuilder: ConstraintSystemBuilder? = null, val outerCSBuilder: ConstraintSystemBuilder? = null,
@@ -80,7 +80,11 @@ class FirSyntheticCallGenerator(
assert(resolvable.calleeReference is FirStubReference) assert(resolvable.calleeReference is FirStubReference)
} }
fun generateCalleeForWhenExpression(whenExpression: FirWhenExpression, context: ResolutionContext): FirWhenExpression { fun generateCalleeForWhenExpression(
whenExpression: FirWhenExpression,
context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirWhenExpression {
assertSyntheticResolvableReferenceIsNotResolved(whenExpression) assertSyntheticResolvableReferenceIsNotResolved(whenExpression)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
@@ -91,13 +95,18 @@ class FirSyntheticCallGenerator(
whenSelectFunction, whenSelectFunction,
argumentList, argumentList,
SyntheticCallableId.WHEN.callableName, SyntheticCallableId.WHEN.callableName,
context = context context = context,
resolutionMode = resolutionMode,
) )
return whenExpression.transformCalleeReference(UpdateReference, reference) return whenExpression.transformCalleeReference(UpdateReference, reference)
} }
fun generateCalleeForTryExpression(tryExpression: FirTryExpression, context: ResolutionContext): FirTryExpression { fun generateCalleeForTryExpression(
tryExpression: FirTryExpression,
context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirTryExpression {
assertSyntheticResolvableReferenceIsNotResolved(tryExpression) assertSyntheticResolvableReferenceIsNotResolved(tryExpression)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
@@ -114,13 +123,18 @@ class FirSyntheticCallGenerator(
trySelectFunction, trySelectFunction,
argumentList, argumentList,
SyntheticCallableId.TRY.callableName, SyntheticCallableId.TRY.callableName,
context = context context = context,
resolutionMode = resolutionMode,
) )
return tryExpression.transformCalleeReference(UpdateReference, reference) return tryExpression.transformCalleeReference(UpdateReference, reference)
} }
fun generateCalleeForCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, context: ResolutionContext): FirCheckNotNullCall { fun generateCalleeForCheckNotNullCall(
checkNotNullCall: FirCheckNotNullCall,
context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirCheckNotNullCall {
assertSyntheticResolvableReferenceIsNotResolved(checkNotNullCall) assertSyntheticResolvableReferenceIsNotResolved(checkNotNullCall)
val reference = generateCalleeReferenceWithCandidate( val reference = generateCalleeReferenceWithCandidate(
@@ -128,13 +142,18 @@ class FirSyntheticCallGenerator(
checkNotNullFunction, checkNotNullFunction,
checkNotNullCall.argumentList, checkNotNullCall.argumentList,
SyntheticCallableId.CHECK_NOT_NULL.callableName, SyntheticCallableId.CHECK_NOT_NULL.callableName,
context = context context = context,
resolutionMode = resolutionMode,
) )
return checkNotNullCall.transformCalleeReference(UpdateReference, reference) return checkNotNullCall.transformCalleeReference(UpdateReference, reference)
} }
fun generateCalleeForElvisExpression(elvisExpression: FirElvisExpression, context: ResolutionContext): FirElvisExpression { fun generateCalleeForElvisExpression(
elvisExpression: FirElvisExpression,
context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirElvisExpression {
assertSyntheticResolvableReferenceIsNotResolved(elvisExpression) assertSyntheticResolvableReferenceIsNotResolved(elvisExpression)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
@@ -146,13 +165,14 @@ class FirSyntheticCallGenerator(
elvisFunction, elvisFunction,
argumentList, argumentList,
SyntheticCallableId.ELVIS_NOT_NULL.callableName, SyntheticCallableId.ELVIS_NOT_NULL.callableName,
context = context context = context,
resolutionMode = resolutionMode,
) )
return elvisExpression.transformCalleeReference(UpdateReference, reference) return elvisExpression.transformCalleeReference(UpdateReference, reference)
} }
fun generateSyntheticIdCall(arrayLiteral: FirExpression, context: ResolutionContext): FirFunctionCall { fun generateSyntheticIdCall(arrayLiteral: FirExpression, context: ResolutionContext, resolutionMode: ResolutionMode): FirFunctionCall {
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
arguments += arrayLiteral arguments += arrayLiteral
} }
@@ -163,7 +183,8 @@ class FirSyntheticCallGenerator(
idFunction, idFunction,
argumentList, argumentList,
SyntheticCallableId.ID.callableName, SyntheticCallableId.ID.callableName,
context = context context = context,
resolutionMode = resolutionMode,
) )
} }
} }
@@ -171,7 +192,8 @@ class FirSyntheticCallGenerator(
fun generateSyntheticArrayOfCall( fun generateSyntheticArrayOfCall(
arrayLiteral: FirArrayLiteral, arrayLiteral: FirArrayLiteral,
expectedTypeRef: FirTypeRef, expectedTypeRef: FirTypeRef,
context: ResolutionContext context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirFunctionCall { ): FirFunctionCall {
val argumentList = arrayLiteral.argumentList val argumentList = arrayLiteral.argumentList
val arrayOfSymbol = calculateArrayOfSymbol(expectedTypeRef) val arrayOfSymbol = calculateArrayOfSymbol(expectedTypeRef)
@@ -185,6 +207,7 @@ class FirSyntheticCallGenerator(
ArrayFqNames.ARRAY_OF_FUNCTION, ArrayFqNames.ARRAY_OF_FUNCTION,
callKind = CallKind.Function, callKind = CallKind.Function,
context = context, context = context,
resolutionMode,
) )
} ?: buildErrorNamedReference { } ?: buildErrorNamedReference {
diagnostic = ConeUnresolvedNameError(ArrayFqNames.ARRAY_OF_FUNCTION) diagnostic = ConeUnresolvedNameError(ArrayFqNames.ARRAY_OF_FUNCTION)
@@ -225,7 +248,8 @@ class FirSyntheticCallGenerator(
fun resolveCallableReferenceWithSyntheticOuterCall( fun resolveCallableReferenceWithSyntheticOuterCall(
callableReferenceAccess: FirCallableReferenceAccess, callableReferenceAccess: FirCallableReferenceAccess,
expectedTypeRef: FirTypeRef?, expectedTypeRef: FirTypeRef?,
context: ResolutionContext context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirCallableReferenceAccess { ): FirCallableReferenceAccess {
val argumentList = buildUnaryArgumentList(callableReferenceAccess) val argumentList = buildUnaryArgumentList(callableReferenceAccess)
@@ -235,7 +259,13 @@ class FirSyntheticCallGenerator(
else -> context.session.builtinTypes.anyType else -> context.session.builtinTypes.anyType
} }
var reference = generateCalleeReferenceWithCandidate(callableReferenceAccess, argumentList, parameterTypeRef, context) var reference = generateCalleeReferenceWithCandidate(
callableReferenceAccess,
argumentList,
parameterTypeRef,
context,
resolutionMode,
)
var initialCallWasUnresolved = false var initialCallWasUnresolved = false
if (reference is FirErrorReferenceWithCandidate && reference.diagnostic is ConeInapplicableCandidateError) { if (reference is FirErrorReferenceWithCandidate && reference.diagnostic is ConeInapplicableCandidateError) {
@@ -247,7 +277,13 @@ class FirSyntheticCallGenerator(
} }
reference = reference =
generateCalleeReferenceWithCandidate(callableReferenceAccess, argumentList, context.session.builtinTypes.anyType, context) generateCalleeReferenceWithCandidate(
callableReferenceAccess,
argumentList,
context.session.builtinTypes.anyType,
context,
resolutionMode,
)
initialCallWasUnresolved = true initialCallWasUnresolved = true
} }
@@ -308,6 +344,7 @@ class FirSyntheticCallGenerator(
argumentList: FirArgumentList, argumentList: FirArgumentList,
parameterTypeRef: FirResolvedTypeRef, parameterTypeRef: FirResolvedTypeRef,
context: ResolutionContext, context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirNamedReferenceWithCandidate { ): FirNamedReferenceWithCandidate {
val callableId = SyntheticCallableId.ACCEPT_SPECIFIC_TYPE val callableId = SyntheticCallableId.ACCEPT_SPECIFIC_TYPE
val functionSymbol = FirSyntheticFunctionSymbol(callableId) val functionSymbol = FirSyntheticFunctionSymbol(callableId)
@@ -324,6 +361,7 @@ class FirSyntheticCallGenerator(
callableId.callableName, callableId.callableName,
CallKind.SyntheticIdForCallableReferencesResolution, CallKind.SyntheticIdForCallableReferencesResolution,
context, context,
resolutionMode,
) )
} }
@@ -334,8 +372,9 @@ class FirSyntheticCallGenerator(
name: Name, name: Name,
callKind: CallKind = CallKind.SyntheticSelect, callKind: CallKind = CallKind.SyntheticSelect,
context: ResolutionContext, context: ResolutionContext,
resolutionMode: ResolutionMode,
): FirNamedReferenceWithCandidate { ): FirNamedReferenceWithCandidate {
val callInfo = generateCallInfo(callSite, name, argumentList, callKind) val callInfo = generateCallInfo(callSite, name, argumentList, callKind, resolutionMode)
val candidate = generateCandidate(callInfo, function, context) val candidate = generateCandidate(callInfo, function, context)
val applicability = components.resolutionStageRunner.processCandidate(candidate, context) val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
val source = callSite.source?.fakeElement(KtFakeSourceElementKind.SyntheticCall) val source = callSite.source?.fakeElement(KtFakeSourceElementKind.SyntheticCall)
@@ -367,6 +406,7 @@ class FirSyntheticCallGenerator(
name: Name, name: Name,
argumentList: FirArgumentList, argumentList: FirArgumentList,
callKind: CallKind, callKind: CallKind,
resolutionMode: ResolutionMode,
) = CallInfo( ) = CallInfo(
callSite = callSite, callSite = callSite,
callKind = callKind, callKind = callKind,
@@ -378,7 +418,8 @@ class FirSyntheticCallGenerator(
typeArguments = emptyList(), typeArguments = emptyList(),
session = session, session = session,
containingFile = components.file, containingFile = components.file,
containingDeclarations = components.containingDeclarations containingDeclarations = components.containingDeclarations,
resolutionMode = resolutionMode,
) )
private fun generateSyntheticSelectTypeParameter( private fun generateSyntheticSelectTypeParameter(
@@ -88,7 +88,11 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
resolutionModeForBranches, resolutionModeForBranches,
) )
whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression, resolutionContext) whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(
whenExpression,
resolutionContext,
data,
)
completionNeeded = true completionNeeded = true
} }
} }
@@ -161,7 +165,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
dataFlowAnalyzer.exitTryMainBlock() dataFlowAnalyzer.exitTryMainBlock()
tryExpression.transformCatches(this, ResolutionMode.ContextDependent) tryExpression.transformCatches(this, ResolutionMode.ContextDependent)
val incomplete = syntheticCallGenerator.generateCalleeForTryExpression(tryExpression, resolutionContext) val incomplete = syntheticCallGenerator.generateCalleeForTryExpression(tryExpression, resolutionContext, data)
var result = callCompleter.completeCall(incomplete, data) var result = callCompleter.completeCall(incomplete, data)
if (result.finallyBlock != null) { if (result.finallyBlock != null) {
dataFlowAnalyzer.enterFinallyBlock() dataFlowAnalyzer.enterFinallyBlock()
@@ -255,7 +259,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
elvisExpression.transformRhs(transformer, resolutionModeForRhs) elvisExpression.transformRhs(transformer, resolutionModeForRhs)
val result = callCompleter.completeCall( val result = callCompleter.completeCall(
syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext), data syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext, data), data
) )
var isLhsNotNull = false var isLhsNotNull = false
@@ -155,7 +155,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
callSite = when (data) { callSite = when (data) {
is ResolutionMode.AssignmentLValue -> data.variableAssignment is ResolutionMode.AssignmentLValue -> data.variableAssignment
else -> qualifiedAccessExpression else -> qualifiedAccessExpression
} },
data,
) )
// NB: here we can get raw expression because of dropped qualifiers (see transform callee), // NB: here we can get raw expression because of dropped qualifiers (see transform callee),
// so candidate existence must be checked before calling completion // so candidate existence must be checked before calling completion
@@ -222,9 +223,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean, isUsedAsGetClassReceiver: Boolean,
callSite: FirElement, callSite: FirElement,
data: ResolutionMode,
): FirStatement { ): FirStatement {
return callResolver.resolveVariableAccessAndSelectCandidate( return callResolver.resolveVariableAccessAndSelectCandidate(
qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite, data
) )
} }
@@ -437,7 +439,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
} }
val resultExpression = context.inferenceSession.onCandidatesResolution(withTransformedArguments) { val resultExpression = context.inferenceSession.onCandidatesResolution(withTransformedArguments) {
callResolver.resolveCallAndSelectCandidate(withTransformedArguments) callResolver.resolveCallAndSelectCandidate(withTransformedArguments, data)
} }
val completeInference = callCompleter.completeCall(resultExpression, data) val completeInference = callCompleter.completeCall(resultExpression, data)
@@ -950,7 +952,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
.replaceArgumentList(checkNotNullCall.argumentList.transform(transformer, ResolutionMode.ContextDependent)) .replaceArgumentList(checkNotNullCall.argumentList.transform(transformer, ResolutionMode.ContextDependent))
val result = callCompleter.completeCall( val result = callCompleter.completeCall(
components.syntheticCallGenerator.generateCalleeForCheckNotNullCall(checkNotNullCall, resolutionContext), data components.syntheticCallGenerator.generateCalleeForCheckNotNullCall(checkNotNullCall, resolutionContext, data), data
) )
if (checkNotNullCall.arguments.firstOrNull()?.coneTypeOrNull !is ConeDynamicType) { if (checkNotNullCall.arguments.firstOrNull()?.coneTypeOrNull !is ConeDynamicType) {
@@ -1069,7 +1071,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
callableReferenceAccess callableReferenceAccess
} else { } else {
components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall( components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall(
callableReferenceAccess, data.expectedType, resolutionContext, callableReferenceAccess, data.expectedType, resolutionContext, data
) )
}.also { }.also {
dataFlowAnalyzer.exitCallableReference(it) dataFlowAnalyzer.exitCallableReference(it)
@@ -1647,13 +1649,22 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
// Default value of array parameter (Array<T> or primitive array such as IntArray, FloatArray, ...) // Default value of array parameter (Array<T> or primitive array such as IntArray, FloatArray, ...)
// or argument for array parameter in annotation call. // or argument for array parameter in annotation call.
arrayLiteral.transformChildren(transformer, ResolutionMode.ContextDependent) arrayLiteral.transformChildren(transformer, ResolutionMode.ContextDependent)
val call = components.syntheticCallGenerator.generateSyntheticArrayOfCall(arrayLiteral, data.expectedTypeRef, resolutionContext) val call = components.syntheticCallGenerator.generateSyntheticArrayOfCall(
arrayLiteral,
data.expectedTypeRef,
resolutionContext,
data,
)
callCompleter.completeCall(call, data) callCompleter.completeCall(call, data)
arrayOfCallTransformer.transformFunctionCall(call, session) arrayOfCallTransformer.transformFunctionCall(call, session)
} }
else -> { else -> {
// Other unsupported usage. // Other unsupported usage.
val syntheticIdCall = components.syntheticCallGenerator.generateSyntheticIdCall(arrayLiteral, resolutionContext) val syntheticIdCall = components.syntheticCallGenerator.generateSyntheticIdCall(
arrayLiteral,
resolutionContext,
data,
)
arrayLiteral.transformChildren(transformer, ResolutionMode.ContextDependent) arrayLiteral.transformChildren(transformer, ResolutionMode.ContextDependent)
callCompleter.completeCall(syntheticIdCall, data) callCompleter.completeCall(syntheticIdCall, data)
arrayLiteral arrayLiteral
@@ -9,7 +9,6 @@ import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
import org.jetbrains.kotlin.fir.extensions.* import org.jetbrains.kotlin.fir.extensions.*
@@ -190,7 +189,8 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean, isUsedAsGetClassReceiver: Boolean,
callSite: FirElement callSite: FirElement,
data: ResolutionMode,
): FirStatement { ): FirStatement {
qualifiedAccessExpression.resolveFromImportScope() qualifiedAccessExpression.resolveFromImportScope()
return qualifiedAccessExpression return qualifiedAccessExpression