Introduce Variable: Do not replace assignment left-hand sides
#KT-14240 Fixed
This commit is contained in:
@@ -252,6 +252,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
||||
- [`KT-14182`](https://youtrack.jetbrains.com/issue/KT-14182) Move: Show error message on applying to enum entries
|
||||
- Extract Function: Support implicit abnormal exits via Nothing-typed expressions
|
||||
- [`KT-14285`](https://youtrack.jetbrains.com/issue/KT-14285) Rename: Forbid on backing field reference
|
||||
- [`KT-14240`](https://youtrack.jetbrains.com/issue/KT-14240) Introduce Variable: Do not replace assignment left-hand sides
|
||||
|
||||
##### New features
|
||||
|
||||
|
||||
+11
@@ -320,11 +320,18 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler {
|
||||
return commonContainer.allChildren.lastOrNull { it.textRange.contains(startOffset) } ?: return null
|
||||
}
|
||||
|
||||
private fun PsiElement.isAssignmentLHS(): Boolean {
|
||||
return parents.any { KtPsiUtil.isAssignment(it) && (it as KtBinaryExpression).left == this }
|
||||
}
|
||||
|
||||
private fun KtExpression.findOccurrences(occurrenceContainer: PsiElement): List<KtExpression> {
|
||||
return toRange()
|
||||
.match(occurrenceContainer, KotlinPsiUnifier.DEFAULT)
|
||||
.mapNotNull {
|
||||
val candidate = it.range.elements.first()
|
||||
|
||||
if (candidate.isAssignmentLHS()) return@mapNotNull null
|
||||
|
||||
when (candidate) {
|
||||
is KtExpression -> candidate
|
||||
is KtStringTemplateEntryWithExpression -> candidate.expression
|
||||
@@ -694,6 +701,10 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler {
|
||||
val expression = expressionToExtract?.let { KtPsiUtil.safeDeparenthesize(it) }
|
||||
?: return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.expression"))
|
||||
|
||||
if (expression.isAssignmentLHS()) {
|
||||
return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.expression"))
|
||||
}
|
||||
|
||||
val physicalExpression = expression.substringContextOrThis
|
||||
|
||||
val resolutionFacade = physicalExpression.getResolutionFacade()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: IntArray)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(IntArray(1) { 1 })
|
||||
println(<selection>foo.bar</selection>)
|
||||
foo.bar[0] = foo.bar[0] + 1
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: IntArray)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(IntArray(1) { 1 })
|
||||
val message = foo.bar
|
||||
println(message)
|
||||
message[0] = message[0] + 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: Int)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(1)
|
||||
println(foo.bar)
|
||||
<selection>foo.bar</selection> = foo.bar + 1
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Cannot perform refactoring without an expression
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: Bar)
|
||||
class Bar(var baz: Int)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(Bar(1))
|
||||
println(<selection>foo.bar</selection>)
|
||||
foo.bar.baz = foo.bar.baz + 1
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: Bar)
|
||||
class Bar(var baz: Int)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(Bar(1))
|
||||
val message = foo.bar
|
||||
println(message)
|
||||
message.baz = message.baz + 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: Int)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(1)
|
||||
println(<selection>foo.bar</selection>)
|
||||
foo.bar = foo.bar + 1
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
class Foo(var bar: Int)
|
||||
|
||||
fun test() {
|
||||
val foo = Foo(1)
|
||||
val message = foo.bar
|
||||
println(message)
|
||||
foo.bar = message + 1
|
||||
}
|
||||
+24
@@ -43,6 +43,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayAssignment.kt")
|
||||
public void testArrayAssignment() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/arrayAssignment.kt");
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callUnderSmartCast.kt")
|
||||
public void testCallUnderSmartCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/callUnderSmartCast.kt");
|
||||
@@ -337,6 +343,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("onAssignmentLHS.kt")
|
||||
public void testOnAssignmentLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/onAssignmentLHS.kt");
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("OneExplicitReceiver.kt")
|
||||
public void testOneExplicitReceiver() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/OneExplicitReceiver.kt");
|
||||
@@ -367,6 +379,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("selectorAssignment.kt")
|
||||
public void testSelectorAssignment() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/selectorAssignment.kt");
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/Simple.kt");
|
||||
@@ -385,6 +403,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("skipUsageInAssignmentLHS.kt")
|
||||
public void testSkipUsageInAssignmentLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/skipUsageInAssignmentLHS.kt");
|
||||
doIntroduceVariableTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("StringInjection.kt")
|
||||
public void testStringInjection() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/StringInjection.kt");
|
||||
|
||||
Reference in New Issue
Block a user