mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] K2: add intention to convert receiver to context parameter
KTIJ-33555 GitOrigin-RevId: 0e2cda8c461a26177d5318f18d037c27591b41d3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9c4cfdbde4
commit
10d6fe208f
@@ -2515,9 +2515,10 @@ hints.codevision.settings=Settings\u2026
|
||||
convert.string.template.to.build.string=Convert to 'buildString' call
|
||||
convert.concatenation.to.build.string=Convert concatenation to 'buildString' call
|
||||
convert.to.indexed.function.call=Convert to indexed function call
|
||||
convert.to.regular.parameter=Convert context parameter to value parameter
|
||||
convert.to.receiver.parameter=Convert context parameter to receiver
|
||||
convert.to.context.parameter=Convert value parameter to context parameter
|
||||
convert.context.parameter.to.regular.parameter=Convert context parameter to value parameter
|
||||
convert.context.parameter.to.receiver.parameter=Convert context parameter to receiver
|
||||
convert.value.parameter.to.context.parameter=Convert value parameter to context parameter
|
||||
convert.receiver.parameter.to.context.parameter=Convert receiver to context parameter
|
||||
inspection.kotlin.invalid.bundle.or.property.display.name=Invalid property key
|
||||
inspection.gradle.kotlinx.coroutines.deprecation.display.name=Incompatible kotlinx.coroutines dependency is used with Kotlin 1.3+ in Gradle
|
||||
inspection.deprecated.gradle.dependency.display.name=Deprecated library is used in Gradle
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
context(string: String)
|
||||
fun foo() {
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fun <spot>String</spot>.foo() {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Converts a function receiver to a context parameter and updates usages.
|
||||
</body>
|
||||
</html>
|
||||
+7
@@ -634,5 +634,12 @@
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertReceiverParameterToContextParameterIntention</className>
|
||||
<bundleName>messages.KotlinBundle</bundleName>
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
class ConvertContextParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(
|
||||
KtParameter::class.java, KotlinBundle.lazyMessage("convert.to.receiver.parameter")
|
||||
KtParameter::class.java, KotlinBundle.lazyMessage("convert.context.parameter.to.receiver.parameter")
|
||||
) {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.KotlinChangeInfo
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
class ConvertContextParameterToRegularParameterIntention : SelfTargetingIntention<KtParameter>(
|
||||
KtParameter::class.java, KotlinBundle.lazyMessage("convert.to.regular.parameter")
|
||||
KtParameter::class.java, KotlinBundle.lazyMessage("convert.context.parameter.to.regular.parameter")
|
||||
) {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
// Copyright 2000-2025 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.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingIntention
|
||||
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.refactoring.rename.KotlinMemberInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class ConvertReceiverParameterToContextParameterIntention : SelfTargetingIntention<KtTypeReference>(
|
||||
KtTypeReference::class.java,
|
||||
KotlinBundle.lazyMessage("convert.receiver.parameter.to.context.parameter"),
|
||||
), LowPriorityAction {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun isApplicableTo(element: KtTypeReference, caretOffset: Int): Boolean {
|
||||
return element.languageVersionSettings.supportsFeature(LanguageFeature.ContextParameters)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtTypeReference, editor: Editor?) {
|
||||
val ktFunction = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
||||
val methodDescriptor = KotlinMethodDescriptor(ktFunction)
|
||||
val changeInfo = KotlinChangeInfo(methodDescriptor)
|
||||
if (!configureChangeInfo(changeInfo)) return
|
||||
object : KotlinChangeSignatureProcessor(element.project, changeInfo) {
|
||||
override fun performRefactoring(usages: Array<out UsageInfo?>) {
|
||||
super.performRefactoring(usages)
|
||||
DumbService.getInstance(element.project).smartInvokeLater {
|
||||
renameLastContextParameter(ktFunction, editor)
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
it.prepareSuccessfulSwingThreadCallback = Runnable { }
|
||||
}.run()
|
||||
}
|
||||
|
||||
private fun configureChangeInfo(changeInfo: KotlinChangeInfo): Boolean {
|
||||
val oldReceiverInfo = changeInfo.oldReceiverInfo ?: return false
|
||||
changeInfo.receiverParameterInfo = null
|
||||
oldReceiverInfo.isContextParameter = true
|
||||
return true
|
||||
}
|
||||
|
||||
private fun renameLastContextParameter(ktFunction: KtNamedFunction, editor: Editor?) {
|
||||
if (!ktFunction.isValid || editor == null || editor.isDisposed) return
|
||||
val lastContextParameter = ktFunction.contextReceiverList?.contextParameters()?.lastOrNull() ?: return
|
||||
editor.caretModel.moveToOffset(lastContextParameter.startOffset)
|
||||
PsiDocumentManager.getInstance(ktFunction.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
KotlinMemberInplaceRenameHandler().doRename(lastContextParameter, editor, null)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
class ConvertRegularParameterToContextParameterIntention : SelfTargetingIntention<KtParameter>(
|
||||
KtParameter::class.java,
|
||||
KotlinBundle.lazyMessage("convert.to.context.parameter"),
|
||||
KotlinBundle.lazyMessage("convert.value.parameter.to.context.parameter"),
|
||||
) {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
|
||||
+74
@@ -14358,6 +14358,80 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter")
|
||||
public static class ReceiverToContextParameter 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("classScopeExtensionArgument.kt")
|
||||
public void testClassScopeExtensionArgument() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/classScopeExtensionArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("contextFunCallInBody.kt")
|
||||
public void testContextFunCallInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/contextFunCallInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("contextMemberExtensionFunCallInBody.kt")
|
||||
public void testContextMemberExtensionFunCallInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/contextMemberExtensionFunCallInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("explicitExtensionArgument.kt")
|
||||
public void testExplicitExtensionArgument() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/explicitExtensionArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("explicitThisInBody.kt")
|
||||
public void testExplicitThisInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/explicitThisInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFunCallInBody.kt")
|
||||
public void testExtensionFunCallInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/extensionFunCallInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitExtensionArgument.kt")
|
||||
public void testImplicitExtensionArgument() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/implicitExtensionArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitThisInBody.kt")
|
||||
public void testImplicitThisInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/implicitThisInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inapplicableDisabledFeature.kt")
|
||||
public void testInapplicableDisabledFeature() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/inapplicableDisabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberExtensionFunCallInBody.kt")
|
||||
public void testMemberExtensionFunCallInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/memberExtensionFunCallInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunCallInBody.kt")
|
||||
public void testMemberFunCallInBody() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/memberFunCallInBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withAnotherContextBefore.kt")
|
||||
public void testWithAnotherContextBefore() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/contextParameters/receiverToContextParameter/withAnotherContextBefore.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/contextParameters/regularParameterToContextParameter")
|
||||
public static class RegularParameterToContextParameter extends AbstractK2IntentionTest {
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertReceiverParameterToContextParameterIntention
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
interface Foo
|
||||
|
||||
context(c: Int)
|
||||
fun <caret>Foo.foo(param: String) {
|
||||
}
|
||||
|
||||
class Bar : Foo {
|
||||
context(c1: Int)
|
||||
fun baz() {
|
||||
foo("boo")
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
interface Foo
|
||||
|
||||
context(c: Int, foo: Foo)
|
||||
fun foo(param: String) {
|
||||
}
|
||||
|
||||
class Bar : Foo {
|
||||
context(c1: Int)
|
||||
fun baz() {
|
||||
foo("boo")
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
fun <caret>String.foo() {
|
||||
bar()
|
||||
}
|
||||
|
||||
context(c: String)
|
||||
fun bar() {
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(string: String) fun foo() {
|
||||
bar()
|
||||
}
|
||||
|
||||
context(c: String)
|
||||
fun bar() {
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
// K2_AFTER_ERROR: Unresolved reference 'bar'.
|
||||
/* KTIJ-34522 */
|
||||
|
||||
context(c1: Int)
|
||||
fun <caret>Bar.foo() {
|
||||
"foo".bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
context(c: Int)
|
||||
fun String.bar() {}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
// K2_AFTER_ERROR: Unresolved reference 'bar'.
|
||||
/* KTIJ-34522 */
|
||||
|
||||
context(c1: Int, bar: Bar)
|
||||
fun foo() {
|
||||
"foo".bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
context(c: Int)
|
||||
fun String.bar() {}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c: Int)
|
||||
fun <caret>String.foo(param: String) {
|
||||
}
|
||||
|
||||
context(c1: Int)
|
||||
fun bar() {
|
||||
"baz".foo("boo")
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c: Int, string: String)
|
||||
fun foo(param: String) {
|
||||
}
|
||||
|
||||
context(c1: Int)
|
||||
fun bar() {
|
||||
with("baz") {
|
||||
foo("boo")
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
fun <caret>String.foo() {
|
||||
println(this)
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(string: String) fun foo() {
|
||||
println(string)
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
fun <caret>String.foo() {
|
||||
bar()
|
||||
}
|
||||
|
||||
fun String.bar() {
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(string: String) fun foo() {
|
||||
string.bar()
|
||||
}
|
||||
|
||||
fun String.bar() {
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c: Int)
|
||||
fun <caret>String.foo(param: String) {
|
||||
}
|
||||
|
||||
context(c1: Int)
|
||||
fun String.bar() {
|
||||
foo("boo")
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c: Int, string: String)
|
||||
fun foo(param: String) {
|
||||
}
|
||||
|
||||
context(c1: Int)
|
||||
fun String.bar() {
|
||||
foo("boo")
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
fun <caret>String.foo() {
|
||||
println(isEmpty())
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(string: String) fun foo() {
|
||||
println(string.isEmpty())
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// LANGUAGE_VERSION: 2.1
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun <caret>String.foo() {
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
// K2_AFTER_ERROR: Unresolved reference 'bar'.
|
||||
/* KTIJ-34522 */
|
||||
|
||||
fun <caret>Bar.foo() {
|
||||
"foo".bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun String.bar() {}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
// K2_AFTER_ERROR: Unresolved reference 'bar'.
|
||||
/* KTIJ-34522 */
|
||||
|
||||
context(bar: Bar) fun foo() {
|
||||
"foo".bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun String.bar() {}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
fun <caret>Bar.foo() {
|
||||
bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun bar() {}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(bar: Bar) fun foo() {
|
||||
bar.bar()
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun bar() {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c1: Int)
|
||||
fun <caret>String.foo() {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -Xcontext-parameters
|
||||
|
||||
context(c1: Int, string: String)
|
||||
fun foo() {
|
||||
}
|
||||
Reference in New Issue
Block a user