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.resolve.BindingContext
|
||||
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.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
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.source.getPsi
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -359,9 +361,11 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
assert(originalReceiverInfo != null) { "No original receiver info provided: " + functionUsageInfo.declaration.text }
|
||||
result.add(KotlinParameterUsage(expression, originalReceiverInfo!!, functionUsageInfo))
|
||||
} else {
|
||||
if (receiverDescriptor.value is ExtensionReceiver) return
|
||||
val targetDescriptor = receiverDescriptor.type.constructor.declarationDescriptor
|
||||
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.getStrictParentOfType
|
||||
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.model.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -540,7 +541,11 @@ class KotlinFunctionCallUsage(
|
||||
is ExpressionReceiver -> receiver.expression
|
||||
is ImplicitReceiver -> {
|
||||
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)
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testFunctionExpression() throws Exception {
|
||||
runTest("idea/testData/intentions/convertParameterToReceiver/functionExpression.kt");
|
||||
@@ -6089,6 +6109,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
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")
|
||||
public void testFunctionExpression() throws Exception {
|
||||
runTest("idea/testData/intentions/convertReceiverToParameter/functionExpression.kt");
|
||||
@@ -6129,6 +6154,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
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")
|
||||
public void testValidOverload() throws Exception {
|
||||
runTest("idea/testData/intentions/convertReceiverToParameter/validOverload.kt");
|
||||
|
||||
Reference in New Issue
Block a user