From 4c62788c3e331f0ac491f52f6e8f1e9b89b2b1ae Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Wed, 5 Jun 2019 14:47:52 +0900 Subject: [PATCH] Make "Add operator modifier" an inspection instead of intention #KT-31533 Fixed --- idea/resources/META-INF/plugin-common.xml | 14 ++++-- .../AddOperatorModifier.html | 5 ++ .../after.kt.template | 1 - .../before.kt.template | 1 - .../description.html | 5 -- .../AddOperatorModifierInspection.kt | 37 ++++++++++++++ .../AddOperatorModifierIntention.kt | 39 --------------- .../j2k/J2KPostProcessingRegistrarImpl.kt | 2 +- .../addOperatorModifier/.inspection | 1 + .../addOperatorModifier/containsBool.kt | 0 .../addOperatorModifier/containsBool.kt.after | 0 .../addOperatorModifier/containsInt.kt | 2 +- .../addOperatorModifier/extension.kt | 0 .../addOperatorModifier/extension.kt.after | 0 .../addOperatorModifier/forOverride.kt | 0 .../addOperatorModifier/forOverride.kt.after | 0 .../addOperatorModifier/overridden.kt | 2 +- .../addOperatorModifier/simple.kt | 0 .../addOperatorModifier/simple.kt.after | 0 .../addOperatorModifier/toplevel.kt | 2 +- .../intentions/addOperatorModifier/.intention | 1 - .../LocalInspectionTestGenerated.java | 48 +++++++++++++++++++ .../intentions/IntentionTestGenerated.java | 48 ------------------- .../nj2k/postProcessing/J2kPostProcessor.kt | 2 +- 24 files changed, 105 insertions(+), 105 deletions(-) create mode 100644 idea/resources/inspectionDescriptions/AddOperatorModifier.html delete mode 100644 idea/resources/intentionDescriptions/AddOperatorModifierIntention/after.kt.template delete mode 100644 idea/resources/intentionDescriptions/AddOperatorModifierIntention/before.kt.template delete mode 100644 idea/resources/intentionDescriptions/AddOperatorModifierIntention/description.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt delete mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt create mode 100644 idea/testData/inspectionsLocal/addOperatorModifier/.inspection rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/containsBool.kt (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/containsBool.kt.after (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/containsInt.kt (70%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/extension.kt (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/extension.kt.after (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/forOverride.kt (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/forOverride.kt.after (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/overridden.kt (82%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/simple.kt (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/simple.kt.after (100%) rename idea/testData/{intentions => inspectionsLocal}/addOperatorModifier/toplevel.kt (66%) delete mode 100644 idea/testData/intentions/addOperatorModifier/.intention diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index eef0bc80864..629ed9e5309 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -1265,11 +1265,6 @@ Kotlin - - org.jetbrains.kotlin.idea.intentions.AddOperatorModifierIntention - Kotlin - - org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaIntention Kotlin @@ -3381,6 +3376,15 @@ language="kotlin" /> + + diff --git a/idea/resources/inspectionDescriptions/AddOperatorModifier.html b/idea/resources/inspectionDescriptions/AddOperatorModifier.html new file mode 100644 index 00000000000..892b7d92acc --- /dev/null +++ b/idea/resources/inspectionDescriptions/AddOperatorModifier.html @@ -0,0 +1,5 @@ + + +This inspection reports a function that matches one of the operator conventions but is not annotated as operator. + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/after.kt.template b/idea/resources/intentionDescriptions/AddOperatorModifierIntention/after.kt.template deleted file mode 100644 index 8287e078ba7..00000000000 --- a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/after.kt.template +++ /dev/null @@ -1 +0,0 @@ -operator fun X.get(index: Int): String \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/before.kt.template b/idea/resources/intentionDescriptions/AddOperatorModifierIntention/before.kt.template deleted file mode 100644 index 4ca9328c501..00000000000 --- a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/before.kt.template +++ /dev/null @@ -1 +0,0 @@ -fun X.get(index: Int): String \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/description.html b/idea/resources/intentionDescriptions/AddOperatorModifierIntention/description.html deleted file mode 100644 index 3a497daa12d..00000000000 --- a/idea/resources/intentionDescriptions/AddOperatorModifierIntention/description.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This intention adds an operator modifier to a function that matches one of the operator conventions but is not annotated as operator. - - diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt new file mode 100644 index 00000000000..5e76b280d65 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.inspections + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.refactoring.withExpectedActuals +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.util.OperatorChecks + +class AddOperatorModifierInspection : AbstractApplicabilityBasedInspection( + KtNamedFunction::class.java +) { + override fun inspectionTarget(element: KtNamedFunction) = element.nameIdentifier ?: element + + override fun inspectionText(element: KtNamedFunction) = "Function should have 'operator' modifier" + + override val defaultFixText = "Add 'operator' modifier" + + override fun isApplicable(element: KtNamedFunction): Boolean { + if (element.nameIdentifier == null || element.hasModifier(KtTokens.OPERATOR_KEYWORD)) return false + val functionDescriptor = element.resolveToDescriptorIfAny() ?: return false + return !functionDescriptor.isOperator && OperatorChecks.check(functionDescriptor).isSuccess + } + + override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { + val function = element.getStrictParentOfType() ?: return + function.withExpectedActuals().forEach { it.addModifier(KtTokens.OPERATOR_KEYWORD) } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt deleted file mode 100644 index 6577e02fce5..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.intentions - -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.util.TextRange -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.refactoring.withExpectedActuals -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.util.OperatorChecks - -class AddOperatorModifierIntention : SelfTargetingRangeIntention(KtNamedFunction::class.java, "Add 'operator' modifier") { - override fun applicabilityRange(element: KtNamedFunction): TextRange? { - val nameIdentifier = element.nameIdentifier ?: return null - val functionDescriptor = element.resolveToDescriptorIfAny() ?: return null - if (functionDescriptor.isOperator || !OperatorChecks.check(functionDescriptor).isSuccess) return null - return nameIdentifier.textRange - } - - override fun applyTo(element: KtNamedFunction, editor: Editor?) { - element.withExpectedActuals().forEach { it.addModifier(KtTokens.OPERATOR_KEYWORD) } - } -} - diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt index a5abde45dbb..69158f2f015 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt @@ -95,7 +95,7 @@ object J2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { registerIntentionBasedProcessing(IfThenToElvisIntention()) registerInspectionBasedProcessing(SimplifyNegatedBinaryExpressionInspection()) registerInspectionBasedProcessing(ReplaceGetOrSetInspection()) - registerIntentionBasedProcessing(AddOperatorModifierIntention()) + registerInspectionBasedProcessing(AddOperatorModifierInspection()) registerIntentionBasedProcessing(ObjectLiteralToLambdaIntention()) registerIntentionBasedProcessing(AnonymousFunctionToLambdaIntention()) registerIntentionBasedProcessing(RemoveUnnecessaryParenthesesIntention()) diff --git a/idea/testData/inspectionsLocal/addOperatorModifier/.inspection b/idea/testData/inspectionsLocal/addOperatorModifier/.inspection new file mode 100644 index 00000000000..7e35b9d67a5 --- /dev/null +++ b/idea/testData/inspectionsLocal/addOperatorModifier/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.AddOperatorModifierInspection \ No newline at end of file diff --git a/idea/testData/intentions/addOperatorModifier/containsBool.kt b/idea/testData/inspectionsLocal/addOperatorModifier/containsBool.kt similarity index 100% rename from idea/testData/intentions/addOperatorModifier/containsBool.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/containsBool.kt diff --git a/idea/testData/intentions/addOperatorModifier/containsBool.kt.after b/idea/testData/inspectionsLocal/addOperatorModifier/containsBool.kt.after similarity index 100% rename from idea/testData/intentions/addOperatorModifier/containsBool.kt.after rename to idea/testData/inspectionsLocal/addOperatorModifier/containsBool.kt.after diff --git a/idea/testData/intentions/addOperatorModifier/containsInt.kt b/idea/testData/inspectionsLocal/addOperatorModifier/containsInt.kt similarity index 70% rename from idea/testData/intentions/addOperatorModifier/containsInt.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/containsInt.kt index 504a7e5b917..164223846aa 100644 --- a/idea/testData/intentions/addOperatorModifier/containsInt.kt +++ b/idea/testData/inspectionsLocal/addOperatorModifier/containsInt.kt @@ -1,4 +1,4 @@ -// IS_APPLICABLE: false +// PROBLEM: none class A { fun contains(other: A): Int = -1 } diff --git a/idea/testData/intentions/addOperatorModifier/extension.kt b/idea/testData/inspectionsLocal/addOperatorModifier/extension.kt similarity index 100% rename from idea/testData/intentions/addOperatorModifier/extension.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/extension.kt diff --git a/idea/testData/intentions/addOperatorModifier/extension.kt.after b/idea/testData/inspectionsLocal/addOperatorModifier/extension.kt.after similarity index 100% rename from idea/testData/intentions/addOperatorModifier/extension.kt.after rename to idea/testData/inspectionsLocal/addOperatorModifier/extension.kt.after diff --git a/idea/testData/intentions/addOperatorModifier/forOverride.kt b/idea/testData/inspectionsLocal/addOperatorModifier/forOverride.kt similarity index 100% rename from idea/testData/intentions/addOperatorModifier/forOverride.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/forOverride.kt diff --git a/idea/testData/intentions/addOperatorModifier/forOverride.kt.after b/idea/testData/inspectionsLocal/addOperatorModifier/forOverride.kt.after similarity index 100% rename from idea/testData/intentions/addOperatorModifier/forOverride.kt.after rename to idea/testData/inspectionsLocal/addOperatorModifier/forOverride.kt.after diff --git a/idea/testData/intentions/addOperatorModifier/overridden.kt b/idea/testData/inspectionsLocal/addOperatorModifier/overridden.kt similarity index 82% rename from idea/testData/intentions/addOperatorModifier/overridden.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/overridden.kt index 9c44bde4ecb..465cb8e34f3 100644 --- a/idea/testData/intentions/addOperatorModifier/overridden.kt +++ b/idea/testData/inspectionsLocal/addOperatorModifier/overridden.kt @@ -1,4 +1,4 @@ -// IS_APPLICABLE: false +// PROBLEM: none open class A { open operator fun plus(a: A) = A() } diff --git a/idea/testData/intentions/addOperatorModifier/simple.kt b/idea/testData/inspectionsLocal/addOperatorModifier/simple.kt similarity index 100% rename from idea/testData/intentions/addOperatorModifier/simple.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/simple.kt diff --git a/idea/testData/intentions/addOperatorModifier/simple.kt.after b/idea/testData/inspectionsLocal/addOperatorModifier/simple.kt.after similarity index 100% rename from idea/testData/intentions/addOperatorModifier/simple.kt.after rename to idea/testData/inspectionsLocal/addOperatorModifier/simple.kt.after diff --git a/idea/testData/intentions/addOperatorModifier/toplevel.kt b/idea/testData/inspectionsLocal/addOperatorModifier/toplevel.kt similarity index 66% rename from idea/testData/intentions/addOperatorModifier/toplevel.kt rename to idea/testData/inspectionsLocal/addOperatorModifier/toplevel.kt index 92aefcc4810..6e7e62ae6ee 100644 --- a/idea/testData/intentions/addOperatorModifier/toplevel.kt +++ b/idea/testData/inspectionsLocal/addOperatorModifier/toplevel.kt @@ -1,4 +1,4 @@ -// IS_APPLICABLE: false +// PROBLEM: none class A { } diff --git a/idea/testData/intentions/addOperatorModifier/.intention b/idea/testData/intentions/addOperatorModifier/.intention deleted file mode 100644 index bae269a0e51..00000000000 --- a/idea/testData/intentions/addOperatorModifier/.intention +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.kotlin.idea.intentions.AddOperatorModifierIntention \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 618345da153..a9b26ebc4c2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -29,6 +29,54 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("idea/testData/inspectionsLocal/addOperatorModifier") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AddOperatorModifier extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInAddOperatorModifier() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/addOperatorModifier"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); + } + + @TestMetadata("containsBool.kt") + public void testContainsBool() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/containsBool.kt"); + } + + @TestMetadata("containsInt.kt") + public void testContainsInt() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/containsInt.kt"); + } + + @TestMetadata("extension.kt") + public void testExtension() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/extension.kt"); + } + + @TestMetadata("forOverride.kt") + public void testForOverride() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/forOverride.kt"); + } + + @TestMetadata("overridden.kt") + public void testOverridden() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/overridden.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/simple.kt"); + } + + @TestMetadata("toplevel.kt") + public void testToplevel() throws Exception { + runTest("idea/testData/inspectionsLocal/addOperatorModifier/toplevel.kt"); + } + } + @TestMetadata("idea/testData/inspectionsLocal/arrayInDataClass") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 96a5dcd3c70..000c8afef73 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -1476,54 +1476,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } - @TestMetadata("idea/testData/intentions/addOperatorModifier") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class AddOperatorModifier extends AbstractIntentionTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); - } - - public void testAllFilesPresentInAddOperatorModifier() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/addOperatorModifier"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); - } - - @TestMetadata("containsBool.kt") - public void testContainsBool() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/containsBool.kt"); - } - - @TestMetadata("containsInt.kt") - public void testContainsInt() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/containsInt.kt"); - } - - @TestMetadata("extension.kt") - public void testExtension() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/extension.kt"); - } - - @TestMetadata("forOverride.kt") - public void testForOverride() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/forOverride.kt"); - } - - @TestMetadata("overridden.kt") - public void testOverridden() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/overridden.kt"); - } - - @TestMetadata("simple.kt") - public void testSimple() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/simple.kt"); - } - - @TestMetadata("toplevel.kt") - public void testToplevel() throws Exception { - runTest("idea/testData/intentions/addOperatorModifier/toplevel.kt"); - } - } - @TestMetadata("idea/testData/intentions/addPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt index 09691f9fa52..59c5d7e2759 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt @@ -125,7 +125,7 @@ private val processings: List = listOf( intentionBasedProcessing(IfThenToElvisIntention()), inspectionBasedProcessing(SimplifyNegatedBinaryExpressionInspection()), inspectionBasedProcessing(ReplaceGetOrSetInspection()), - intentionBasedProcessing(AddOperatorModifierIntention()), + inspectionBasedProcessing(AddOperatorModifierInspection()), intentionBasedProcessing(ObjectLiteralToLambdaIntention()), intentionBasedProcessing(AnonymousFunctionToLambdaIntention()), intentionBasedProcessing(RemoveUnnecessaryParenthesesIntention()),