From 185d0c61659c8c2855c27e102237e8cbb67cd7a9 Mon Sep 17 00:00:00 2001 From: Felix Guo Date: Thu, 17 Jan 2019 01:28:58 +0300 Subject: [PATCH] Remove unnecessary constructor keyword intention (KT-29143) #KT-29143 Fixed --- .../kotlin/psi/KtPrimaryConstructor.kt | 8 +++ idea/resources/META-INF/plugin-common.xml | 5 ++ .../after.kt.template | 1 + .../before.kt.template | 1 + .../description.html | 5 ++ .../RemoveConstructorKeywordIntention.kt | 26 +++++++++ .../removeConstructorKeyword/.intention | 1 + .../removeConstructorKeyword/abstractClass.kt | 1 + .../abstractClass.kt.after | 1 + .../annotatedParam.kt | 5 ++ .../annotatedParam.kt.after | 5 ++ .../annotationClass.kt | 1 + .../annotationClass.kt.after | 1 + .../removeConstructorKeyword/comments.kt | 12 +++++ .../comments.kt.after | 11 ++++ .../removeConstructorKeyword/dataClass.kt | 1 + .../dataClass.kt.after | 1 + .../removeConstructorKeyword/inParameters.kt | 1 + .../inParameters.kt.after | 1 + .../removeConstructorKeyword/varargVal.kt | 1 + .../varargVal.kt.after | 1 + .../withProperties.kt | 1 + .../withProperties.kt.after | 1 + .../intentions/IntentionTestGenerated.java | 53 +++++++++++++++++++ 24 files changed, 145 insertions(+) create mode 100644 idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/description.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/RemoveConstructorKeywordIntention.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/.intention create mode 100644 idea/testData/intentions/removeConstructorKeyword/abstractClass.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/abstractClass.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/annotationClass.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/annotationClass.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/comments.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/comments.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/dataClass.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/dataClass.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/inParameters.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/inParameters.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/varargVal.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/varargVal.kt.after create mode 100644 idea/testData/intentions/removeConstructorKeyword/withProperties.kt create mode 100644 idea/testData/intentions/removeConstructorKeyword/withProperties.kt.after diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPrimaryConstructor.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPrimaryConstructor.kt index 459f608b11c..ab3a20b966a 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPrimaryConstructor.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPrimaryConstructor.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi import com.intellij.lang.ASTNode import com.intellij.psi.PsiElement +import com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier @@ -36,6 +37,13 @@ class KtPrimaryConstructor : KtConstructor { return getConstructorKeyword() ?: addBefore(KtPsiFactory(this).createConstructorKeyword(), valueParameterList!!) } + fun removeRedundantConstructorKeywordAndSpace() { + getConstructorKeyword()?.delete() + if (prevSibling is PsiWhiteSpace) { + prevSibling.delete() + } + } + override fun addModifier(modifier: KtModifierKeywordToken) { val modifierList = modifierList if (modifierList != null) { diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index c3f461a50fd..12690a1199e 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -1394,6 +1394,11 @@ Kotlin + + org.jetbrains.kotlin.idea.intentions.RemoveConstructorKeywordIntention + Kotlin + + org.jetbrains.kotlin.idea.intentions.ConvertPrimaryConstructorToSecondaryIntention Kotlin diff --git a/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/after.kt.template b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/after.kt.template new file mode 100644 index 00000000000..6a66078d06a --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/after.kt.template @@ -0,0 +1 @@ +class Foo(x: Int, y: Int) \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/before.kt.template b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/before.kt.template new file mode 100644 index 00000000000..18be3587874 --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/before.kt.template @@ -0,0 +1 @@ +class Foo constructor(x: Int, y: Int) \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/description.html b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/description.html new file mode 100644 index 00000000000..2d97b010dfc --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveConstructorKeywordIntention/description.html @@ -0,0 +1,5 @@ + + +This intention removes a redundant constructor keyword for primary constructors. + + \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveConstructorKeywordIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveConstructorKeywordIntention.kt new file mode 100644 index 00000000000..fec55ecd584 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveConstructorKeywordIntention.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.intentions + +import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtPrimaryConstructor +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject + +class RemoveConstructorKeywordIntention : SelfTargetingIntention( + KtPrimaryConstructor::class.java, + "Remove constructor keyword" +) { + override fun applyTo(element: KtPrimaryConstructor, editor: Editor?) { + element.removeRedundantConstructorKeywordAndSpace() + } + + override fun isApplicableTo(element: KtPrimaryConstructor, caretOffset: Int): Boolean { + if (element.containingClassOrObject !is KtClass) return false + if (element.getConstructorKeyword() == null) return false + return element.modifierList == null + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeConstructorKeyword/.intention b/idea/testData/intentions/removeConstructorKeyword/.intention new file mode 100644 index 00000000000..af7f73be7ee --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.RemoveConstructorKeywordIntention diff --git a/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt b/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt new file mode 100644 index 00000000000..6b9c8d4eb71 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt @@ -0,0 +1 @@ +abstract class Base constructor(val x: Int) diff --git a/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt.after b/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt.after new file mode 100644 index 00000000000..cb233823fa7 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/abstractClass.kt.after @@ -0,0 +1 @@ +abstract class Base(val x: Int) diff --git a/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt b/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt new file mode 100644 index 00000000000..9b61295f1cf --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt @@ -0,0 +1,5 @@ +annotation class Ann + +class AnnotatedParam constructor(@Ann x: Double) { + val y = x +} diff --git a/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt.after b/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt.after new file mode 100644 index 00000000000..e17a9481a71 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt.after @@ -0,0 +1,5 @@ +annotation class Ann + +class AnnotatedParam(@Ann x: Double) { + val y = x +} diff --git a/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt b/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt new file mode 100644 index 00000000000..a5837149250 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt @@ -0,0 +1 @@ +annotation class Ann constructor(val i: Int) diff --git a/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt.after b/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt.after new file mode 100644 index 00000000000..8e1c9a4c374 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/annotationClass.kt.after @@ -0,0 +1 @@ +annotation class Ann(val i: Int) diff --git a/idea/testData/intentions/removeConstructorKeyword/comments.kt b/idea/testData/intentions/removeConstructorKeyword/comments.kt new file mode 100644 index 00000000000..9c57523b801 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/comments.kt @@ -0,0 +1,12 @@ +/** + * An important class + */ +class WithComments +/** + * Some nasty constructor + */ +constructor( + /* First parameter */ + val first: Int, + /* Second Parameter */ + val second: Double) diff --git a/idea/testData/intentions/removeConstructorKeyword/comments.kt.after b/idea/testData/intentions/removeConstructorKeyword/comments.kt.after new file mode 100644 index 00000000000..ef23dc8d59e --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/comments.kt.after @@ -0,0 +1,11 @@ +/** + * An important class + */ +class WithComments +/** + * Some nasty constructor + */( + /* First parameter */ + val first: Int, + /* Second Parameter */ + val second: Double) diff --git a/idea/testData/intentions/removeConstructorKeyword/dataClass.kt b/idea/testData/intentions/removeConstructorKeyword/dataClass.kt new file mode 100644 index 00000000000..18156d1517b --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/dataClass.kt @@ -0,0 +1 @@ +data class Data constructor(val value: String) diff --git a/idea/testData/intentions/removeConstructorKeyword/dataClass.kt.after b/idea/testData/intentions/removeConstructorKeyword/dataClass.kt.after new file mode 100644 index 00000000000..5951cea9e1f --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/dataClass.kt.after @@ -0,0 +1 @@ +data class Data(val value: String) diff --git a/idea/testData/intentions/removeConstructorKeyword/inParameters.kt b/idea/testData/intentions/removeConstructorKeyword/inParameters.kt new file mode 100644 index 00000000000..7d7f7080679 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/inParameters.kt @@ -0,0 +1 @@ +class InParameters constructor(val x: Int, val y: Int = 7, private val z: Int = 13) diff --git a/idea/testData/intentions/removeConstructorKeyword/inParameters.kt.after b/idea/testData/intentions/removeConstructorKeyword/inParameters.kt.after new file mode 100644 index 00000000000..3e171c505b1 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/inParameters.kt.after @@ -0,0 +1 @@ +class InParameters(val x: Int, val y: Int = 7, private val z: Int = 13) diff --git a/idea/testData/intentions/removeConstructorKeyword/varargVal.kt b/idea/testData/intentions/removeConstructorKeyword/varargVal.kt new file mode 100644 index 00000000000..3305643630f --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/varargVal.kt @@ -0,0 +1 @@ +class VarargVal constructor(vararg val param: String) diff --git a/idea/testData/intentions/removeConstructorKeyword/varargVal.kt.after b/idea/testData/intentions/removeConstructorKeyword/varargVal.kt.after new file mode 100644 index 00000000000..17ea4bbf513 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/varargVal.kt.after @@ -0,0 +1 @@ +class VarargVal(vararg val param: String) \ No newline at end of file diff --git a/idea/testData/intentions/removeConstructorKeyword/withProperties.kt b/idea/testData/intentions/removeConstructorKeyword/withProperties.kt new file mode 100644 index 00000000000..42381c1d88a --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/withProperties.kt @@ -0,0 +1 @@ +class WithProperties constructor(val x: Int, val y: Int = 7, private val z: Int = 13) diff --git a/idea/testData/intentions/removeConstructorKeyword/withProperties.kt.after b/idea/testData/intentions/removeConstructorKeyword/withProperties.kt.after new file mode 100644 index 00000000000..13c57372369 --- /dev/null +++ b/idea/testData/intentions/removeConstructorKeyword/withProperties.kt.after @@ -0,0 +1 @@ +class WithProperties(val x: Int, val y: Int = 7, private val z: Int = 13) diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 35fab2613a5..086e019311e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -13257,6 +13257,59 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/removeConstructorKeyword") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RemoveConstructorKeyword extends AbstractIntentionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + @TestMetadata("abstractClass.kt") + public void testAbstractClass() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/abstractClass.kt"); + } + + public void testAllFilesPresentInRemoveConstructorKeyword() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeConstructorKeyword"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); + } + + @TestMetadata("annotatedParam.kt") + public void testAnnotatedParam() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/annotatedParam.kt"); + } + + @TestMetadata("annotationClass.kt") + public void testAnnotationClass() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/annotationClass.kt"); + } + + @TestMetadata("comments.kt") + public void testComments() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/comments.kt"); + } + + @TestMetadata("dataClass.kt") + public void testDataClass() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/dataClass.kt"); + } + + @TestMetadata("inParameters.kt") + public void testInParameters() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/inParameters.kt"); + } + + @TestMetadata("varargVal.kt") + public void testVarargVal() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/varargVal.kt"); + } + + @TestMetadata("withProperties.kt") + public void testWithProperties() throws Exception { + runTest("idea/testData/intentions/removeConstructorKeyword/withProperties.kt"); + } + } + @TestMetadata("idea/testData/intentions/removeCurlyBracesFromTemplate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)