diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index c7c45d1e044..43946a02027 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -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( ): NewAbstractResolvedCall() { 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 get() = completedCall.argumentMappingByOriginal @@ -496,7 +496,7 @@ class NewVariableAsFunctionResolvedCallImpl( ): VariableAsFunctionResolvedCall, ResolvedCall by functionCall class StubOnlyResolvedCall(val candidate: SimpleKotlinResolutionCandidate): NewAbstractResolvedCall() { - 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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index 3318c527886..108df969cca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -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 { 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, 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 { @@ -403,11 +398,11 @@ class NewResolutionOldInference( invoke.resolvedCall as MutableResolvedCall, variable.resolvedCall as MutableResolvedCall ) - 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 { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 53e93ec1d18..91941e47117 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -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(singleCandidate, context, trace.takeUnless { isInapplicableReceiver }) @@ -211,12 +211,12 @@ class PSICallResolver( private fun Collection.areAllCompletedAndFailed() = all { it is ResolvedKotlinCall.CompletedResolvedKotlinCall && - !it.completedCall.resolutionStatus.resultingApplicability.isSuccess + !it.completedCall.resultingApplicability.isSuccess } private fun Collection.areAllCompletedAndInapplicable() = all { - val applicability = it.currentStatus.resultingApplicability + val applicability = it.resultingApplicability applicability == ResolutionCandidateApplicability.INAPPLICABLE || applicability == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER || applicability == ResolutionCandidateApplicability.HIDDEN diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt index a3096935253..a50373e241f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -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) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt index acb41ffd0e3..ec147ffc18d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt @@ -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().none { + candidate.getCandidateDiagnostics().filterIsInstance().none { it.receiver == receiver } && - candidate.status.diagnostics.filterIsInstance().none { + candidate.getCandidateDiagnostics().filterIsInstance().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().any { + val thereIsUnstableSmartCastError = candidate.getCandidateDiagnostics().filterIsInstance().any { it.argument == argument } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt index 0232530dbc5..2de5826fdd6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt @@ -68,9 +68,10 @@ class CallableReferenceCandidate( val explicitReceiverKind: ExplicitReceiverKind, val reflectionCandidateType: UnwrappedType, val numDefaults: Int, - override val status: ResolutionCandidateStatus + val diagnostics: List ) : 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( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index 487235db2ba..1b03d089fcf 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -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 { + var diagnostics = candidate.getCandidateDiagnostics() + if (isTopLevel) { + diagnostics += candidate.constraintSystem.diagnostics + } + diagnostics += additionalDiagnosticReporter.createAdditionalDiagnostics(candidate, resultingDescriptor) + return diagnostics } // true if we should complete this call diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index abb8fd298ad..3a8336f0a58 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -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() @@ -100,6 +92,7 @@ sealed class AbstractSimpleKotlinResolutionCandidate( addDiagnostics(initialDiagnostics) } + fun getCandidateDiagnostics(): List = diagnostics abstract val resolutionSequence: List } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt index 213eb30c2fb..eab32d32381 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt @@ -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, val lambdaArguments: List ): 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, val explicitReceiverKind: ExplicitReceiverKind, val dispatchReceiver: ReceiverValueWithSmartCastInfo?, val extensionReceiver: ReceiverValueWithSmartCastInfo?, val typeArguments: List, val argumentMappingByOriginal: Map - ): 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) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt index 20dc92bcff4..950ccd535c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt @@ -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) { - val resultingApplicability: ResolutionCandidateApplicability = diagnostics.asSequence().map { it.candidateApplicability }.max() - ?: RESOLVED -} +fun getResultApplicability(diagnostics: List) = diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability + ?: RESOLVED enum class ResolutionCandidateApplicability { RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index e97da56bccb..cf8fa35b7a4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -28,7 +28,7 @@ interface Candidate { // this operation should be very fast val isSuccessful: Boolean - val status: ResolutionCandidateStatus + val resultingApplicability: ResolutionCandidateApplicability } interface CandidateFactory { @@ -75,13 +75,13 @@ class TowerResolver { scopeTower: ImplicitScopeTower, processor: ScopeTowerProcessor, useOrder: Boolean - ): Collection = scopeTower.run(processor, SuccessfulResultCollector { it.status }, useOrder) + ): Collection = scopeTower.run(processor, SuccessfulResultCollector(), useOrder) fun collectAllCandidates( scopeTower: ImplicitScopeTower, processor: ScopeTowerProcessor ): Collection - = scopeTower.run(processor, AllCandidatesCollector { it.status }, false) + = scopeTower.run(processor, AllCandidatesCollector(), false) private fun ImplicitScopeTower.createNonLocalLevels(): List { val result = ArrayList() @@ -100,7 +100,7 @@ class TowerResolver { return result } - private fun ImplicitScopeTower.run( + private fun ImplicitScopeTower.run( processor: ScopeTowerProcessor, resultCollector: ResultCollector, useOrder: Boolean @@ -173,13 +173,13 @@ class TowerResolver { return resultCollector.getFinalCandidates() } - fun runWithEmptyTowerData( + fun runWithEmptyTowerData( processor: ScopeTowerProcessor, resultCollector: ResultCollector, useOrder: Boolean ): Collection = processTowerData(processor, resultCollector, useOrder, TowerData.Empty) ?: resultCollector.getFinalCandidates() - private fun processTowerData( + private fun processTowerData( processor: ScopeTowerProcessor, resultCollector: ResultCollector, useOrder: Boolean, @@ -203,14 +203,14 @@ class TowerResolver { } - abstract class ResultCollector(protected val getStatus: (C) -> ResolutionCandidateStatus) { + abstract class ResultCollector { abstract fun getSuccessfulCandidates(): Collection? abstract fun getFinalCandidates(): Collection fun pushCandidates(candidates: Collection) { 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) } - class AllCandidatesCollector(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector(getStatus) { + class AllCandidatesCollector: ResultCollector() { private val allCandidates = ArrayList() override fun getSuccessfulCandidates(): Collection? = null @@ -230,7 +230,7 @@ class TowerResolver { } } - class SuccessfulResultCollector(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector(getStatus) { + class SuccessfulResultCollector: ResultCollector() { private var currentCandidates: Collection = emptyList() private var currentLevel: ResolutionCandidateApplicability? = null @@ -247,10 +247,10 @@ class TowerResolver { override fun getFinalCandidates() = getResolved() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList() override fun addCandidates(candidates: Collection) { - 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 } } } }