Document&use CandidateApplicability.shouldStopResolve/isSuccess properly
This commit is contained in:
+2
-3
@@ -8,9 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
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.K2_DSL_SCOPE_VIOLATION
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.K2_SYNTHETIC_RESOLVED
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.shouldStopResolve
|
||||
|
||||
open class CandidateCollector(
|
||||
val components: BodyResolveComponents,
|
||||
@@ -53,7 +52,7 @@ open class CandidateCollector(
|
||||
shouldStopResolve && bestGroup < group
|
||||
|
||||
private val shouldStopResolve: Boolean
|
||||
get() = currentApplicability == K2_DSL_SCOPE_VIOLATION || currentApplicability >= K2_SYNTHETIC_RESOLVED
|
||||
get() = currentApplicability.shouldStopResolve
|
||||
|
||||
val isSuccess: Boolean
|
||||
get() = currentApplicability.isSuccess
|
||||
|
||||
+13
-2
@@ -25,7 +25,7 @@ enum class CandidateApplicability {
|
||||
// Below has isSuccess = true
|
||||
RESOLVED_LOW_PRIORITY,
|
||||
K2_PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful.
|
||||
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
|
||||
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that change resolve
|
||||
|
||||
// Tower resolve does not go to further scopes if candidate with applicability below is found
|
||||
|
||||
@@ -34,5 +34,16 @@ enum class CandidateApplicability {
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
}
|
||||
|
||||
/**
|
||||
* This property determines that the considered candidate is "successful" in terms of having no resolve errors.
|
||||
* Note that it does not necessarily mean tower resolve should stop on this candidate.
|
||||
*/
|
||||
val CandidateApplicability.isSuccess: Boolean
|
||||
get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||
get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY && this != CandidateApplicability.K1_RESOLVED_WITH_ERROR
|
||||
|
||||
/**
|
||||
* This property determines that tower resolve should stop on the candidate/group with this applicability
|
||||
* and should not go to further scope levels. Note that candidate can still have error(s).
|
||||
*/
|
||||
val CandidateApplicability.shouldStopResolve: Boolean
|
||||
get() = this == CandidateApplicability.K2_DSL_SCOPE_VIOLATION || this >= CandidateApplicability.K2_SYNTHETIC_RESOLVED
|
||||
|
||||
+5
-1
@@ -29,9 +29,13 @@ sealed class ResolutionCandidate : Candidate, KotlinDiagnosticsHolder {
|
||||
override val isSuccessful: Boolean
|
||||
get() {
|
||||
processParts(stopOnFirstError = true)
|
||||
return resultingApplicabilities.minOrNull()!!.isSuccess && !getSystem().hasContradiction
|
||||
// Note: candidate with K1_RESOLVED_WITH_ERROR is exceptionally treated as successful
|
||||
return resultingApplicabilities.minOrNull()!!.isSuccessOrSuccessWithError && !getSystem().hasContradiction
|
||||
}
|
||||
|
||||
private val CandidateApplicability.isSuccessOrSuccessWithError: Boolean
|
||||
get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||
|
||||
override val resultingApplicability: CandidateApplicability
|
||||
get() {
|
||||
processParts(stopOnFirstError = false)
|
||||
|
||||
@@ -424,30 +424,30 @@ class TowerResolver {
|
||||
if (!isSuccessful) return null
|
||||
var compatibilityCandidate: C? = null
|
||||
var compatibilityGroup: Collection<C>? = null
|
||||
var firstGroupWithResolved: Collection<C>? = null
|
||||
var shouldStopGroup: Collection<C>? = null
|
||||
outer@ for (group in candidateGroups) {
|
||||
for (candidate in group) {
|
||||
if (isSuccessfulCandidate(candidate)) {
|
||||
firstGroupWithResolved = group
|
||||
if (shouldStopResolveOnCandidate(candidate)) {
|
||||
shouldStopGroup = group
|
||||
break@outer
|
||||
}
|
||||
|
||||
if (compatibilityCandidate == null && isSuccessfulPreserveCompatibility(candidate)) {
|
||||
if (compatibilityCandidate == null && isPreserveCompatibilityCandidate(candidate)) {
|
||||
compatibilityGroup = group
|
||||
compatibilityCandidate = candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstGroupWithResolved == null) return null
|
||||
if (shouldStopGroup == null) return null
|
||||
if (compatibilityCandidate != null
|
||||
&& compatibilityGroup !== firstGroupWithResolved
|
||||
&& compatibilityGroup !== shouldStopGroup
|
||||
&& needToReportCompatibilityWarning(compatibilityCandidate)
|
||||
) {
|
||||
firstGroupWithResolved.forEach { it.addCompatibilityWarning(compatibilityCandidate) }
|
||||
shouldStopGroup.forEach { it.addCompatibilityWarning(compatibilityCandidate) }
|
||||
}
|
||||
|
||||
return firstGroupWithResolved.filter(::isSuccessfulCandidate)
|
||||
return shouldStopGroup.filter(::shouldStopResolveOnCandidate)
|
||||
}
|
||||
|
||||
private fun needToReportCompatibilityWarning(candidate: C) = candidate is ResolutionCandidate &&
|
||||
@@ -455,12 +455,11 @@ class TowerResolver {
|
||||
(it.constraintSystemError as? LowerPriorityToPreserveCompatibility)?.needToReportWarning == true
|
||||
}
|
||||
|
||||
private fun isSuccessfulCandidate(candidate: C): Boolean {
|
||||
return candidate.resultingApplicability == CandidateApplicability.RESOLVED
|
||||
|| candidate.resultingApplicability == CandidateApplicability.K1_RESOLVED_WITH_ERROR
|
||||
private fun shouldStopResolveOnCandidate(candidate: C): Boolean {
|
||||
return candidate.resultingApplicability.shouldStopResolve
|
||||
}
|
||||
|
||||
private fun isSuccessfulPreserveCompatibility(candidate: C): Boolean =
|
||||
private fun isPreserveCompatibilityCandidate(candidate: C): Boolean =
|
||||
candidate.resultingApplicability == CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY
|
||||
|
||||
override fun pushCandidates(candidates: Collection<C>) {
|
||||
|
||||
Reference in New Issue
Block a user