Refactoring. Remove ResolutionCandidateStatus.
Use diagnostics directly. Also TowerCandidate since now know only about applicability and not about diagnostics itself.
This commit is contained in:
+3
-3
@@ -347,7 +347,7 @@ class KotlinToResolvedCallTransformer(
|
||||
val newContext = context.replaceBindingTrace(trackingTrace)
|
||||
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(constantExpressionEvaluator, newContext, completedCall.kotlinCall.psiKotlinCall)
|
||||
|
||||
for (diagnostic in completedCall.resolutionStatus.diagnostics) {
|
||||
for (diagnostic in completedCall.diagnostics) {
|
||||
trackingTrace.reported = false
|
||||
diagnostic.report(diagnosticReporter)
|
||||
|
||||
@@ -464,7 +464,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
): NewAbstractResolvedCall<D>() {
|
||||
override val kotlinCall: KotlinCall get() = completedCall.kotlinCall
|
||||
|
||||
override fun getStatus(): ResolutionStatus = completedCall.resolutionStatus.resultingApplicability.toResolutionStatus()
|
||||
override fun getStatus(): ResolutionStatus = completedCall.resultingApplicability.toResolutionStatus()
|
||||
|
||||
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
get() = completedCall.argumentMappingByOriginal
|
||||
@@ -496,7 +496,7 @@ class NewVariableAsFunctionResolvedCallImpl(
|
||||
): VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall
|
||||
|
||||
class StubOnlyResolvedCall<D : CallableDescriptor>(val candidate: SimpleKotlinResolutionCandidate): NewAbstractResolvedCall<D>() {
|
||||
override fun getStatus() = candidate.status.resultingApplicability.toResolutionStatus()
|
||||
override fun getStatus() = candidate.resultingApplicability.toResolutionStatus()
|
||||
|
||||
override fun getCandidateDescriptor(): D = candidate.candidateDescriptor as D
|
||||
override fun getResultingDescriptor(): D = candidate.descriptorWithFreshTypes as D
|
||||
|
||||
+16
-21
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallKind
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isBinaryRemOperator
|
||||
@@ -38,9 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
||||
import org.jetbrains.kotlin.resolve.calls.context.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceSupport
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
@@ -176,7 +173,7 @@ class NewResolutionOldInference(
|
||||
|
||||
// Temporary hack to resolve 'rem' as 'mod' if the first is do not present
|
||||
val emptyOrInapplicableCandidates = candidates.isEmpty() ||
|
||||
candidates.all { it.candidateStatus.resultingApplicability.isInapplicable }
|
||||
candidates.all { it.resultingApplicability.isInapplicable }
|
||||
if (isBinaryRemOperator && shouldUseOperatorRem && emptyOrInapplicableCandidates) {
|
||||
val deprecatedName = OperatorConventions.REM_TO_MOD_OPERATION_NAMES[name]
|
||||
val processorForDeprecatedName = kind.createTowerProcessor(this, deprecatedName!!, tracing, scopeTower, detailedReceiver, context)
|
||||
@@ -204,7 +201,7 @@ class NewResolutionOldInference(
|
||||
val resolvedCall = ResolvedCallImpl.create(candidate, candidateTrace, tracing, basicCallContext.dataFlowInfoForArguments)
|
||||
|
||||
if (candidate.descriptor.isHiddenInResolution(languageVersionSettings, basicCallContext.isSuperCall)) {
|
||||
return@map MyCandidate(ResolutionCandidateStatus(listOf(HiddenDescriptor)), resolvedCall)
|
||||
return@map MyCandidate(listOf(HiddenDescriptor), resolvedCall)
|
||||
}
|
||||
|
||||
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
|
||||
@@ -214,16 +211,16 @@ class NewResolutionOldInference(
|
||||
candidateResolver.performResolutionForCandidateCall(callCandidateResolutionContext, basicCallContext.checkArguments) // todo
|
||||
|
||||
val diagnostics = listOfNotNull(createPreviousResolveError(resolvedCall.status))
|
||||
MyCandidate(ResolutionCandidateStatus(diagnostics), resolvedCall)
|
||||
MyCandidate(diagnostics, resolvedCall)
|
||||
}
|
||||
if (basicCallContext.collectAllCandidates) {
|
||||
val allCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolvedCandidates),
|
||||
TowerResolver.AllCandidatesCollector { it.candidateStatus }, useOrder = false)
|
||||
TowerResolver.AllCandidatesCollector(), useOrder = false)
|
||||
return allCandidatesResult(allCandidates)
|
||||
}
|
||||
|
||||
val processedCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolvedCandidates),
|
||||
TowerResolver.SuccessfulResultCollector { it.candidateStatus }, useOrder = true)
|
||||
TowerResolver.SuccessfulResultCollector(), useOrder = true)
|
||||
|
||||
return convertToOverloadResults(processedCandidates, tracing, basicCallContext, languageVersionSettings)
|
||||
}
|
||||
@@ -240,7 +237,7 @@ class NewResolutionOldInference(
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): OverloadResolutionResultsImpl<D> {
|
||||
val resolvedCalls = candidates.map {
|
||||
val (status, resolvedCall) = it
|
||||
val (diagnostics, resolvedCall) = it
|
||||
if (resolvedCall is VariableAsFunctionResolvedCallImpl) {
|
||||
// todo hacks
|
||||
tracing.bindReference(resolvedCall.variableCall.trace, resolvedCall.variableCall)
|
||||
@@ -256,7 +253,7 @@ class NewResolutionOldInference(
|
||||
}
|
||||
|
||||
if (resolvedCall.status.possibleTransformToSuccess()) {
|
||||
for (error in status.diagnostics) {
|
||||
for (error in diagnostics) {
|
||||
when (error) {
|
||||
is UnsupportedInnerClassCall -> resolvedCall.trace.report(Errors.UNSUPPORTED.on(resolvedCall.call.callElement, error.message))
|
||||
is NestedClassViaInstanceReference -> tracing.nestedClassAccessViaInstanceReference(resolvedCall.trace, error.classDescriptor, resolvedCall.explicitReceiverKind)
|
||||
@@ -317,13 +314,11 @@ class NewResolutionOldInference(
|
||||
}
|
||||
|
||||
internal data class MyCandidate(
|
||||
val candidateStatus: ResolutionCandidateStatus,
|
||||
val diagnostics: List<KotlinCallDiagnostic>,
|
||||
val resolvedCall: MutableResolvedCall<*>
|
||||
) : Candidate {
|
||||
override val isSuccessful: Boolean
|
||||
get() = candidateStatus.resultingApplicability.isSuccess
|
||||
override val status: ResolutionCandidateStatus
|
||||
get() = candidateStatus
|
||||
override val resultingApplicability: ResolutionCandidateApplicability = getResultApplicability(diagnostics)
|
||||
override val isSuccessful get() = resultingApplicability.isSuccess
|
||||
}
|
||||
|
||||
private inner class CandidateFactoryImpl(
|
||||
@@ -358,12 +353,12 @@ class NewResolutionOldInference(
|
||||
if (parameterIsDynamic != argumentIsDynamic ||
|
||||
(parameterIsDynamic && !towerCandidate.descriptor.hasDynamicExtensionAnnotation())
|
||||
) {
|
||||
return MyCandidate(ResolutionCandidateStatus(listOf(HiddenExtensionRelatedToDynamicTypes)), candidateCall)
|
||||
return MyCandidate(listOf(HiddenExtensionRelatedToDynamicTypes), candidateCall)
|
||||
}
|
||||
}
|
||||
|
||||
if (towerCandidate.descriptor.isHiddenInResolution(languageVersionSettings, basicCallContext.isSuperCall)) {
|
||||
return MyCandidate(ResolutionCandidateStatus(listOf(HiddenDescriptor)), candidateCall)
|
||||
return MyCandidate(listOf(HiddenDescriptor), candidateCall)
|
||||
}
|
||||
|
||||
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
|
||||
@@ -375,7 +370,7 @@ class NewResolutionOldInference(
|
||||
val diagnostics = (towerCandidate.diagnostics +
|
||||
checkInfixAndOperator(basicCallContext.call, towerCandidate.descriptor) +
|
||||
createPreviousResolveError(candidateCall.status)).filterNotNull() // todo
|
||||
return MyCandidate(ResolutionCandidateStatus(diagnostics), candidateCall)
|
||||
return MyCandidate(diagnostics, candidateCall)
|
||||
}
|
||||
|
||||
private fun checkInfixAndOperator(call: Call, descriptor: CallableDescriptor): List<ResolutionDiagnostic> {
|
||||
@@ -403,11 +398,11 @@ class NewResolutionOldInference(
|
||||
invoke.resolvedCall as MutableResolvedCall<FunctionDescriptor>,
|
||||
variable.resolvedCall as MutableResolvedCall<VariableDescriptor>
|
||||
)
|
||||
assert(variable.candidateStatus.resultingApplicability.isSuccess) {
|
||||
assert(variable.resultingApplicability.isSuccess) {
|
||||
"Variable call must be success: $variable"
|
||||
}
|
||||
|
||||
return MyCandidate(ResolutionCandidateStatus(variable.candidateStatus.diagnostics + invoke.candidateStatus.diagnostics), resolvedCallImpl)
|
||||
return MyCandidate(variable.diagnostics + invoke.diagnostics, resolvedCallImpl)
|
||||
}
|
||||
|
||||
override fun factoryForVariable(stripExplicitReceiver: Boolean): CandidateFactory<MyCandidate> {
|
||||
|
||||
@@ -179,7 +179,7 @@ class PSICallResolver(
|
||||
1 -> {
|
||||
val singleCandidate = result.single()
|
||||
|
||||
val isInapplicableReceiver = singleCandidate.currentStatus.resultingApplicability == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
val isInapplicableReceiver = singleCandidate.resultingApplicability == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
|
||||
val resolvedCall = kotlinToResolvedCallTransformer.transformAndReport<D>(singleCandidate, context, trace.takeUnless { isInapplicableReceiver })
|
||||
|
||||
@@ -211,12 +211,12 @@ class PSICallResolver(
|
||||
private fun Collection<ResolvedKotlinCall>.areAllCompletedAndFailed() =
|
||||
all {
|
||||
it is ResolvedKotlinCall.CompletedResolvedKotlinCall &&
|
||||
!it.completedCall.resolutionStatus.resultingApplicability.isSuccess
|
||||
!it.completedCall.resultingApplicability.isSuccess
|
||||
}
|
||||
|
||||
private fun Collection<ResolvedKotlinCall>.areAllCompletedAndInapplicable() =
|
||||
all {
|
||||
val applicability = it.currentStatus.resultingApplicability
|
||||
val applicability = it.resultingApplicability
|
||||
applicability == ResolutionCandidateApplicability.INAPPLICABLE ||
|
||||
applicability == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER ||
|
||||
applicability == ResolutionCandidateApplicability.HIDDEN
|
||||
|
||||
@@ -82,7 +82,7 @@ class KotlinCallResolver(
|
||||
)
|
||||
}
|
||||
val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
|
||||
TowerResolver.SuccessfulResultCollector { it.status },
|
||||
TowerResolver.SuccessfulResultCollector(),
|
||||
useOrder = true)
|
||||
return choseMostSpecific(resolutionCallbacks, expectedType, candidates)
|
||||
}
|
||||
|
||||
+4
-4
@@ -42,7 +42,7 @@ class AdditionalDiagnosticReporter {
|
||||
}
|
||||
|
||||
private fun reportSmartCastOnReceiver(
|
||||
candidate: KotlinResolutionCandidate,
|
||||
candidate: SimpleKotlinResolutionCandidate,
|
||||
receiver: SimpleKotlinCallArgument?,
|
||||
parameter: ReceiverParameterDescriptor?
|
||||
): SmartCastDiagnostic? {
|
||||
@@ -53,11 +53,11 @@ class AdditionalDiagnosticReporter {
|
||||
|
||||
// todo may be we have smart cast to Int?
|
||||
return smartCastDiagnostic.takeIf {
|
||||
candidate.status.diagnostics.filterIsInstance<UnsafeCallError>().none {
|
||||
candidate.getCandidateDiagnostics().filterIsInstance<UnsafeCallError>().none {
|
||||
it.receiver == receiver
|
||||
}
|
||||
&&
|
||||
candidate.status.diagnostics.filterIsInstance<UnstableSmartCast>().none {
|
||||
candidate.getCandidateDiagnostics().filterIsInstance<UnstableSmartCast>().none {
|
||||
it.argument == receiver
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ class AdditionalDiagnosticReporter {
|
||||
for (argument in candidate.argumentMappingByOriginal[parameter.original]?.arguments ?: continue) {
|
||||
val smartCastDiagnostic = createSmartCastDiagnostic(argument, argument.getExpectedType(parameter)) ?: continue
|
||||
|
||||
val thereIsUnstableSmartCastError = candidate.status.diagnostics.filterIsInstance<UnstableSmartCast>().any {
|
||||
val thereIsUnstableSmartCastError = candidate.getCandidateDiagnostics().filterIsInstance<UnstableSmartCast>().any {
|
||||
it.argument == argument
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -68,9 +68,10 @@ class CallableReferenceCandidate(
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
val reflectionCandidateType: UnwrappedType,
|
||||
val numDefaults: Int,
|
||||
override val status: ResolutionCandidateStatus
|
||||
val diagnostics: List<KotlinCallDiagnostic>
|
||||
) : Candidate {
|
||||
override val isSuccessful get() = status.resultingApplicability.isSuccess
|
||||
override val resultingApplicability = getResultApplicability(diagnostics)
|
||||
override val isSuccessful get() = resultingApplicability.isSuccess
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,9 +185,9 @@ class CallableReferencesCandidateFactory(
|
||||
}
|
||||
|
||||
if (candidateDescriptor !is CallableMemberDescriptor) {
|
||||
val status = ResolutionCandidateStatus(listOf(NotCallableMemberReference(argument, candidateDescriptor)))
|
||||
return CallableReferenceCandidate(candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
||||
explicitReceiverKind, reflectionCandidateType, defaults, status)
|
||||
explicitReceiverKind, reflectionCandidateType, defaults,
|
||||
listOf(NotCallableMemberReference(argument, candidateDescriptor)))
|
||||
}
|
||||
|
||||
diagnostics.addAll(towerCandidate.diagnostics)
|
||||
@@ -205,7 +206,7 @@ class CallableReferencesCandidateFactory(
|
||||
}
|
||||
|
||||
return CallableReferenceCandidate(candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
||||
explicitReceiverKind, reflectionCandidateType, defaults, ResolutionCandidateStatus(diagnostics))
|
||||
explicitReceiverKind, reflectionCandidateType, defaults, diagnostics)
|
||||
}
|
||||
|
||||
private fun getArgumentAndReturnTypeUseMappingByExpectedType(
|
||||
|
||||
+20
-14
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.returnTypeOrNothing
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
||||
import org.jetbrains.kotlin.types.TypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -104,9 +103,9 @@ class KotlinCallCompleter(
|
||||
resolutionCallbacks: KotlinResolutionCallbacks
|
||||
): ResolvedKotlinCall.CompletedResolvedKotlinCall {
|
||||
val currentSubstitutor = c.buildResultingSubstitutor()
|
||||
val completedCall = candidate.toCompletedCall(currentSubstitutor)
|
||||
val completedCall = candidate.toCompletedCall(currentSubstitutor, isTopLevel = true)
|
||||
val competedCalls = c.innerCalls.map {
|
||||
it.candidate.toCompletedCall(currentSubstitutor)
|
||||
it.candidate.toCompletedCall(currentSubstitutor, isTopLevel = false)
|
||||
}
|
||||
for (postponedArgument in c.postponedArguments) {
|
||||
when (postponedArgument) {
|
||||
@@ -125,17 +124,17 @@ class KotlinCallCompleter(
|
||||
return ResolvedKotlinCall.CompletedResolvedKotlinCall(completedCall, competedCalls, c.lambdaArguments)
|
||||
}
|
||||
|
||||
private fun KotlinResolutionCandidate.toCompletedCall(substitutor: NewTypeSubstitutor): CompletedKotlinCall {
|
||||
private fun KotlinResolutionCandidate.toCompletedCall(substitutor: NewTypeSubstitutor, isTopLevel: Boolean): CompletedKotlinCall {
|
||||
if (this is VariableAsFunctionKotlinResolutionCandidate) {
|
||||
val variable = resolvedVariable.toCompletedCall(substitutor)
|
||||
val invoke = invokeCandidate.toCompletedCall(substitutor)
|
||||
val variable = resolvedVariable.toCompletedCall(substitutor, isTopLevel = false)
|
||||
val invoke = invokeCandidate.toCompletedCall(substitutor, isTopLevel)
|
||||
|
||||
return CompletedKotlinCall.VariableAsFunction(kotlinCall, variable, invoke)
|
||||
}
|
||||
return (this as SimpleKotlinResolutionCandidate).toCompletedCall(substitutor)
|
||||
return (this as SimpleKotlinResolutionCandidate).toCompletedCall(substitutor, isTopLevel)
|
||||
}
|
||||
|
||||
private fun SimpleKotlinResolutionCandidate.toCompletedCall(substitutor: NewTypeSubstitutor): CompletedKotlinCall.Simple {
|
||||
private fun SimpleKotlinResolutionCandidate.toCompletedCall(substitutor: NewTypeSubstitutor, isTopLevel: Boolean): CompletedKotlinCall.Simple {
|
||||
val containsCapturedTypes = descriptorWithFreshTypes.returnType?.contains { it is NewCapturedType } ?: false
|
||||
val resultingDescriptor = when {
|
||||
descriptorWithFreshTypes is FunctionDescriptor ||
|
||||
@@ -152,15 +151,22 @@ class KotlinCallCompleter(
|
||||
TypeApproximator().approximateToSuperType(substituted, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: substituted
|
||||
}
|
||||
|
||||
val status = computeStatus(this, resultingDescriptor)
|
||||
return CompletedKotlinCall.Simple(kotlinCall, candidateDescriptor, resultingDescriptor, status, explicitReceiverKind,
|
||||
val diagnostics = computeDiagnostics(this, resultingDescriptor, isTopLevel)
|
||||
return CompletedKotlinCall.Simple(kotlinCall, candidateDescriptor, resultingDescriptor, diagnostics, explicitReceiverKind,
|
||||
dispatchReceiverArgument?.receiver, extensionReceiver?.receiver, typeArguments, argumentMappingByOriginal)
|
||||
}
|
||||
|
||||
private fun computeStatus(candidate: SimpleKotlinResolutionCandidate, resultingDescriptor: CallableDescriptor): ResolutionCandidateStatus {
|
||||
val smartCasts = additionalDiagnosticReporter.createAdditionalDiagnostics(candidate, resultingDescriptor).takeIf { it.isNotEmpty() } ?:
|
||||
return candidate.status
|
||||
return ResolutionCandidateStatus(candidate.status.diagnostics + smartCasts)
|
||||
private fun computeDiagnostics(
|
||||
candidate: SimpleKotlinResolutionCandidate,
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
isTopLevel: Boolean
|
||||
): List<KotlinCallDiagnostic> {
|
||||
var diagnostics = candidate.getCandidateDiagnostics()
|
||||
if (isTopLevel) {
|
||||
diagnostics += candidate.constraintSystem.diagnostics
|
||||
}
|
||||
diagnostics += additionalDiagnosticReporter.createAdditionalDiagnostics(candidate, resultingDescriptor)
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
// true if we should complete this call
|
||||
|
||||
+7
-14
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.Candidate
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import java.util.*
|
||||
|
||||
@@ -49,8 +46,8 @@ class VariableAsFunctionKotlinResolutionCandidate(
|
||||
val invokeCandidate: SimpleKotlinResolutionCandidate
|
||||
) : KotlinResolutionCandidate() {
|
||||
override val isSuccessful: Boolean get() = resolvedVariable.isSuccessful && invokeCandidate.isSuccessful
|
||||
override val status: ResolutionCandidateStatus
|
||||
get() = ResolutionCandidateStatus(resolvedVariable.status.diagnostics + invokeCandidate.status.diagnostics)
|
||||
override val resultingApplicability: ResolutionCandidateApplicability
|
||||
get() = maxOf(resolvedVariable.resultingApplicability, invokeCandidate.resultingApplicability)
|
||||
|
||||
override val lastCall: SimpleKotlinResolutionCandidate get() = invokeCandidate
|
||||
}
|
||||
@@ -65,15 +62,10 @@ sealed class AbstractSimpleKotlinResolutionCandidate(
|
||||
return !hasErrors
|
||||
}
|
||||
|
||||
private var _status: ResolutionCandidateStatus? = null
|
||||
|
||||
override val status: ResolutionCandidateStatus
|
||||
override val resultingApplicability: ResolutionCandidateApplicability
|
||||
get() {
|
||||
if (_status == null) {
|
||||
process(stopOnFirstError = false)
|
||||
_status = ResolutionCandidateStatus(diagnostics + constraintSystem.diagnostics)
|
||||
}
|
||||
return _status!!
|
||||
process(stopOnFirstError = false)
|
||||
return getResultApplicability(diagnostics + constraintSystem.diagnostics)
|
||||
}
|
||||
|
||||
private val diagnostics = ArrayList<KotlinCallDiagnostic>()
|
||||
@@ -100,6 +92,7 @@ sealed class AbstractSimpleKotlinResolutionCandidate(
|
||||
addDiagnostics(initialDiagnostics)
|
||||
}
|
||||
|
||||
fun getCandidateDiagnostics(): List<KotlinCallDiagnostic> = diagnostics
|
||||
|
||||
abstract val resolutionSequence: List<ResolutionPart>
|
||||
}
|
||||
|
||||
+11
-10
@@ -19,49 +19,50 @@ package org.jetbrains.kotlin.resolve.calls.model
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getResultApplicability
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
|
||||
sealed class ResolvedKotlinCall {
|
||||
abstract val currentStatus: ResolutionCandidateStatus
|
||||
abstract val resultingApplicability: ResolutionCandidateApplicability
|
||||
|
||||
class CompletedResolvedKotlinCall(
|
||||
val completedCall: CompletedKotlinCall,
|
||||
val allInnerCalls: Collection<CompletedKotlinCall>,
|
||||
val lambdaArguments: List<PostponedLambdaArgument>
|
||||
): ResolvedKotlinCall() {
|
||||
override val currentStatus get() = completedCall.resolutionStatus
|
||||
override val resultingApplicability get() = completedCall.resultingApplicability
|
||||
}
|
||||
|
||||
class OnlyResolvedKotlinCall(val candidate: KotlinResolutionCandidate) : ResolvedKotlinCall() {
|
||||
override val currentStatus get() = candidate.status
|
||||
override val resultingApplicability get() = candidate.resultingApplicability
|
||||
}
|
||||
}
|
||||
|
||||
sealed class CompletedKotlinCall {
|
||||
abstract val resolutionStatus: ResolutionCandidateStatus
|
||||
abstract val resultingApplicability: ResolutionCandidateApplicability
|
||||
|
||||
class Simple(
|
||||
val kotlinCall: KotlinCall,
|
||||
val candidateDescriptor: CallableDescriptor,
|
||||
val resultingDescriptor: CallableDescriptor,
|
||||
override val resolutionStatus: ResolutionCandidateStatus,
|
||||
val diagnostics: List<KotlinCallDiagnostic>,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
val dispatchReceiver: ReceiverValueWithSmartCastInfo?,
|
||||
val extensionReceiver: ReceiverValueWithSmartCastInfo?,
|
||||
val typeArguments: List<UnwrappedType>,
|
||||
val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
): CompletedKotlinCall()
|
||||
): CompletedKotlinCall() {
|
||||
override val resultingApplicability = getResultApplicability(diagnostics)
|
||||
}
|
||||
|
||||
class VariableAsFunction(
|
||||
val kotlinCall: KotlinCall,
|
||||
val variableCall: Simple,
|
||||
val invokeCall: Simple
|
||||
): CompletedKotlinCall() {
|
||||
|
||||
override val resolutionStatus: ResolutionCandidateStatus =
|
||||
ResolutionCandidateStatus(variableCall.resolutionStatus.diagnostics + invokeCall.resolutionStatus.diagnostics)
|
||||
override val resultingApplicability get() = maxOf(variableCall.resultingApplicability, invokeCall.resultingApplicability)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -60,10 +60,8 @@ interface CandidateWithBoundDispatchReceiver {
|
||||
val dispatchReceiver: ReceiverValueWithSmartCastInfo?
|
||||
}
|
||||
|
||||
data class ResolutionCandidateStatus(val diagnostics: List<KotlinCallDiagnostic>) {
|
||||
val resultingApplicability: ResolutionCandidateApplicability = diagnostics.asSequence().map { it.candidateApplicability }.max()
|
||||
?: RESOLVED
|
||||
}
|
||||
fun getResultApplicability(diagnostics: List<KotlinCallDiagnostic>) = diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability
|
||||
?: RESOLVED
|
||||
|
||||
enum class ResolutionCandidateApplicability {
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
|
||||
@@ -28,7 +28,7 @@ interface Candidate {
|
||||
// this operation should be very fast
|
||||
val isSuccessful: Boolean
|
||||
|
||||
val status: ResolutionCandidateStatus
|
||||
val resultingApplicability: ResolutionCandidateApplicability
|
||||
}
|
||||
|
||||
interface CandidateFactory<out C: Candidate> {
|
||||
@@ -75,13 +75,13 @@ class TowerResolver {
|
||||
scopeTower: ImplicitScopeTower,
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
useOrder: Boolean
|
||||
): Collection<C> = scopeTower.run(processor, SuccessfulResultCollector { it.status }, useOrder)
|
||||
): Collection<C> = scopeTower.run(processor, SuccessfulResultCollector(), useOrder)
|
||||
|
||||
fun <C: Candidate> collectAllCandidates(
|
||||
scopeTower: ImplicitScopeTower,
|
||||
processor: ScopeTowerProcessor<C>
|
||||
): Collection<C>
|
||||
= scopeTower.run(processor, AllCandidatesCollector { it.status }, false)
|
||||
= scopeTower.run(processor, AllCandidatesCollector(), false)
|
||||
|
||||
private fun ImplicitScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
||||
val result = ArrayList<ScopeTowerLevel>()
|
||||
@@ -100,7 +100,7 @@ class TowerResolver {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <C> ImplicitScopeTower.run(
|
||||
private fun <C : Candidate> ImplicitScopeTower.run(
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
resultCollector: ResultCollector<C>,
|
||||
useOrder: Boolean
|
||||
@@ -173,13 +173,13 @@ class TowerResolver {
|
||||
return resultCollector.getFinalCandidates()
|
||||
}
|
||||
|
||||
fun <C> runWithEmptyTowerData(
|
||||
fun <C : Candidate> runWithEmptyTowerData(
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
resultCollector: ResultCollector<C>,
|
||||
useOrder: Boolean
|
||||
): Collection<C> = processTowerData(processor, resultCollector, useOrder, TowerData.Empty) ?: resultCollector.getFinalCandidates()
|
||||
|
||||
private fun <C> processTowerData(
|
||||
private fun <C : Candidate> processTowerData(
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
resultCollector: ResultCollector<C>,
|
||||
useOrder: Boolean,
|
||||
@@ -203,14 +203,14 @@ class TowerResolver {
|
||||
}
|
||||
|
||||
|
||||
abstract class ResultCollector<C>(protected val getStatus: (C) -> ResolutionCandidateStatus) {
|
||||
abstract class ResultCollector<C : Candidate> {
|
||||
abstract fun getSuccessfulCandidates(): Collection<C>?
|
||||
|
||||
abstract fun getFinalCandidates(): Collection<C>
|
||||
|
||||
fun pushCandidates(candidates: Collection<C>) {
|
||||
val filteredCandidates = candidates.filter {
|
||||
getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||
it.resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||
}
|
||||
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
||||
}
|
||||
@@ -218,7 +218,7 @@ class TowerResolver {
|
||||
protected abstract fun addCandidates(candidates: Collection<C>)
|
||||
}
|
||||
|
||||
class AllCandidatesCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
class AllCandidatesCollector<C : Candidate>: ResultCollector<C>() {
|
||||
private val allCandidates = ArrayList<C>()
|
||||
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = null
|
||||
@@ -230,7 +230,7 @@ class TowerResolver {
|
||||
}
|
||||
}
|
||||
|
||||
class SuccessfulResultCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
class SuccessfulResultCollector<C : Candidate>: ResultCollector<C>() {
|
||||
private var currentCandidates: Collection<C> = emptyList()
|
||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
||||
|
||||
@@ -247,10 +247,10 @@ class TowerResolver {
|
||||
override fun getFinalCandidates() = getResolved() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
val minimalLevel = candidates.map { getStatus(it).resultingApplicability }.min()!!
|
||||
val minimalLevel = candidates.map { it.resultingApplicability }.min()!!
|
||||
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
||||
currentLevel = minimalLevel
|
||||
currentCandidates = candidates.filter { getStatus(it).resultingApplicability == minimalLevel }
|
||||
currentCandidates = candidates.filter { it.resultingApplicability == minimalLevel }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user