If then to elvis: now not applicable for calls with nullable result #KT-14542 Fixed
This commit is contained in:
+8
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
|
|||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
|
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
|
||||||
@@ -26,6 +27,10 @@ import org.jetbrains.kotlin.idea.intentions.getLeftMostReceiverExpression
|
|||||||
import org.jetbrains.kotlin.idea.intentions.replaceFirstReceiver
|
import org.jetbrains.kotlin.idea.intentions.replaceFirstReceiver
|
||||||
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.calls.callUtil.getType
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode.Companion.PARTIAL
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.nullability
|
||||||
|
|
||||||
class IfThenToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfThenToElvisIntention::class)
|
class IfThenToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfThenToElvisIntention::class)
|
||||||
|
|
||||||
@@ -36,7 +41,7 @@ class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<KtIfExpre
|
|||||||
|
|
||||||
private fun KtExpression.clausesReplaceableByElvis(firstClause: KtExpression, secondClause: KtExpression) =
|
private fun KtExpression.clausesReplaceableByElvis(firstClause: KtExpression, secondClause: KtExpression) =
|
||||||
!firstClause.isNullOrBlockExpression() &&
|
!firstClause.isNullOrBlockExpression() &&
|
||||||
(secondClause.evaluatesTo(this) || secondClause.hasFirstReceiverOf(this)) &&
|
(secondClause.evaluatesTo(this) || secondClause.hasFirstReceiverOf(this) && !secondClause.isNullableExpression()) &&
|
||||||
!(firstClause is KtThrowExpression && firstClause.throwsNullPointerExceptionWithNoArguments())
|
!(firstClause is KtThrowExpression && firstClause.throwsNullPointerExceptionWithNoArguments())
|
||||||
|
|
||||||
private fun KtExpression.checkedExpression() = when (this) {
|
private fun KtExpression.checkedExpression() = when (this) {
|
||||||
@@ -72,6 +77,8 @@ class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<KtIfExpre
|
|||||||
return innerExpression is KtBlockExpression || innerExpression.node.elementType == KtNodeTypes.NULL
|
return innerExpression is KtBlockExpression || innerExpression.node.elementType == KtNodeTypes.NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtExpression.isNullableExpression() = getType(analyze(PARTIAL))?.nullability() != TypeNullability.NOT_NULL
|
||||||
|
|
||||||
private fun KtExpression.hasFirstReceiverOf(receiver: KtExpression): Boolean {
|
private fun KtExpression.hasFirstReceiverOf(receiver: KtExpression): Boolean {
|
||||||
val actualReceiver = (unwrapBlockOrParenthesis() as? KtDotQualifiedExpression)?.getLeftMostReceiverExpression() ?: return false
|
val actualReceiver = (unwrapBlockOrParenthesis() as? KtDotQualifiedExpression)?.getLeftMostReceiverExpression() ?: return false
|
||||||
return actualReceiver.evaluatesTo(receiver)
|
return actualReceiver.evaluatesTo(receiver)
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
|
||||||
|
fun foo(p: String?): String? {
|
||||||
|
return <caret>if (p != null) p.bar() else "a"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.bar(): String? = null
|
||||||
@@ -1404,6 +1404,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nullableThen.kt")
|
||||||
|
public void testNullableThen() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/branched/ifThenToElvis/nullableThen.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("otherBlockHasMoreThanOneStatement.kt")
|
@TestMetadata("otherBlockHasMoreThanOneStatement.kt")
|
||||||
public void testOtherBlockHasMoreThanOneStatement() throws Exception {
|
public void testOtherBlockHasMoreThanOneStatement() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/branched/ifThenToElvis/otherBlockHasMoreThanOneStatement.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/branched/ifThenToElvis/otherBlockHasMoreThanOneStatement.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user