diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/FoldInitializerAndIfToElvisIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/FoldInitializerAndIfToElvisIntention.kt index de09e2385423d604771d376e8318a2a7e2f712a8..ea1fbcf03fef7a601f9788c2d0eae6605ed48cac 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/FoldInitializerAndIfToElvisIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/FoldInitializerAndIfToElvisIntention.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.search.LocalSearchScope +import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.setType @@ -27,10 +29,7 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.expressionCo import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange -import org.jetbrains.kotlin.psi.psiUtil.endOffset -import org.jetbrains.kotlin.psi.psiUtil.siblings -import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.makeNotNullable @@ -107,21 +106,22 @@ class FoldInitializerAndIfToElvisIntention : SelfTargetingRangeIntention() ?: return null - if (prevStatement !is KtVariableDeclaration) return null + val prevStatement = (ifExpression.siblings(forward = false, withItself = false) + .firstIsInstanceOrNull() ?: return null) as? KtVariableDeclaration + prevStatement ?: return null if (prevStatement.nameAsName != value.getReferencedNameAsName()) return null val initializer = prevStatement.initializer ?: return null val then = ifExpression.then ?: return null val typeReference = (operationExpression as? KtIsExpression)?.typeReference - if (then is KtBlockExpression) { - val statement = then.statements.singleOrNull() ?: return null - return Data(initializer, prevStatement, statement, typeReference) - } - else { - return Data(initializer, prevStatement, then, typeReference) + val statement = if (then is KtBlockExpression) then.statements.singleOrNull() else then + statement ?: return null + + if (ReferencesSearch.search(prevStatement, LocalSearchScope(statement)).findFirst() != null) { + return null } + + return Data(initializer, prevStatement, statement, typeReference) } private fun PsiChildRange.withoutLastStatement(): PsiChildRange { diff --git a/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInside.kt b/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInside.kt new file mode 100644 index 0000000000000000000000000000000000000000..da066385f3b5a0a1097dd4763414c8d643d4c739 --- /dev/null +++ b/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInside.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false + +interface A { + val s: String +} + +fun foo() = Any() + +fun test(): String { + val y = foo() + if (y !is A) return y.toString() + return y.s +} \ No newline at end of file diff --git a/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInsideInTemplate.kt b/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInsideInTemplate.kt new file mode 100644 index 0000000000000000000000000000000000000000..615ba279e22735c3455355f0089248e5048ebce7 --- /dev/null +++ b/idea/testData/intentions/foldInitializerAndIfToElvis/UsedInsideInTemplate.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false + +interface A { + val s: String +} + +fun foo() = Any() + +fun test(): String { + val y = foo() + if (y !is A) return "Expected A: $y" + return y.s +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index cef5bdcfddf339623687c66a12db29dc4edb780d..0a4590870869bffcf5063bc0312acd5500c028f9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -7397,6 +7397,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("UsedInside.kt") + public void testUsedInside() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/foldInitializerAndIfToElvis/UsedInside.kt"); + doTest(fileName); + } + + @TestMetadata("UsedInsideInTemplate.kt") + public void testUsedInsideInTemplate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/foldInitializerAndIfToElvis/UsedInsideInTemplate.kt"); + doTest(fileName); + } + @TestMetadata("Var.kt") public void testVar() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/foldInitializerAndIfToElvis/Var.kt");