[FIR] Cleanup detection that applicability is successful

This commit is contained in:
Dmitriy Novozhilov
2020-09-08 12:05:13 +03:00
parent 68f3d84e22
commit 19707667fd
7 changed files with 19 additions and 15 deletions
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorResolvedQualifier
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) { class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
@@ -65,7 +65,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString()) is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString())
is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, diagnostic.candidateSymbol) is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, diagnostic.candidateSymbol)
is ConeInapplicableCandidateError -> FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidateSymbol) is ConeInapplicableCandidateError -> FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidateSymbol)
is ConeAmbiguityError -> if (diagnostic.applicability < CandidateApplicability.SYNTHETIC_RESOLVED) { is ConeAmbiguityError -> if (!diagnostic.applicability.isSuccess) {
FirErrors.NONE_APPLICABLE.on(source, diagnostic.candidates) FirErrors.NONE_APPLICABLE.on(source, diagnostic.candidates)
} else { } else {
FirErrors.AMBIGUITY.on(source, diagnostic.candidates) FirErrors.AMBIGUITY.on(source, diagnostic.candidates)
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
class FirCallResolver( class FirCallResolver(
@@ -149,7 +150,7 @@ class FirCallResolver(
info, info,
) )
val bestCandidates = result.bestCandidates() val bestCandidates = result.bestCandidates()
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { val reducedCandidates = if (!result.currentApplicability.isSuccess) {
bestCandidates.toSet() bestCandidates.toSet()
} else { } else {
val onSuperReference = (explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference val onSuperReference = (explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference
@@ -157,7 +158,7 @@ class FirCallResolver(
bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference
) )
} }
if ((reducedCandidates.isEmpty() || result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) && if ((reducedCandidates.isEmpty() || !result.currentApplicability.isSuccess) &&
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
) { ) {
val approximatedQualifiedAccess = qualifiedAccess.transformExplicitReceiver(integerLiteralTypeApproximator, null) val approximatedQualifiedAccess = qualifiedAccess.transformExplicitReceiver(integerLiteralTypeApproximator, null)
@@ -192,8 +193,7 @@ class FirCallResolver(
) )
if (qualifiedAccess.explicitReceiver == null) { if (qualifiedAccess.explicitReceiver == null) {
if (result.applicability < CandidateApplicability.SYNTHETIC_RESOLVED if (!result.applicability.isSuccess) {
) {
// 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
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier -> qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
@@ -260,7 +260,7 @@ class FirCallResolver(
manager = TowerResolveManager(localCollector), manager = TowerResolveManager(localCollector),
) )
val bestCandidates = result.bestCandidates() val bestCandidates = result.bestCandidates()
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED val noSuccessfulCandidates = !result.currentApplicability.isSuccess
val reducedCandidates = if (noSuccessfulCandidates) { val reducedCandidates = if (noSuccessfulCandidates) {
bestCandidates.toSet() bestCandidates.toSet()
} else { } else {
@@ -419,7 +419,7 @@ class FirCallResolver(
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector, callInfo: CallInfo call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector, callInfo: CallInfo
): FirDelegatedConstructorCall { ): FirDelegatedConstructorCall {
val bestCandidates = result.bestCandidates() val bestCandidates = result.bestCandidates()
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { val reducedCandidates = if (!result.currentApplicability.isSuccess) {
bestCandidates.toSet() bestCandidates.toSet()
} else { } else {
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = true) conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = true)
@@ -498,7 +498,7 @@ class FirCallResolver(
name name
) )
applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> { !applicability.isSuccess -> {
val candidate = candidates.single() val candidate = candidates.single()
val diagnostic = when (applicability) { val diagnostic = when (applicability) {
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol) CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
open class CandidateCollector( open class CandidateCollector(
val components: BodyResolveComponents, val components: BodyResolveComponents,
@@ -50,7 +51,7 @@ open class CandidateCollector(
isSuccess() && bestGroup < group isSuccess() && bestGroup < group
fun isSuccess(): Boolean { fun isSuccess(): Boolean {
return currentApplicability >= CandidateApplicability.SYNTHETIC_RESOLVED return currentApplicability.isSuccess
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.PrivateForInline import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
abstract class CheckerSink { abstract class CheckerSink {
@@ -52,6 +53,6 @@ class CheckerSinkImpl(
} }
override val needYielding: Boolean override val needYielding: Boolean
get() = stopOnFirstError && current < CandidateApplicability.SYNTHETIC_RESOLVED get() = stopOnFirstError && !current.isSuccess
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
@@ -35,7 +36,7 @@ class ResolutionStageRunner(val components: InferenceComponents) {
while (!finished) { while (!finished) {
sink.continuation!!.resume(Unit) sink.continuation!!.resume(Unit)
if (sink.current < CandidateApplicability.SYNTHETIC_RESOLVED) { if (!sink.current.isSuccess) {
break break
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.model.StubTypeMarker import org.jetbrains.kotlin.types.model.StubTypeMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.types.model.freshTypeConstructor import org.jetbrains.kotlin.types.model.freshTypeConstructor
@@ -78,7 +79,7 @@ class PostponedArgumentsAnalyzer(
?: Pair(null, CandidateApplicability.INAPPLICABLE) ?: Pair(null, CandidateApplicability.INAPPLICABLE)
val namedReference = when { val namedReference = when {
resultingCandidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> resultingCandidate == null || !applicability.isSuccess ->
buildErrorNamedReference { buildErrorNamedReference {
source = callableReferenceAccess.source source = callableReferenceAccess.source
diagnostic = ConeUnresolvedReferenceError(callableReferenceAccess.calleeReference.name) diagnostic = ConeUnresolvedReferenceError(callableReferenceAccess.calleeReference.name)
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolve
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
class SingleCandidateResolver( class SingleCandidateResolver(
private val firSession: FirSession, private val firSession: FirSession,
@@ -70,7 +70,7 @@ class SingleCandidateResolver(
) )
val applicability = resolutionStageRunner.processCandidate(candidate, stopOnFirstError = true) val applicability = resolutionStageRunner.processCandidate(candidate, stopOnFirstError = true)
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) { if (applicability.isSuccess) {
return completeResolvedCandidate(candidate, resolutionParameters) return completeResolvedCandidate(candidate, resolutionParameters)
} }
return null return null