From 6b0d87c77026bde63bc5f90269c7424bbc7abecd Mon Sep 17 00:00:00 2001 From: Andrey Cherkasov Date: Wed, 11 Sep 2024 03:24:40 +0400 Subject: [PATCH] [kotlin] Port AddValVarToConstructorParameterActionIntention to K2 IJ-CR-137425 ^KTIJ-29587 GitOrigin-RevId: 4e08de4e418113ea478a64bf27756c02e1344e70 --- ...dValVarToConstructorParameterFixFactory.kt | 10 +-- .../AddValVarToConstructorParameterUtils.kt | 20 ++++++ .../kotlin.code-insight.intentions.k2.xml | 7 ++ ...arToConstructorParameterActionIntention.kt | 51 +++++++++++++ .../tests/K2IntentionTestGenerated.java | 72 +++++++++++++++++++ .../intentions/addValOrVar/.k2Intention | 1 + .../quickfix/addValVar/addValAfterVarArg.kt | 4 +- .../addValVar/addValAfterVarArg.kt.after | 4 +- .../codeinsight/GenerateK2IntentionTests.kt | 2 +- 9 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/intentions/AddValVarToConstructorParameterUtils.kt create mode 100644 plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddValVarToConstructorParameterActionIntention.kt create mode 100644 plugins/kotlin/idea/tests/testData/intentions/addValOrVar/.k2Intention diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/AddValVarToConstructorParameterFixFactory.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/AddValVarToConstructorParameterFixFactory.kt index b0ff2ec4d464..fdd0d74043fb 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/AddValVarToConstructorParameterFixFactory.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/AddValVarToConstructorParameterFixFactory.kt @@ -9,11 +9,9 @@ import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KaFirDiagnostic import org.jetbrains.kotlin.idea.base.psi.mustHaveOnlyValPropertiesInPrimaryConstructor import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixFactory -import org.jetbrains.kotlin.idea.codeinsight.utils.ValVarExpression +import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.addValVarToConstructorParameter import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType internal object AddValVarToConstructorParameterFixFactory { @@ -45,11 +43,7 @@ internal object AddValVarToConstructorParameterFixFactory { actionContext: ActionContext, element: KtParameter, updater: ModPsiUpdater, - ) { - val valKeyword = element.addBefore(KtPsiFactory(actionContext.project).createValKeyword(), element.nameIdentifier) - if (element.containingClass()?.mustHaveOnlyValPropertiesInPrimaryConstructor() == true) return - updater.templateBuilder().field(valKeyword, ValVarExpression) - } + ) = addValVarToConstructorParameter(actionContext.project, element, updater) override fun getPresentation( context: ActionContext, diff --git a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/intentions/AddValVarToConstructorParameterUtils.kt b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/intentions/AddValVarToConstructorParameterUtils.kt new file mode 100644 index 000000000000..398a1a56bbf8 --- /dev/null +++ b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/intentions/AddValVarToConstructorParameterUtils.kt @@ -0,0 +1,20 @@ +// 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.codeinsights.impl.base.intentions + +import com.intellij.modcommand.ModPsiUpdater +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.base.psi.mustHaveOnlyValPropertiesInPrimaryConstructor +import org.jetbrains.kotlin.idea.codeinsight.utils.ValVarExpression +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.psiUtil.containingClass + +fun addValVarToConstructorParameter( + project: Project, + element: KtParameter, + updater: ModPsiUpdater, +) { + val valKeyword = element.addBefore(KtPsiFactory(project).createValKeyword(), element.nameIdentifier) + if (element.containingClass()?.mustHaveOnlyValPropertiesInPrimaryConstructor() == true) return + updater.templateBuilder().field(valKeyword, ValVarExpression) +} diff --git a/plugins/kotlin/code-insight/intentions-k2/resources/kotlin.code-insight.intentions.k2.xml b/plugins/kotlin/code-insight/intentions-k2/resources/kotlin.code-insight.intentions.k2.xml index fdc79c997110..3035fda91705 100644 --- a/plugins/kotlin/code-insight/intentions-k2/resources/kotlin.code-insight.intentions.k2.xml +++ b/plugins/kotlin/code-insight/intentions-k2/resources/kotlin.code-insight.intentions.k2.xml @@ -394,5 +394,12 @@ group.names.kotlin + + kotlin + org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddValVarToConstructorParameterActionIntention + messages.KotlinBundle + group.names.kotlin + + diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddValVarToConstructorParameterActionIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddValVarToConstructorParameterActionIntention.kt new file mode 100644 index 000000000000..0fa8797899d1 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddValVarToConstructorParameterActionIntention.kt @@ -0,0 +1,51 @@ +// 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.modcommand.ActionContext +import com.intellij.modcommand.ModPsiUpdater +import com.intellij.modcommand.Presentation +import com.intellij.openapi.util.TextRange +import org.jetbrains.kotlin.analysis.api.KaSession +import org.jetbrains.kotlin.idea.base.psi.mustHaveOnlyPropertiesInPrimaryConstructor +import org.jetbrains.kotlin.idea.base.psi.mustHaveValOrVar +import org.jetbrains.kotlin.idea.base.resources.KotlinBundle +import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinApplicableModCommandAction +import org.jetbrains.kotlin.idea.codeinsights.impl.base.applicators.ApplicabilityRanges +import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.addValVarToConstructorParameter +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtParameterList +import org.jetbrains.kotlin.psi.KtPrimaryConstructor +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.isExpectDeclaration + +class AddValVarToConstructorParameterActionIntention : KotlinApplicableModCommandAction(KtParameter::class) { + + override fun getFamilyName(): String = KotlinBundle.message("add.val.var.to.primary.constructor.parameter") + + override fun getPresentation(context: ActionContext, element: KtParameter): Presentation { + val actionName = KotlinBundle.message("add.val.var.to.parameter.0", element.name ?: "") + return Presentation.of(actionName) + } + + override fun isApplicableByPsi(element: KtParameter): Boolean { + if (element.valOrVarKeyword != null) return false + val constructor = (element.parent as? KtParameterList)?.parent as? KtPrimaryConstructor ?: return false + if (!constructor.mustHaveValOrVar() && constructor.isExpectDeclaration()) return false + val containingClass = element.getStrictParentOfType()?: return false + return !containingClass.mustHaveOnlyPropertiesInPrimaryConstructor() + } + + override fun getApplicableRanges(element: KtParameter): List = ApplicabilityRanges.declarationName(element) + + context(KaSession) + override fun prepareContext(element: KtParameter) { + } + + override fun invoke( + actionContext: ActionContext, + element: KtParameter, + elementContext: Unit, + updater: ModPsiUpdater, + ) = addValVarToConstructorParameter(actionContext.project, element, updater) +} diff --git a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java index 6ddbc837e4b7..58fb2301ac6b 100644 --- a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java +++ b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java @@ -10379,7 +10379,79 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../../idea/tests/testData/intentions/addValOrVar") + public static class AddValOrVar 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("actualClass.kt") + public void testActualClass() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/actualClass.kt"); + } + + @TestMetadata("addVal.kt") + public void testAddVal() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/addVal.kt"); + } + + @TestMetadata("dataClass.kt") + public void testDataClass() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/dataClass.kt"); + } + + @TestMetadata("expectAnnotation.kt") + public void testExpectAnnotation() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/expectAnnotation.kt"); + } + + @TestMetadata("expectClass.kt") + public void testExpectClass() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/expectClass.kt"); + } + + @TestMetadata("expectClass2.kt") + public void testExpectClass2() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/expectClass2.kt"); + } + + @TestMetadata("expectInlineClass.kt") + public void testExpectInlineClass() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/expectInlineClass.kt"); + } + + @TestMetadata("funParameter.kt") + public void testFunParameter() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/funParameter.kt"); + } + + @TestMetadata("hasVal.kt") + public void testHasVal() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/hasVal.kt"); + } + + @TestMetadata("hasVar.kt") + public void testHasVar() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/hasVar.kt"); + } + + @TestMetadata("outOfRange.kt") + public void testOutOfRange() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/outOfRange.kt"); + } + + @TestMetadata("secondaryConstructorParameter.kt") + public void testSecondaryConstructorParameter() throws Exception { + runTest("../../../idea/tests/testData/intentions/addValOrVar/secondaryConstructorParameter.kt"); + } + } diff --git a/plugins/kotlin/idea/tests/testData/intentions/addValOrVar/.k2Intention b/plugins/kotlin/idea/tests/testData/intentions/addValOrVar/.k2Intention new file mode 100644 index 000000000000..deb2c3b18076 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/addValOrVar/.k2Intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddValVarToConstructorParameterActionIntention \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt b/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt index 32b0be550791..47dee72de0c7 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt @@ -1,6 +1,6 @@ // "Add 'val' or 'var' to parameter 'x'" "true" -/* IGNORE_K2 */ class Foo(vararg x: Int, val y: Int) { } -// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction$Intention \ No newline at end of file +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction$Intention +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddValVarToConstructorParameterActionIntention \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt.after index 731f8d96d2d7..bf10a5eb01e4 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt.after +++ b/plugins/kotlin/idea/tests/testData/quickfix/addValVar/addValAfterVarArg.kt.after @@ -1,6 +1,6 @@ // "Add 'val' or 'var' to parameter 'x'" "true" -/* IGNORE_K2 */ class Foo(vararg val x: Int, val y: Int) { } -// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction$Intention \ No newline at end of file +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction$Intention +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddValVarToConstructorParameterActionIntention \ No newline at end of file diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2IntentionTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2IntentionTests.kt index 0f70a0094757..b18828449fab 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2IntentionTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2IntentionTests.kt @@ -181,7 +181,7 @@ internal fun MutableTWorkspace.generateK2IntentionTests() { model("${idea}intentions/convertReceiverToParameter", pattern = pattern) model("${idea}intentions/convertUnsafeCastCallToUnsafeCast", pattern = pattern, isIgnored = true) model("${idea}intentions/convertSnakeCaseTestFunctionToSpaced", pattern = pattern, isIgnored = true) - model("${idea}intentions/addValOrVar", pattern = pattern, isIgnored = true) + model("${idea}intentions/addValOrVar", pattern = pattern) model("${idea}intentions/convertBlockCommentToLineComment", pattern = pattern, isIgnored = true) model("${idea}intentions/removeSingleExpressionStringTemplate", pattern = pattern, isIgnored = true) model("${idea}intentions/convertLambdaToMultiLine", pattern = pattern, isIgnored = true)