mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] K2 Introduce Variable: use psi matcher to enable extraction of multiple occurrences
^KTIJ-27679 Fixed ^KTIJ-27681 Fixed ^KTIJ-27861 Fixed GitOrigin-RevId: 5a33e3dba0f7f7d94997fdeaf6294db26ec20154
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3caea821fd
commit
e80a56e53b
+1
-1
@@ -104,7 +104,7 @@ object K1IntroduceVariableHandler : KotlinIntroduceVariableHandler() {
|
||||
ConvertToBlockBodyIntention.Holder.convert(declaration)
|
||||
}
|
||||
|
||||
fun KtExpression.findOccurrences(occurrenceContainer: PsiElement): List<KtExpression> =
|
||||
override fun KtExpression.findOccurrences(occurrenceContainer: KtElement): List<KtExpression> =
|
||||
toRange().match(occurrenceContainer, KotlinPsiUnifier.DEFAULT).mapNotNull {
|
||||
val candidate = it.range.elements.first()
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ internal class KotlinIntroduceVariableServiceK1Impl(private val project: Project
|
||||
|
||||
override fun findOccurrences(
|
||||
expression: KtExpression,
|
||||
occurrenceContainer: PsiElement
|
||||
occurrenceContainer: KtElement
|
||||
): List<KtExpression> = with(K1IntroduceVariableHandler) {
|
||||
expression.findOccurrences(occurrenceContainer)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
1
|
||||
1
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val i = 1
|
||||
i
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo() {
|
||||
val z = <selection>123</selection>
|
||||
val x: (Int) -> Int = { 123}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo() {
|
||||
val i = 123
|
||||
val z = i
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int) =
|
||||
if (a > 1) {
|
||||
(<selection>a + 1</selection>) * (a - 1)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int): Int {
|
||||
val i = a + 1
|
||||
return if (a > 1) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
if (true) {
|
||||
if (true) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val i = 1
|
||||
if (true) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
if (true) {
|
||||
<selection>1</selection>
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val i = 1
|
||||
if (true) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun test() {
|
||||
<selection>1</selection>
|
||||
1
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun test() {
|
||||
val i = 1<caret>
|
||||
i
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a(x: Int) {
|
||||
val a = <selection>x + 1</selection>
|
||||
"it's a number ${x + 1}"
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a(x: Int) {
|
||||
val i = x + 1
|
||||
val a = i
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun main(args: Array<String>) {
|
||||
val myA = A()
|
||||
println(<selection>myA.prop</selection>)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun main(args: Array<String>) {
|
||||
val myA = A()
|
||||
val prop = myA.prop
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
val a = 2
|
||||
|
||||
val x: Int get() =
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
val a = 2
|
||||
|
||||
val x: Int get() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class Bar {
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class Bar {
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val x = <selection>Foo()</selection>
|
||||
println(Foo())
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val foo = Foo()
|
||||
val x = foo
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class A {
|
||||
fun test() = 1
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class A {
|
||||
fun test() = 1
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class A {
|
||||
fun test() = 1
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
class A {
|
||||
fun test() = 1
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
when (1) {
|
||||
is 3 -> 1
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun a() {
|
||||
val i = 1
|
||||
when (i) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: IntArray)
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: IntArray)
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
interface T {
|
||||
fun foo(): Int
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
interface T {
|
||||
fun foo(): Int
|
||||
}
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
// WITH_STDLIB
|
||||
fun f() {
|
||||
val listOf = listOf<Int>()
|
||||
val v : List<Int> = (listOf)
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) { }
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo(fun() = (i) * 3)
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) { }
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo(fun(): Int { return (i) * 3 })
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) { }
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo { (i) * 3 }
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) = f()
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo(fun() = foo(fun() = (i) * 3))
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) = f()
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo { foo(fun() = (i) * 3) }
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) = f()
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo { foo { (i) * 3 } }
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
fun foo(f: () -> Int) = f()
|
||||
|
||||
fun test() {
|
||||
val i = 1 + 2
|
||||
foo(fun() = foo { (i) * 3 })
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: test1
|
||||
fun test() = "123"
|
||||
|
||||
open class First(val s: String)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: test1
|
||||
fun test() = "123"
|
||||
|
||||
open class First(val s: String)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun test() = "123"
|
||||
|
||||
val f = <selection>test()</selection> + "456"
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun test() = "123"
|
||||
|
||||
val test = test()
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: test1
|
||||
fun test() = "123"
|
||||
|
||||
val f = <selection>test()</selection> + "456"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: test1
|
||||
fun test() = "123"
|
||||
|
||||
val test1 = test()
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
// WITH_STDLIB
|
||||
fun test() {
|
||||
val pair = 1 to 2
|
||||
(pair).first
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(): Int {
|
||||
val s: String? = ""
|
||||
return if (true) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(): Int {
|
||||
val s: String? = ""
|
||||
val length = s!!.length
|
||||
|
||||
-1
@@ -1,3 +1,2 @@
|
||||
// IGNORE_K2
|
||||
1 + 2
|
||||
<selection>2</selection> + 3
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
val i = 2
|
||||
1 + i
|
||||
i + 3
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: Bar)
|
||||
class Bar(var baz: Int)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: Bar)
|
||||
class Bar(var baz: Int)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: Int)
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
// WITH_STDLIB
|
||||
class Foo(var bar: Int)
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: s
|
||||
fun foo(a: Int): String {
|
||||
val x = "abc$a"
|
||||
val y = "abc${a}"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_K2
|
||||
// INPLACE_VARIABLE_NAME: s
|
||||
fun foo(a: Int): String {
|
||||
val s = "abc$a"
|
||||
val x = s
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int): String {
|
||||
val x = "-${a + 1}"
|
||||
val y = "x${a + 1}y"
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int): String {
|
||||
val i = a + 1
|
||||
val x = "-$i"
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int): String {
|
||||
val x = "-$a"
|
||||
val y = "x${a}y"
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun foo(a: Int): String {
|
||||
val a1 = a
|
||||
val x = "-$a1"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun (String.() -> String).foo(x : String) {
|
||||
x.<selection>this</selection>()
|
||||
x.this@foo()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_K2
|
||||
fun (String.() -> String).foo(x : String) {
|
||||
val function = this
|
||||
x.function()
|
||||
|
||||
+2
@@ -62,6 +62,8 @@ abstract class KotlinIntroduceVariableHandler : RefactoringActionHandler {
|
||||
onNonInteractiveFinish: ((KtDeclaration) -> Unit)? = null,
|
||||
)
|
||||
|
||||
abstract fun KtExpression.findOccurrences(occurrenceContainer: KtElement): List<KtExpression>
|
||||
|
||||
/**
|
||||
* @param contained expression, which is:
|
||||
* * parent of extracted expression before refactoring
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ interface KotlinIntroduceVariableService {
|
||||
): PsiElement?
|
||||
|
||||
fun getContainersForExpression(expression: KtExpression): List<KotlinIntroduceVariableHelper.Containers>
|
||||
fun findOccurrences(expression: KtExpression, occurrenceContainer: PsiElement): List<KtExpression>
|
||||
fun findOccurrences(expression: KtExpression, occurrenceContainer: KtElement): List<KtExpression>
|
||||
|
||||
fun doRefactoringWithContainer(
|
||||
editor: Editor?,
|
||||
|
||||
+16
-1
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.idea.codeinsight.utils.ConvertToBlockBodyUtils
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.addTypeArguments
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.getRenderedTypeArguments
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.introduce.K2SemanticMatcher
|
||||
import org.jetbrains.kotlin.idea.refactoring.KotlinCommonRefactoringSettings
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.KotlinIntroduceVariableContext
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.KotlinIntroduceVariableHandler
|
||||
@@ -208,7 +209,8 @@ object K2IntroduceVariableHandler : KotlinIntroduceVariableHandler() {
|
||||
|
||||
val isInplaceAvailable = editor != null
|
||||
|
||||
val allOccurrences = listOf(expression) // TODO: KTIJ-27861
|
||||
val allOccurrences = occurrencesToReplace ?: expression.findOccurrences(containers.occurrenceContainer)
|
||||
|
||||
val callback = Pass.create { replaceChoice: OccurrencesChooser.ReplaceChoice ->
|
||||
val allReplaces = when (replaceChoice) {
|
||||
OccurrencesChooser.ReplaceChoice.ALL -> allOccurrences
|
||||
@@ -345,6 +347,19 @@ object K2IntroduceVariableHandler : KotlinIntroduceVariableHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun KtExpression.findOccurrences(occurrenceContainer: KtElement): List<KtExpression> =
|
||||
analyzeInModalWindow(contextElement = this, KotlinBundle.message("find.usages.prepare.dialog.progress")) {
|
||||
K2SemanticMatcher.findMatches(patternElement = this@findOccurrences, scopeElement = occurrenceContainer)
|
||||
.filterNot { it.isAssignmentLHS() }
|
||||
.mapNotNull { match ->
|
||||
when (match) {
|
||||
is KtExpression -> match
|
||||
is KtStringTemplateEntryWithExpression -> match.expression
|
||||
else -> errorWithAttachment("Unexpected candidate element ${match::class.java}") { withPsiEntry("match", match) }
|
||||
}
|
||||
}
|
||||
}.ifEmpty { listOf(this) }
|
||||
|
||||
private fun areTypeArgumentsNeededForCorrectTypeInference(expression: KtExpression): Boolean {
|
||||
val call = expression.getPossiblyQualifiedCallExpression() ?: return false
|
||||
if (call.typeArgumentList != null) return false
|
||||
|
||||
+4
-2
@@ -45,8 +45,10 @@ internal class KotlinIntroduceVariableServiceK2Impl(private val project: Project
|
||||
|
||||
override fun findOccurrences(
|
||||
expression: KtExpression,
|
||||
occurrenceContainer: PsiElement
|
||||
): List<KtExpression> = listOf(expression)
|
||||
occurrenceContainer: KtElement,
|
||||
): List<KtExpression> = with(K2IntroduceVariableHandler) {
|
||||
expression.findOccurrences(occurrenceContainer)
|
||||
}
|
||||
|
||||
override fun doRefactoringWithContainer(
|
||||
editor: Editor?,
|
||||
|
||||
Reference in New Issue
Block a user