Rename: Fix qualified expression replacement for the case 'invoke' <-> 'get'
#KT-22705 Fixed
This commit is contained in:
@@ -156,6 +156,9 @@ fun KtExpression.getQualifiedExpressionForReceiverOrThis(): KtExpression {
|
||||
fun KtExpression.isDotReceiver(): Boolean =
|
||||
(parent as? KtDotQualifiedExpression)?.receiverExpression == this
|
||||
|
||||
fun KtExpression.getPossiblyQualifiedCallExpression(): KtCallExpression? =
|
||||
((this as? KtQualifiedExpression)?.selectorExpression ?: this) as? KtCallExpression
|
||||
|
||||
// ---------- Block expression -------------------------------------------------------------------------------------------------------------
|
||||
|
||||
fun KtElement.blockExpressionsOrSingle(): Sequence<KtElement> =
|
||||
|
||||
+22
-6
@@ -20,12 +20,14 @@ import com.google.common.collect.Lists
|
||||
import com.intellij.psi.MultiRangeReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.buildExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET
|
||||
@@ -55,13 +57,27 @@ class KtArrayAccessReference(
|
||||
override fun handleElementRename(newElementName: String?): PsiElement? {
|
||||
val arrayAccessExpression = expression
|
||||
if (OperatorNameConventions.INVOKE.asString() == newElementName) {
|
||||
val callExpression = KtPsiFactory(arrayAccessExpression.project).buildExpression {
|
||||
appendExpression(arrayAccessExpression.arrayExpression)
|
||||
val replacement = KtPsiFactory(arrayAccessExpression.project).buildExpression {
|
||||
val arrayExpression = arrayAccessExpression.arrayExpression
|
||||
if (arrayExpression is KtQualifiedExpression) {
|
||||
appendExpression(arrayExpression.receiverExpression)
|
||||
appendFixedText(arrayExpression.operationSign.value)
|
||||
appendExpression(arrayExpression.selectorExpression)
|
||||
}
|
||||
else {
|
||||
appendExpression(arrayExpression)
|
||||
}
|
||||
|
||||
appendFixedText("(")
|
||||
appendExpressions(arrayAccessExpression.indexExpressions, ",")
|
||||
appendFixedText(")")
|
||||
}
|
||||
return arrayAccessExpression.replace(callExpression)
|
||||
val fullCallExpression = arrayAccessExpression.replaced(replacement)
|
||||
val callExpression = fullCallExpression.getPossiblyQualifiedCallExpression()
|
||||
if (callExpression != null && callExpression.canMoveLambdaOutsideParentheses()) {
|
||||
callExpression.moveFunctionLiteralOutsideParentheses()
|
||||
}
|
||||
return fullCallExpression
|
||||
}
|
||||
|
||||
return this.renameImplicitConventionalCall(newElementName)
|
||||
|
||||
+7
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
@@ -95,14 +96,19 @@ class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReferenc
|
||||
|
||||
override fun handleElementRename(newElementName: String?): PsiElement? {
|
||||
val callExpression = expression
|
||||
val fullCallExpression = callExpression.getQualifiedExpressionForSelectorOrThis()
|
||||
if (newElementName == OperatorNameConventions.GET.asString() && callExpression.typeArguments.isEmpty()) {
|
||||
val arrayAccessExpression = KtPsiFactory(callExpression).buildExpression {
|
||||
if (fullCallExpression is KtQualifiedExpression) {
|
||||
appendExpression(fullCallExpression.receiverExpression)
|
||||
appendFixedText(fullCallExpression.operationSign.value)
|
||||
}
|
||||
appendExpression(callExpression.calleeExpression)
|
||||
appendFixedText("[")
|
||||
appendExpressions(callExpression.valueArguments.map { it.getArgumentExpression() })
|
||||
appendFixedText("]")
|
||||
}
|
||||
return callExpression.replace(arrayAccessExpression)
|
||||
return fullCallExpression.replace(arrayAccessExpression)
|
||||
}
|
||||
|
||||
return renameImplicitConventionalCall(newElementName)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun <caret>get(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second) {
|
||||
boo(s) {
|
||||
s.testInvoke[{
|
||||
"Hello"
|
||||
}]
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun invoke(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second) {
|
||||
boo(s) {
|
||||
s.testInvoke {
|
||||
"Hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun <caret>get(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second?, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second?) {
|
||||
boo(s) {
|
||||
s?.testInvoke[{
|
||||
"Hello"
|
||||
}]
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun invoke(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second?, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second?) {
|
||||
boo(s) {
|
||||
s?.testInvoke {
|
||||
"Hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun <caret>invoke(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second) {
|
||||
boo(s) {
|
||||
s.testInvoke {
|
||||
"Hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun get(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second) {
|
||||
boo(s) {
|
||||
s.testInvoke[{
|
||||
"Hello"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun <caret>invoke(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second?, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second?) {
|
||||
boo(s) {
|
||||
s?.testInvoke {
|
||||
"Hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class WInvoke {
|
||||
operator fun get(body: () -> Unit) { }
|
||||
}
|
||||
|
||||
class Second {
|
||||
val testInvoke = WInvoke()
|
||||
}
|
||||
|
||||
fun boo(s: Second?, body: () -> Unit) { }
|
||||
|
||||
fun foo(s: Second?) {
|
||||
boo(s) {
|
||||
s?.testInvoke[{
|
||||
"Hello"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,14 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToGetWithQualifiedExpr() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToGetWithSafeQualifiedExpr() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToPlus() {
|
||||
doTestMemberInplaceRename("plus")
|
||||
}
|
||||
@@ -106,6 +114,14 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToInvokeWithQualifiedExpr() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToInvokeWithSafeQualifiedExpr() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToPlus() {
|
||||
doTestMemberInplaceRename("plus")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user