mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix for 'this' expression call
Original commit: e31eac16adaf47ae5bf5af870e08f06abb29b333 GitOrigin-RevId: 12b8394048b87f6cf4f3898da2bf08c095fd47cf
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8e7c876180
commit
dd8af0b030
+38
-4
@@ -71,8 +71,10 @@ 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.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -403,6 +405,33 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private fun processThisCall(
|
||||
expression: KtSimpleNameExpression,
|
||||
context: BindingContext,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
dispatchReceiver: ReceiverValue?
|
||||
) {
|
||||
val thisExpression = expression.parent as? KtThisExpression ?: return
|
||||
val thisCallExpression = thisExpression.parent as? KtCallExpression ?: return
|
||||
val usageInfo = when (callableDescriptor) {
|
||||
dispatchReceiver.getReceiverTargetDescriptor(context) -> {
|
||||
val extensionReceiverTargetDescriptor = extensionReceiver.getReceiverTargetDescriptor(context)
|
||||
if (extensionReceiverTargetDescriptor != null) {
|
||||
KotlinNonQualifiedOuterThisCallUsage(
|
||||
thisCallExpression, originalReceiverInfo!!, functionUsageInfo, extensionReceiverTargetDescriptor
|
||||
)
|
||||
} else {
|
||||
KotlinParameterUsage(expression, originalReceiverInfo!!, functionUsageInfo)
|
||||
}
|
||||
}
|
||||
extensionReceiver.getReceiverTargetDescriptor(context) -> {
|
||||
KotlinParameterUsage(expression, originalReceiverInfo!!, functionUsageInfo)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
result.addIfNotNull(usageInfo)
|
||||
}
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, context: BindingContext): Void? {
|
||||
val resolvedCall = expression.getResolvedCall(context) ?: return null
|
||||
|
||||
@@ -412,11 +441,16 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
return null
|
||||
}
|
||||
|
||||
val receiverValue = resolvedCall
|
||||
val (extensionReceiver, dispatchReceiver) = resolvedCall
|
||||
.let { (it as? VariableAsFunctionResolvedCall)?.variableCall ?: it }
|
||||
.let { it.extensionReceiver ?: it.dispatchReceiver }
|
||||
if (receiverValue is ImplicitReceiver) {
|
||||
processImplicitThis(resolvedCall.call.callElement, receiverValue)
|
||||
.let { (it.extensionReceiver to it.dispatchReceiver) }
|
||||
if (extensionReceiver != null || dispatchReceiver != null) {
|
||||
val receiverValue = extensionReceiver ?: dispatchReceiver
|
||||
if (receiverValue is ImplicitReceiver) {
|
||||
processImplicitThis(resolvedCall.call.callElement, receiverValue)
|
||||
} else {
|
||||
processThisCall(expression, context, extensionReceiver, dispatchReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
+17
-5
@@ -11,10 +11,8 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences.Options
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinParameterInfo
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtThisExpression
|
||||
import org.jetbrains.kotlin.idea.refactoring.explicateAsTextForReceiver
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
|
||||
|
||||
// Explicit reference to function parameter or outer this
|
||||
@@ -63,4 +61,18 @@ class KotlinNonQualifiedOuterThisUsage(
|
||||
}
|
||||
|
||||
override fun getReplacementText(changeInfo: KotlinChangeInfo): String = "this@${targetDescriptor.name.asString()}"
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinNonQualifiedOuterThisCallUsage(
|
||||
element: KtCallExpression,
|
||||
val parameterInfo: KotlinParameterInfo,
|
||||
val containingCallable: KotlinCallableDefinitionUsage<*>,
|
||||
val targetDescriptor: DeclarationDescriptor
|
||||
) : KotlinExplicitReferenceUsage<KtCallExpression>(element) {
|
||||
override fun getReplacementText(changeInfo: KotlinChangeInfo): String {
|
||||
val inheritedName = parameterInfo.getInheritedName(containingCallable)
|
||||
val receiver = targetDescriptor.explicateAsTextForReceiver()
|
||||
element?.calleeExpression?.replace(KtPsiFactory(changeInfo.context).createExpression(receiver))
|
||||
return "with($inheritedName) $inheritedName@{ ${element?.text} }"
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -6454,6 +6454,11 @@ public abstract class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
runTest("testData/intentions/convertReceiverToParameter/replaceThis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("thisCall.kt")
|
||||
public void testThisCall() throws Exception {
|
||||
runTest("testData/intentions/convertReceiverToParameter/thisCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFun.kt")
|
||||
public void testTopLevelFun() throws Exception {
|
||||
runTest("testData/intentions/convertReceiverToParameter/topLevelFun.kt");
|
||||
|
||||
+3
@@ -9,6 +9,8 @@ class User(
|
||||
val callableLambda: () -> Unit = {}
|
||||
|
||||
fun checkName() = Unit
|
||||
|
||||
operator fun invoke() = Unit
|
||||
}
|
||||
|
||||
fun <caret>User.extFun() {
|
||||
@@ -16,4 +18,5 @@ fun <caret>User.extFun() {
|
||||
checkName()
|
||||
callableLambda()
|
||||
callableObject()
|
||||
this()
|
||||
}
|
||||
+3
@@ -9,6 +9,8 @@ class User(
|
||||
val callableLambda: () -> Unit = {}
|
||||
|
||||
fun checkName() = Unit
|
||||
|
||||
operator fun invoke() = Unit
|
||||
}
|
||||
|
||||
fun extFun(user: User) {
|
||||
@@ -16,4 +18,5 @@ fun extFun(user: User) {
|
||||
user.checkName()
|
||||
user.callableLambda()
|
||||
user.callableObject()
|
||||
user()
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_RUNTIME
|
||||
class CallableObject {
|
||||
operator fun User.invoke() = println("User.invoke")
|
||||
}
|
||||
|
||||
class User {
|
||||
operator fun CallableObject.invoke() = println("CallableObject.invoke")
|
||||
}
|
||||
|
||||
fun <caret>User.extFun() {
|
||||
val callableObject = CallableObject()
|
||||
with(callableObject) {
|
||||
this()
|
||||
this@extFun()
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// WITH_RUNTIME
|
||||
class CallableObject {
|
||||
operator fun User.invoke() = println("User.invoke")
|
||||
}
|
||||
|
||||
class User {
|
||||
operator fun CallableObject.invoke() = println("CallableObject.invoke")
|
||||
}
|
||||
|
||||
fun extFun(user: User) {
|
||||
val callableObject = CallableObject()
|
||||
with(callableObject) {
|
||||
with(user) user@{ this@with() }
|
||||
user()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user