Do not suggest !! on expression which is always null
Related to KT-14643
This commit is contained in:
committed by
Mikhail Glukhikh
parent
66bd9d63dd
commit
4f678fa85c
@@ -30,12 +30,15 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
|
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
@@ -128,11 +131,21 @@ class AddExclExclCallFix(psiElement: PsiElement, val checkImplicitReceivers: Boo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (psiElement is KtExpression) {
|
else if (psiElement is KtExpression) {
|
||||||
if (checkImplicitReceivers && psiElement.getResolvedCall(psiElement.analyze())?.getImplicitReceiverValue() != null) {
|
val context = psiElement.analyze()
|
||||||
|
if (checkImplicitReceivers && psiElement.getResolvedCall(context)?.getImplicitReceiverValue() != null) {
|
||||||
val expressionToReplace = psiElement.parent as? KtCallExpression ?: psiElement
|
val expressionToReplace = psiElement.parent as? KtCallExpression ?: psiElement
|
||||||
expressionToReplace.expressionForCall(implicitReceiver = true)
|
expressionToReplace.expressionForCall(implicitReceiver = true)
|
||||||
}
|
}
|
||||||
else psiElement.expressionForCall()
|
else {
|
||||||
|
context[BindingContext.EXPRESSION_TYPE_INFO, psiElement]?.let {
|
||||||
|
val type = it.type
|
||||||
|
if (type != null) {
|
||||||
|
val nullability = it.dataFlowInfo.getStableNullability(DataFlowValueFactory.createDataFlowValue(psiElement, type, context, psiElement.findModuleDescriptor()))
|
||||||
|
if (!nullability.canBeNonNull()) return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
psiElement.expressionForCall()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
null
|
null
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// "Add non-null asserted (!!) call" "false"
|
||||||
|
// ACTION: Add 'toString()' call
|
||||||
|
// ACTION: Change type of 'x' to 'String?'
|
||||||
|
// ACTION: Remove braces from 'if' statement
|
||||||
|
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||||
|
|
||||||
|
fun foo(arg: String?) {
|
||||||
|
if (arg == null) {
|
||||||
|
val x: String = arg<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -272,6 +272,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nullExpression.kt")
|
||||||
|
public void testNullExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addExclExclCall/nullExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("operationIn.kt")
|
@TestMetadata("operationIn.kt")
|
||||||
public void testOperationIn() throws Exception {
|
public void testOperationIn() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addExclExclCall/operationIn.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addExclExclCall/operationIn.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user