[kotlin] k2: port ConvertParameterToReceiver

^KTIJ-30159 fixed

GitOrigin-RevId: e75de574e0e8393cf05f64cba1adbf8d9b70c572
This commit is contained in:
Anna Kozlova
2024-06-26 20:05:38 +00:00
committed by intellij-monorepo-bot
parent 18caa2f9fd
commit f72e6fd961
38 changed files with 268 additions and 67 deletions
@@ -275,6 +275,13 @@
<categoryKey>group.names.kotlin</categoryKey>
</intentionAction>
<intentionAction>
<language>kotlin</language>
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertParameterToReceiverIntention</className>
<bundleName>messages.KotlinBundle</bundleName>
<categoryKey>group.names.kotlin</categoryKey>
</intentionAction>
<intentionAction>
<language>kotlin</language>
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.IfToWhenIntention</className>
@@ -0,0 +1,80 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.intentions
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.impl.Utils.computeWithProgressIcon
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.readAction
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiMethod
import com.intellij.refactoring.RefactoringBundle
import com.intellij.ui.awt.RelativePoint
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingIntention
import org.jetbrains.kotlin.idea.codeinsight.utils.findExistingEditor
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport
import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.KotlinChangeInfo
import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.KotlinChangeSignatureProcessor
import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.KotlinMethodDescriptor
import org.jetbrains.kotlin.idea.k2.refactoring.checkSuperMethods
import org.jetbrains.kotlin.lexer.KtTokens.OVERRIDE_KEYWORD
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
internal class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(
KtParameter::class.java,
KotlinBundle.lazyMessage("convert.parameter.to.receiver")
) {
override fun startInWriteAction(): Boolean = false
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
val nameIdentifier = element.nameIdentifier ?: return false
if (!nameIdentifier.textRange.contains(caretOffset)) return false
if (element.isVarArg) return false
val namedFunction = element.ownerFunction as? KtNamedFunction ?: return false
if (namedFunction.receiverTypeReference != null) return false
if (namedFunction.hasModifier(OVERRIDE_KEYWORD)) {
val overridesJava = {
analyze(namedFunction) {
namedFunction.symbol.allOverriddenSymbols.any { it.psi is PsiMethod }
}
}
val hasJavaOverride = if (ApplicationManager.getApplication().isDispatchThread()) {
val editor = element.findExistingEditor()!!
val aComponent = editor.contentComponent
val point = RelativePoint(aComponent, editor.logicalPositionToXY(editor.offsetToLogicalPosition(caretOffset)))
computeWithProgressIcon(point, aComponent, ActionPlaces.UNKNOWN) {
readAction { overridesJava() }
}
}
else {
overridesJava()
}
if (hasJavaOverride) return false
}
return true
}
override fun applyTo(element: KtParameter, editor: Editor?) {
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
val parameterIndex = function.valueParameters.indexOf(element)
val superMethods = checkSuperMethods(function, emptyList(), RefactoringBundle.message("to.refactor"))
val superFunction = superMethods.firstOrNull() as? KtNamedFunction ?: return
val methodDescriptor = KotlinMethodDescriptor(superFunction)
val changeInfo = KotlinChangeInfo(methodDescriptor)
changeInfo.receiverParameterInfo = changeInfo.newParameters[parameterIndex]
KotlinChangeSignatureProcessor(element.project, changeInfo).run()
}
}
@@ -8052,7 +8052,129 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest {
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/intentions/convertParameterToReceiver")
public static class ConvertParameterToReceiver extends AbstractK2IntentionTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("classParameter.kt")
public void testClassParameter() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/classParameter.kt");
}
@TestMetadata("companionAsReceiver.kt")
public void testCompanionAsReceiver() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/companionAsReceiver.kt");
}
@TestMetadata("definitelyNotNullType.kt")
public void testDefinitelyNotNullType() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/definitelyNotNullType.kt");
}
@TestMetadata("explicitThis.kt")
public void testExplicitThis() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/explicitThis.kt");
}
@TestMetadata("explicitThisForAnonymousObject.kt")
public void testExplicitThisForAnonymousObject() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/explicitThisForAnonymousObject.kt");
}
@TestMetadata("explicitThisForExtension.kt")
public void testExplicitThisForExtension() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/explicitThisForExtension.kt");
}
@TestMetadata("explicitThisForExtension2.kt")
public void testExplicitThisForExtension2() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/explicitThisForExtension2.kt");
}
@TestMetadata("functionExpression.kt")
public void testFunctionExpression() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/functionExpression.kt");
}
@TestMetadata("functionExpressionWithThisConflict.kt")
public void testFunctionExpressionWithThisConflict() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/functionExpressionWithThisConflict.kt");
}
@TestMetadata("hasVararg.kt")
public void testHasVararg() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/hasVararg.kt");
}
@TestMetadata("javaBaseMethod.kt")
public void testJavaBaseMethod() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/javaBaseMethod.kt");
}
@TestMetadata("kotlinBaseMethod.kt")
public void testKotlinBaseMethod() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/kotlinBaseMethod.kt");
}
@TestMetadata("lambdaParameter.kt")
public void testLambdaParameter() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/lambdaParameter.kt");
}
@TestMetadata("localFun.kt")
public void testLocalFun() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/localFun.kt");
}
@TestMetadata("localObject.kt")
public void testLocalObject() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/localObject.kt");
}
@TestMetadata("localObjectWithFunctionNameConflict.kt")
public void testLocalObjectWithFunctionNameConflict() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/localObjectWithFunctionNameConflict.kt");
}
@TestMetadata("memberFun.kt")
public void testMemberFun() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/memberFun.kt");
}
@TestMetadata("noParameterUnderCaret.kt")
public void testNoParameterUnderCaret() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/noParameterUnderCaret.kt");
}
@TestMetadata("parameterOfObjectFunction.kt")
public void testParameterOfObjectFunction() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/parameterOfObjectFunction.kt");
}
@TestMetadata("topLevelFun.kt")
public void testTopLevelFun() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/topLevelFun.kt");
}
@TestMetadata("vararg.kt")
public void testVararg() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/vararg.kt");
}
@TestMetadata("withExtensionReceiver.kt")
public void testWithExtensionReceiver() throws Exception {
runTest("../../../idea/tests/testData/intentions/convertParameterToReceiver/withExtensionReceiver.kt");
}
}
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertParameterToReceiverIntention
@@ -1,4 +1,5 @@
// SHOULD_FAIL_WITH: Parameter reference can't be safely replaced with this since target function can't be referenced in this context
// IGNORE_K2
interface T {
val foo: Int
}
@@ -1,4 +1,5 @@
// SHOULD_FAIL_WITH: Parameter reference can't be safely replaced with this@foo since @foo is ambiguous in this context
// IGNORE_K2
fun foo(<caret>bar: Int) {
object {
fun foo() {
@@ -1,4 +1,5 @@
// WITH_STDLIB
// IGNORE_K2
object Foo {
fun bar(<caret>p: String){}
}
@@ -1,6 +1,7 @@
import Foo.bar
// WITH_STDLIB
// IGNORE_K2
object Foo {
fun String.bar() {}
}
@@ -1,3 +1,2 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual fun f1(i: Int, <caret>s: String) {}
@@ -1,3 +1,2 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual fun String.f1(i: Int<caret>) {}
@@ -1,3 +1,2 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect fun f1(i: Int, <caret>s: String)
@@ -1,3 +1,2 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect fun String.f1(i: Int<caret>)
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun c(a: Int, b: String) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun String.c(a: Int) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun c(a: Int, <caret>b: String) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun String.c(a: Int<caret>) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect class A {
fun c(a: Int, <caret>b: String)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect class A {
fun String.c(a: Int<caret>)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect open class A() {
open fun c(a: Int, <caret>b: String)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect open class A() {
open fun String.c(a: Int<caret>)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect open class A() {
open fun c(a: Int, b: String)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect open class A() {
open fun String.c(a: Int)
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun c(a: Int, b: String) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual open class A {
actual open fun String.c(a: Int) {}
}
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect class Foo {
fun foo(n: Int, <caret>s: String)
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
expect class Foo {
fun String.foo(n: Int)
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual class Foo {
actual fun foo(n: Int, <caret>s: String) {
@@ -1,5 +1,4 @@
// "Convert parameter to receiver" "true"
// IGNORE_K2
actual class Foo {
actual fun String.foo(n: Int) {
@@ -6,7 +6,7 @@ fun Foo.m() {
object : Runnable {
override fun run() {
if ((1..2).find<Int> {
println(this@m.i)
println(this@Foo.i)
true
} != 0) {
}
@@ -3,7 +3,7 @@
enum class MyEnum {
<caret>m;
companion object { val m = 1 }
fun context() = println(m.hashCode() + Companion.m)
fun context() = println(m.hashCode() + MyEnum.Companion.m)
}
fun external() = println(MyEnum.m.hashCode() + MyEnum.Companion.m)
// IGNORE_K1
@@ -0,0 +1,8 @@
// NEW_NAME: e
// RENAME: member
enum class MyEnum {
e;
companion object { val <caret>e = 1 }
fun context() = println(e.hashCode() + MyEnum.Companion.e)
}
fun external() = println(MyEnum.e.hashCode() + MyEnum.Companion.e)
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KaValueParameterSymbol
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.base.util.useScope
import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.usages.*
import org.jetbrains.kotlin.idea.k2.refactoring.getThisQualifier
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
import org.jetbrains.kotlin.psi.*
@@ -116,8 +117,8 @@ internal object KotlinChangeSignatureUsageSearcher {
if (name != null) {
if (receiverExpression is KtThisExpression) {
result.add(KotlinNonQualifiedOuterThisUsage(receiverExpression, name))
} else if (receiverValue is KaImplicitReceiverValue && partiallyAppliedSymbol.extensionReceiver == null) {
result.add(KotlinImplicitThisUsage(receiverExpression, name))
} else if (receiverValue is KaImplicitReceiverValue && partiallyAppliedSymbol.extensionReceiver == null && receiverExpression is KtNameReferenceExpression) {
result.add(KotlinImplicitThisUsage(receiverExpression, getThisQualifier(receiverValue)))
}
}
}
@@ -69,19 +69,15 @@ internal class KotlinImplicitThisToParameterUsage(
internal class KotlinImplicitThisUsage(
callElement: KtElement,
private val targetDescriptor: Name
private val newReceiver: String
) : UsageInfo(callElement), KotlinBaseChangeSignatureUsage {
private fun getNewReceiverText() = when {
targetDescriptor.isSpecial -> "this"
else -> "this@${targetDescriptor.asString()}"
}
override fun processUsage(
changeInfo: KotlinChangeInfoBase,
element: KtElement,
allUsages: Array<out UsageInfo>
): KtElement {
val newQualifiedCall = KtPsiFactory(element.project).createExpression("${getNewReceiverText()}.${element.text}"
val newQualifiedCall = KtPsiFactory(element.project).createExpression("$newReceiver.${element.text}"
) as KtQualifiedExpression
return element.replace(newQualifiedCall).parent as KtElement
}
@@ -3,6 +3,8 @@
package org.jetbrains.kotlin.idea.k2.refactoring.copy
import com.intellij.ide.util.EditorHelper
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
@@ -171,8 +173,10 @@ class CopyKotlinDeclarationsHandler : AbstractCopyKotlinDeclarationsHandler() {
project.checkConflictsInteractively(conflicts) {
try {
project.executeCommand(copyCommandName) {
doRefactor(sourceData, targetData)
ApplicationManagerEx.getApplicationEx().runWriteActionWithCancellableProgressInDispatchThread(copyCommandName, project, null) {
project.executeCommand(copyCommandName) {
doRefactor(sourceData, targetData)
}
}
} finally {
elements.filterIsInstance<KtElement>().forEach(::unMarkAllUsages)
@@ -3,22 +3,22 @@ package org.jetbrains.kotlin.idea.k2.refactoring.inline.codeInliner
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.resolution.KaImplicitReceiverValue
import org.jetbrains.kotlin.analysis.api.resolution.singleFunctionCallOrNull
import org.jetbrains.kotlin.analysis.api.resolution.singleVariableAccessCall
import org.jetbrains.kotlin.analysis.api.resolution.symbol
import org.jetbrains.kotlin.analysis.api.permissions.KaAllowAnalysisFromWriteAction
import org.jetbrains.kotlin.analysis.api.permissions.KaAllowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.api.permissions.allowAnalysisFromWriteAction
import org.jetbrains.kotlin.analysis.api.permissions.allowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.api.resolution.KaImplicitReceiverValue
import org.jetbrains.kotlin.analysis.api.resolution.singleFunctionCallOrNull
import org.jetbrains.kotlin.analysis.api.resolution.singleVariableAccessCall
import org.jetbrains.kotlin.analysis.api.resolution.symbol
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaDeclarationContainerSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.types.KaFunctionType
import org.jetbrains.kotlin.idea.codeinsight.utils.addTypeArguments
import org.jetbrains.kotlin.idea.codeinsight.utils.getRenderedTypeArguments
import org.jetbrains.kotlin.idea.k2.refactoring.getThisQualifier
import org.jetbrains.kotlin.idea.k2.refactoring.util.ConvertReferenceToLambdaUtil
import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.CodeToInline
import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.MutableCodeToInline
@@ -209,9 +209,9 @@ internal fun encodeInternalReferences(codeToInline: MutableCodeToInline, origina
analyze(t) {
val resolvedSymbol = t.symbol
val containingSymbol = resolvedSymbol.containingSymbol ?: return true
if (containingSymbol is KaSymbolWithMembers) {
if (containingSymbol is KaDeclarationContainerSymbol) {
val staticScope = containingSymbol.staticMemberScope
return resolvedSymbol in staticScope.getAllSymbols()
return resolvedSymbol in staticScope.declarations
}
return false
}
@@ -306,15 +306,4 @@ internal fun specifyNullTypeExplicitly(codeToInline: MutableCodeToInline, origin
codeToInline.replaceExpression(it, KtPsiFactory.contextual(it).createExpression(nullCast))
}
}
}
context(KaSession)
internal fun getThisQualifier(receiverValue: KaImplicitReceiverValue): String {
val symbol = receiverValue.symbol
return if ((symbol as? KaClassSymbol)?.classKind == KaClassKind.COMPANION_OBJECT) {
(symbol.containingSymbol as KaClassifierSymbol).name!!.asString() + "." + symbol.name!!.asString()
}
else {
"this" + ((((symbol as? KaReceiverParameterSymbol)?.owningCallableSymbol ?: symbol) as? KaNamedSymbol)?.name?.let { "@$it" } ?: "")
}
}
@@ -9,13 +9,21 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentOfType
import com.intellij.refactoring.util.RefactoringDescriptionLocation
import org.jetbrains.annotations.Nls
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.resolution.KaErrorCallInfo
import org.jetbrains.kotlin.analysis.api.resolution.KaImplicitReceiverValue
import org.jetbrains.kotlin.analysis.api.resolution.KaSimpleFunctionCall
import org.jetbrains.kotlin.analysis.api.resolution.successfulFunctionCallOrNull
import org.jetbrains.kotlin.analysis.api.resolution.successfulVariableAccessCall
import org.jetbrains.kotlin.analysis.api.resolution.symbol
import org.jetbrains.kotlin.analysis.api.symbols.KaAnonymousObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaReceiverParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
import org.jetbrains.kotlin.analysis.api.types.KaType
import org.jetbrains.kotlin.analysis.api.types.KaTypeParameterType
import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow
@@ -177,4 +185,19 @@ fun KtLambdaExpression.moveFunctionLiteralOutsideParenthesesIfPossible() {
if (call.canMoveLambdaOutsideParentheses()) {
call.moveFunctionLiteralOutsideParentheses()
}
}
context(KaSession)
fun getThisQualifier(receiverValue: KaImplicitReceiverValue): String {
val symbol = receiverValue.symbol
return if ((symbol as? KaClassSymbol)?.classKind == KaClassKind.COMPANION_OBJECT) {
//specify companion name to avoid clashes with enum entries
(symbol.containingSymbol as KaClassifierSymbol).name!!.asString() + "." + symbol.name!!.asString()
} else if (symbol is KaClassifierSymbol && symbol !is KaAnonymousObjectSymbol) {
"this@" + symbol.name!!.asString()
} else if (symbol is KaReceiverParameterSymbol && symbol.owningCallableSymbol is KaNamedSymbol) {
receiverValue.type.expandedSymbol?.name?.let { "this@$it" } ?: "this"
} else {
"this"
}
}
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.resolution.*
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
import org.jetbrains.kotlin.analysis.api.types.KaErrorType
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.k2.refactoring.getThisQualifier
import org.jetbrains.kotlin.idea.refactoring.conflicts.filterCandidates
import org.jetbrains.kotlin.idea.refactoring.conflicts.registerRetargetJobOnPotentialCandidates
import org.jetbrains.kotlin.idea.refactoring.conflicts.renderDescription
@@ -260,20 +260,6 @@ private fun createQualifiedExpression(callExpression: KtExpression, newName: Str
val appliedSymbol = callExpression.resolveToCall()?.successfulCallOrNull<KaCallableMemberCall<*, *>>()?.partiallyAppliedSymbol
val receiver = appliedSymbol?.extensionReceiver ?: appliedSymbol?.dispatchReceiver
fun getThisQualifier(receiverValue: KaImplicitReceiverValue): String {
val symbol = receiverValue.symbol
return if ((symbol as? KaClassSymbol)?.classKind == KaClassKind.COMPANION_OBJECT) {
//specify companion name to avoid clashes with enum entries
symbol.name!!.asString()
} else if (symbol is KaClassifierSymbol && symbol !is KaAnonymousObjectSymbol) {
"this@" + symbol.name!!.asString()
} else if (symbol is KaReceiverParameterSymbol && symbol.owningCallableSymbol is KaNamedSymbol) {
receiverValue.type.expandedSymbol?.name?.let { "this@$it" } ?: "this"
} else {
"this"
}
}
fun getExplicitQualifier(receiverValue: KaExplicitReceiverValue): String? {
val containingSymbol = appliedSymbol?.symbol?.containingSymbol
val enumClassSymbol = containingSymbol?.containingSymbol
@@ -158,7 +158,7 @@ internal fun MutableTWorkspace.generateK2IntentionTests() {
model("${idea}intentions/indentRawString", pattern = pattern, isIgnored = true)
model("${idea}intentions/replaceAddWithPlusAssign", pattern = pattern, isIgnored = true)
model("${idea}intentions/reconstructTypeInCastOrIs", pattern = pattern, isIgnored = true)
model("${idea}intentions/convertParameterToReceiver", pattern = pattern, isIgnored = true)
model("${idea}intentions/convertParameterToReceiver", pattern = pattern)
model("${idea}intentions/convertCollectionConstructorToFunction", pattern = pattern, isIgnored = true)
model("${idea}intentions/replaceMapGetOrDefault", pattern = pattern, isIgnored = true)
model("${idea}intentions/addMissingDestructuring", pattern = pattern, isIgnored = true)