[NI] Resolve callable reference eagerly at the end of resolution parts

This way we'll resolve less callable references later as we'll have
 more constraints to clip wrong candidates for callable references
This commit is contained in:
Mikhail Zarechenskiy
2019-04-05 12:39:34 +03:00
parent c3bc6ef2fa
commit ff2ce316e1
10 changed files with 86 additions and 11 deletions
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun resolveKtPrimitive(
csBuilder: ConstraintSystemBuilder,
callableReferenceResolver: CallableReferenceResolver,
argument: KotlinCallArgument,
expectedType: UnwrappedType?,
diagnosticsHolder: KotlinDiagnosticsHolder,
@@ -42,7 +41,7 @@ fun resolveKtPrimitive(
preprocessLambdaArgument(csBuilder, argument, expectedType)
is CallableReferenceKotlinCallArgument ->
preprocessCallableReference(csBuilder, callableReferenceResolver, argument, expectedType, diagnosticsHolder)
preprocessCallableReference(csBuilder, argument, expectedType, diagnosticsHolder)
is CollectionLiteralKotlinCallArgument ->
preprocessCollectionLiteralArgument(argument, expectedType)
@@ -142,13 +141,11 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(csBuilder
private fun preprocessCallableReference(
csBuilder: ConstraintSystemBuilder,
callableReferenceResolver: CallableReferenceResolver,
argument: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?,
diagnosticsHolder: KotlinDiagnosticsHolder
): ResolvedAtom {
val result = EagerCallableReferenceAtom(argument, expectedType)
callableReferenceResolver.processCallableReferenceArgument(csBuilder, result, diagnosticsHolder)
if (expectedType == null) return result
@@ -94,7 +94,7 @@ class PostponedArgumentsAnalyzer(
val subResolvedKtPrimitives = returnArguments.map {
resolveKtPrimitive(
c.getBuilder(), callableReferenceResolver, it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
)
}
@@ -5,15 +5,18 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.KnownTypeParameterConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.substitute
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
@@ -23,9 +26,9 @@ import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorMo
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
@@ -275,9 +278,7 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
isReceiver: Boolean
) {
val expectedType = candidateParameter?.let { prepareExpectedType(argument, candidateParameter) }
addResolvedKtPrimitive(
resolveKtPrimitive(csBuilder, callableReferenceResolver, argument, expectedType, this, isReceiver)
)
addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver))
}
private fun KotlinResolutionCandidate.prepareExpectedType(
@@ -368,6 +369,16 @@ internal object CheckExternalArgument : ResolutionPart() {
}
}
internal object EagerResolveOfCallableReferences : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
getSubResolvedAtoms()
.filterIsInstance<EagerCallableReferenceAtom>()
.forEach {
callableReferenceResolver.processCallableReferenceArgument(csBuilder, it, this)
}
}
}
internal object CheckInfixResolutionPart : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
val candidateDescriptor = resolvedCall.candidateDescriptor
@@ -213,6 +213,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CheckReceivers,
CheckArgumentsInParenthesis,
CheckExternalArgument,
EagerResolveOfCallableReferences,
PostponedVariablesInitializerResolutionPart
),
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
@@ -95,6 +95,8 @@ class KotlinResolutionCandidate(
currentApplicability = maxOf(diagnostic.candidateApplicability, currentApplicability)
}
fun getSubResolvedAtoms(): List<ResolvedAtom> = subResolvedAtoms
fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom) {
subResolvedAtoms.add(resolvedAtom)
}