From 090c2998d2fe2e293ab8f554c550789e5bfe5e01 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 18 Jan 2019 11:21:14 +0300 Subject: [PATCH] Add running additional receiver checkers in new inference That commit fix next diagnostics: * RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS * NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS (partially, see #KT-29367) --- .../tower/KotlinToResolvedCallTransformer.kt | 33 +++++++++++++++++++ .../calls/tower/ResolvedAtomCompleter.kt | 1 + 2 files changed, 34 insertions(+) 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 92022f222d2..d47939eab21 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 @@ -12,10 +12,12 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver +import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.DiagnosticReporterByTrackingStrategy import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext import org.jetbrains.kotlin.resolve.calls.components.AdditionalDiagnosticReporter @@ -53,6 +55,7 @@ import java.util.* class KotlinToResolvedCallTransformer( private val callCheckers: Iterable, + private val additionalTypeCheckers: Iterable, private val dataFlowAnalyzer: DataFlowAnalyzer, private val argumentTypeResolver: ArgumentTypeResolver, private val constantExpressionEvaluator: ConstantExpressionEvaluator, @@ -202,6 +205,36 @@ class KotlinToResolvedCallTransformer( } } + fun runAdditionalReceiversCheckers(resolvedCall: ResolvedCall<*>, context: BasicCallResolutionContext) { + context.checkReceiver( + resolvedCall, + resolvedCall.resultingDescriptor.extensionReceiverParameter, + resolvedCall.extensionReceiver, + resolvedCall.explicitReceiverKind.isExtensionReceiver, + implicitInvokeCheck = false + ) + context.checkReceiver( + resolvedCall, + resolvedCall.resultingDescriptor.dispatchReceiverParameter, + resolvedCall.dispatchReceiver, + resolvedCall.explicitReceiverKind.isDispatchReceiver, + implicitInvokeCheck = context.call is CallTransformer.CallForImplicitInvoke + ) + + } + + private fun BasicCallResolutionContext.checkReceiver( + resolvedCall: ResolvedCall<*>, + receiverParameter: ReceiverParameterDescriptor?, + receiverArgument: ReceiverValue?, + isExplicitReceiver: Boolean, + implicitInvokeCheck: Boolean + ) { + if (receiverParameter == null || receiverArgument == null) return + val safeAccess = isExplicitReceiver && !implicitInvokeCheck && resolvedCall.call.isSemanticallyEquivalentToSafeCall + additionalTypeCheckers.forEach { it.checkReceiver(receiverParameter, receiverArgument, safeAccess, this) } + } + // todo very beginning code fun runArgumentsChecks( context: BasicCallResolutionContext, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index 6794c70f7a0..76fe7001c62 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -99,6 +99,7 @@ class ResolvedAtomCompleter( kotlinToResolvedCallTransformer.runArgumentsChecks(topLevelCallContext, topLevelTrace, lastCall as NewResolvedCallImpl<*>) kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, callCheckerContext) + kotlinToResolvedCallTransformer.runAdditionalReceiversCheckers(resolvedCall, topLevelCallContext) return resolvedCall }