提交 67788e39 编写于 作者: M Mikhail Glukhikh

Fold initializer & if to elvis: search for variable usage inside if first #KT-14889 Fixed

上级 ee1b741e
......@@ -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<KtIfExp
} as? KtNameReferenceExpression ?: return null
if (ifExpression.parent !is KtBlockExpression) return null
val prevStatement = ifExpression.siblings(forward = false, withItself = false)
.firstIsInstanceOrNull<KtExpression>() ?: return null
if (prevStatement !is KtVariableDeclaration) return null
val prevStatement = (ifExpression.siblings(forward = false, withItself = false)
.firstIsInstanceOrNull<KtExpression>() ?: 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 {
......
// IS_APPLICABLE: false
interface A {
val s: String
}
fun foo() = Any()
fun test(): String {
val y = foo()
<caret>if (y !is A) return y.toString()
return y.s
}
\ No newline at end of file
// IS_APPLICABLE: false
interface A {
val s: String
}
fun foo() = Any()
fun test(): String {
val y = foo()
<caret>if (y !is A) return "Expected A: $y"
return y.s
}
\ No newline at end of file
......@@ -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");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册