FirCallResolver: reuse collectCandidates for variable access

This commit is contained in:
Mikhail Glukhikh
2020-04-22 13:59:16 +03:00
parent 4230a17427
commit 5446795d12
@@ -69,19 +69,20 @@ class FirCallResolver(
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent) functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
} }
var result = collectCandidates(functionCall) val name = functionCall.calleeReference.name
var result = collectCandidates(functionCall, name)
if ( if (
(result.candidates.isEmpty() || result.applicability < CandidateApplicability.SYNTHETIC_RESOLVED) && (result.candidates.isEmpty() || result.applicability < CandidateApplicability.SYNTHETIC_RESOLVED) &&
functionCall.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null functionCall.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
) { ) {
functionCall = functionCall.transformExplicitReceiver(integerLiteralTypeApproximator, null) functionCall = functionCall.transformExplicitReceiver(integerLiteralTypeApproximator, null)
result = collectCandidates(functionCall) result = collectCandidates(functionCall, name)
} }
val nameReference = createResolvedNamedReference( val nameReference = createResolvedNamedReference(
functionCall.calleeReference, functionCall.calleeReference,
functionCall.calleeReference.name, name,
result.candidates, result.candidates,
result.applicability, result.applicability,
) )
@@ -112,18 +113,20 @@ class FirCallResolver(
val info: CallInfo, val applicability: CandidateApplicability, val candidates: Collection<Candidate>, val info: CallInfo, val applicability: CandidateApplicability, val candidates: Collection<Candidate>,
) )
private fun collectCandidates(functionCall: FirFunctionCall): ResolutionResult { private fun <T : FirQualifiedAccess> collectCandidates(qualifiedAccess: T, name: Name): ResolutionResult {
val explicitReceiver = functionCall.explicitReceiver val explicitReceiver = qualifiedAccess.explicitReceiver
val argumentList = functionCall.argumentList val argumentList = (qualifiedAccess as? FirFunctionCall)?.argumentList ?: FirEmptyArgumentList
val typeArguments = functionCall.typeArguments val typeArguments = (qualifiedAccess as? FirFunctionCall)?.typeArguments.orEmpty()
val info = CallInfo( val info = CallInfo(
CallKind.Function, if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
functionCall.calleeReference.name, name,
explicitReceiver, explicitReceiver,
argumentList, argumentList,
functionCall.safe, qualifiedAccess.safe,
isPotentialQualifierPart = false, isPotentialQualifierPart = qualifiedAccess !is FirFunctionCall &&
qualifiedAccess.explicitReceiver is FirResolvedQualifier &&
qualifiedResolver.isPotentialQualifierPartPosition(),
typeArguments, typeArguments,
session, session,
file, file,
@@ -138,7 +141,7 @@ class FirCallResolver(
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
bestCandidates.toSet() bestCandidates.toSet()
} else { } else {
val onSuperReference = (functionCall.explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference val onSuperReference = (explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference
conflictResolver.chooseMaximallySpecificCandidates( conflictResolver.chooseMaximallySpecificCandidates(
bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference
) )
@@ -157,42 +160,17 @@ class FirCallResolver(
return resolvedQualifierPart return resolvedQualifierPart
} }
val info = CallInfo( val result = collectCandidates(qualifiedAccess, callee.name)
CallKind.VariableAccess, val reducedCandidates = result.candidates
callee.name,
qualifiedAccess.explicitReceiver,
FirEmptyArgumentList,
qualifiedAccess.safe,
qualifiedAccess.explicitReceiver is FirResolvedQualifier && qualifiedResolver.isPotentialQualifierPartPosition(),
emptyList(),
session,
file,
transformer.components.implicitReceiverStack,
)
towerResolver.reset()
val result = towerResolver.runResolver(
implicitReceiverStack.receiversAsReversed(),
info,
)
val bestCandidates = result.bestCandidates()
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
bestCandidates.toSet()
} else {
val onSuperReference = (qualifiedAccess.explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference
conflictResolver.chooseMaximallySpecificCandidates(
bestCandidates, discriminateGenerics = false, discriminateAbstracts = onSuperReference
)
}
val nameReference = createResolvedNamedReference( val nameReference = createResolvedNamedReference(
callee, callee,
callee.name, callee.name,
reducedCandidates, reducedCandidates,
result.currentApplicability, result.applicability,
) )
if (qualifiedAccess.explicitReceiver == null) { if (qualifiedAccess.explicitReceiver == null) {
if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED if (result.applicability < CandidateApplicability.SYNTHETIC_RESOLVED
) { ) {
// We should run QualifierResolver if no successful candidates are available // We should run QualifierResolver if no successful candidates are available
// Otherwise expression (even ambiguous) beat qualifier // Otherwise expression (even ambiguous) beat qualifier