Fold initializer & if to elvis: search for variable usage inside if first #KT-14889 Fixed
This commit is contained in:
+13
-13
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// 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
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// 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
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user