Convert parameter <-> receiver intention: do not add label to 'this' if not needed
#KT-17615 Fixed #KT-30028 Fixed #KT-32809 Fixed #KT-28085 Fixed #KT-37508 Fixed Convert receiver to parameter: #KT-37508 Fixed
This commit is contained in:
committed by
Ilya Kirillov
parent
34e9e899f8
commit
c344b85d4e
+5
-1
@@ -60,10 +60,12 @@ import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
|
|||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
@@ -359,9 +361,11 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
assert(originalReceiverInfo != null) { "No original receiver info provided: " + functionUsageInfo.declaration.text }
|
assert(originalReceiverInfo != null) { "No original receiver info provided: " + functionUsageInfo.declaration.text }
|
||||||
result.add(KotlinParameterUsage(expression, originalReceiverInfo!!, functionUsageInfo))
|
result.add(KotlinParameterUsage(expression, originalReceiverInfo!!, functionUsageInfo))
|
||||||
} else {
|
} else {
|
||||||
|
if (receiverDescriptor.value is ExtensionReceiver) return
|
||||||
val targetDescriptor = receiverDescriptor.type.constructor.declarationDescriptor
|
val targetDescriptor = receiverDescriptor.type.constructor.declarationDescriptor
|
||||||
assert(targetDescriptor != null) { "Receiver type has no descriptor: " + functionUsageInfo.declaration.text }
|
assert(targetDescriptor != null) { "Receiver type has no descriptor: " + functionUsageInfo.declaration.text }
|
||||||
result.add(KotlinNonQualifiedOuterThisUsage(expression.parent as KtThisExpression, targetDescriptor!!))
|
if (DescriptorUtils.isAnonymousObject(targetDescriptor!!)) return
|
||||||
|
result.add(KotlinNonQualifiedOuterThisUsage(expression.parent as KtThisExpression, targetDescriptor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
@@ -540,7 +541,11 @@ class KotlinFunctionCallUsage(
|
|||||||
is ExpressionReceiver -> receiver.expression
|
is ExpressionReceiver -> receiver.expression
|
||||||
is ImplicitReceiver -> {
|
is ImplicitReceiver -> {
|
||||||
val descriptor = receiver.declarationDescriptor
|
val descriptor = receiver.declarationDescriptor
|
||||||
val thisText = if (descriptor is ClassDescriptor) "this@" + descriptor.name.asString() else "this"
|
val thisText = if (descriptor is ClassDescriptor && !DescriptorUtils.isAnonymousObject(descriptor)) {
|
||||||
|
"this@" + descriptor.name.asString()
|
||||||
|
} else {
|
||||||
|
"this"
|
||||||
|
}
|
||||||
psiFactory.createExpression(thisText)
|
psiFactory.createExpression(thisText)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class A
|
||||||
|
|
||||||
|
class B {
|
||||||
|
val foo = 1
|
||||||
|
fun test(<caret>a: A) {
|
||||||
|
this.foo
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class A
|
||||||
|
|
||||||
|
class B {
|
||||||
|
val foo = 1
|
||||||
|
fun A.test() {
|
||||||
|
this@B.foo
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(<caret>p: Any) {
|
||||||
|
object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
print(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun Any.foo() {
|
||||||
|
object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
print(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
class C(val x: Int, val y: Int, var z: Int)
|
||||||
|
|
||||||
|
class CBuilder {
|
||||||
|
var x: Int = 0
|
||||||
|
var y: Int = 0
|
||||||
|
fun build() = C(x, y, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(<caret>a: C) =
|
||||||
|
CBuilder().apply {
|
||||||
|
x = a.x
|
||||||
|
y = a.y
|
||||||
|
}.build().apply {
|
||||||
|
val b = this
|
||||||
|
z = b.x + b.y
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
class C(val x: Int, val y: Int, var z: Int)
|
||||||
|
|
||||||
|
class CBuilder {
|
||||||
|
var x: Int = 0
|
||||||
|
var y: Int = 0
|
||||||
|
fun build() = C(x, y, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun C.test() =
|
||||||
|
CBuilder().apply {
|
||||||
|
x = this@test.x
|
||||||
|
y = this@test.y
|
||||||
|
}.build().apply {
|
||||||
|
val b = this
|
||||||
|
z = b.x + b.y
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
interface I
|
||||||
|
interface J
|
||||||
|
|
||||||
|
fun foo(<caret>a: Any, b: String) {
|
||||||
|
b.bar {
|
||||||
|
this as J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.bar(init: I.() -> Unit) {}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
interface I
|
||||||
|
interface J
|
||||||
|
|
||||||
|
fun Any.foo(b: String) {
|
||||||
|
b.bar {
|
||||||
|
this as J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.bar(init: I.() -> Unit) {}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun <caret>Int.add() {
|
||||||
|
run { println(this + 1) }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun add(i: Int) {
|
||||||
|
i.run { println(this + 1) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
interface A
|
||||||
|
|
||||||
|
fun <caret>A.foo() {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
object : A {
|
||||||
|
fun bar() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
interface A
|
||||||
|
|
||||||
|
fun foo(a: A) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
object : A {
|
||||||
|
fun bar() {
|
||||||
|
foo(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5531,6 +5531,26 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertParameterToReceiver/companionAsReceiver.kt");
|
runTest("idea/testData/intentions/convertParameterToReceiver/companionAsReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("explicitThis.kt")
|
||||||
|
public void testExplicitThis() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertParameterToReceiver/explicitThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("explicitThisForAnonymousObject.kt")
|
||||||
|
public void testExplicitThisForAnonymousObject() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertParameterToReceiver/explicitThisForAnonymousObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("explicitThisForExtension.kt")
|
||||||
|
public void testExplicitThisForExtension() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertParameterToReceiver/explicitThisForExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("explicitThisForExtension2.kt")
|
||||||
|
public void testExplicitThisForExtension2() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertParameterToReceiver/explicitThisForExtension2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionExpression.kt")
|
@TestMetadata("functionExpression.kt")
|
||||||
public void testFunctionExpression() throws Exception {
|
public void testFunctionExpression() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertParameterToReceiver/functionExpression.kt");
|
runTest("idea/testData/intentions/convertParameterToReceiver/functionExpression.kt");
|
||||||
@@ -6089,6 +6109,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertReceiverToParameter/autoSuggestedName.kt");
|
runTest("idea/testData/intentions/convertReceiverToParameter/autoSuggestedName.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("explicitThisForExtension.kt")
|
||||||
|
public void testExplicitThisForExtension() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertReceiverToParameter/explicitThisForExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionExpression.kt")
|
@TestMetadata("functionExpression.kt")
|
||||||
public void testFunctionExpression() throws Exception {
|
public void testFunctionExpression() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertReceiverToParameter/functionExpression.kt");
|
runTest("idea/testData/intentions/convertReceiverToParameter/functionExpression.kt");
|
||||||
@@ -6129,6 +6154,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertReceiverToParameter/topLevelFun.kt");
|
runTest("idea/testData/intentions/convertReceiverToParameter/topLevelFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("usedInAnonymousObject.kt")
|
||||||
|
public void testUsedInAnonymousObject() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertReceiverToParameter/usedInAnonymousObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("validOverload.kt")
|
@TestMetadata("validOverload.kt")
|
||||||
public void testValidOverload() throws Exception {
|
public void testValidOverload() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertReceiverToParameter/validOverload.kt");
|
runTest("idea/testData/intentions/convertReceiverToParameter/validOverload.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user