Don't report "Unsafe call with ? extension receiver" with smart-cast

#KT-29499 Fixed
This commit is contained in:
Mikhail Glukhikh
2019-03-01 17:08:20 +03:00
parent 4d19120d84
commit c714e599ea
2 changed files with 20 additions and 3 deletions
@@ -16,12 +16,17 @@ import com.intellij.ui.EditorTextField
import org.intellij.lang.regexp.RegExpFileType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.isNullabilityFlexible
import java.awt.BorderLayout
import java.util.regex.PatternSyntaxException
@@ -46,7 +51,8 @@ class PlatformExtensionReceiverOfInlineInspection : AbstractKotlinInspection() {
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
super.visitDotQualifiedExpression(expression)
if (!expression.languageVersionSettings.supportsFeature(LanguageFeature.NullabilityAssertionOnExtensionReceiver)) {
val languageVersionSettings = expression.languageVersionSettings
if (!languageVersionSettings.supportsFeature(LanguageFeature.NullabilityAssertionOnExtensionReceiver)) {
return
}
val nameRegex = nameRegex
@@ -56,13 +62,19 @@ class PlatformExtensionReceiverOfInlineInspection : AbstractKotlinInspection() {
return
}
val resolvedCall = expression.resolveToCall() ?: return
val context = expression.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = expression.getResolvedCall(context) ?: return
val extensionReceiverType = resolvedCall.extensionReceiver?.type ?: return
if (!extensionReceiverType.isNullabilityFlexible()) return
val descriptor = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return
if (!descriptor.isInline) return
val receiverExpression = expression.receiverExpression
val dataFlowValueFactory = receiverExpression.getResolutionFacade().getFrontendService(DataFlowValueFactory::class.java)
val dataFlow = dataFlowValueFactory.createDataFlowValue(receiverExpression, extensionReceiverType, context, descriptor)
val stableNullability = context.getDataFlowInfoBefore(receiverExpression).getStableNullability(dataFlow)
if (!stableNullability.canBeNull()) return
holder.registerProblem(
receiverExpression,
"Call of inline function with nullable extension receiver can provoke NPE in Kotlin 1.2+",
@@ -6,6 +6,11 @@ fun test() {
JavaClass.getNull().contentNotInline() // OK
JavaClass.getMy().contentNonExtensionInlineFun() // OK
val res = JavaClass.getNull()
if (res != null) {
res.toBoolean() // OK: KT-29499
}
}
fun String.contentNotInline() {}