[NI] Fix shouldRunCompletion for builder inference session

#KT-41308 Fixed
#KT-41363
This commit is contained in:
Dmitriy Novozhilov
2020-08-25 11:56:36 +03:00
parent e98cbf81cf
commit 9cde42e2bc
22 changed files with 162 additions and 5 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.components.CompletedCallInfo
import org.jetbrains.kotlin.resolve.calls.components.NewConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.components.stableType
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.*
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.descriptorUtil.hasBuilderInferenceAnnotation
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
@@ -72,6 +74,10 @@ class CoroutineInferenceSession(
return subResolvedAtoms?.any { it.hasPostponed() } == true
}
if (!candidate.isSuitableForBuilderInference()) {
return true
}
return !storage.notFixedTypeVariables.keys.any {
val variable = storage.allTypeVariables[it]
val isPostponed = variable != null && variable in storage.postponedTypeVariables
@@ -79,6 +85,29 @@ class CoroutineInferenceSession(
} || candidate.getSubResolvedAtoms().any { it.hasPostponed() }
}
private fun KotlinResolutionCandidate.isSuitableForBuilderInference(): Boolean {
val extensionReceiver = resolvedCall.extensionReceiverArgument
val dispatchReceiver = resolvedCall.dispatchReceiverArgument
return when {
extensionReceiver == null && dispatchReceiver == null -> false
extensionReceiver == null -> true
extensionReceiver.receiver.stableType.containsStubType() -> resolvedCall.candidateDescriptor.hasBuilderInferenceAnnotation()
else -> true
}
}
private fun KotlinType.containsNotFixedTypeVariable(storage: ConstraintStorage): Boolean {
return this.contains {
it.constructor in storage.notFixedTypeVariables
}
}
private fun KotlinType.containsStubType(): Boolean {
return this.contains {
it is StubType
}
}
fun addSimpleCall(callExpression: KtExpression) {
simpleCommonCalls.add(callExpression)
}
@@ -332,7 +332,7 @@ class ResolvedAtomCompleter(
resolvedAtom: ResolvedCallableReferenceAtom
) {
val callableCandidate = resolvedAtom.candidate
if (callableCandidate == null) {
if (callableCandidate == null || resolvedAtom.completed) {
// todo report meanfull diagnostic here
return
}
@@ -420,6 +420,7 @@ class ResolvedAtomCompleter(
)
kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, topLevelCallCheckerContext)
resolvedAtom.completed = true
}
private fun ReceiverValue.updateReceiverValue(substitutor: TypeSubstitutor): ReceiverValue {