From e47e9f67639edb560ca623e40d8bd3f46f92538a Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Jan 2016 13:31:43 +0100 Subject: [PATCH] inspection and code cleanup for redundant visibility modifiers --- .../kotlin/idea/core/psiModificationUtils.kt | 19 ++++--- idea/src/META-INF/plugin.xml | 7 +++ .../RedundantVisibilityModifierInspection.kt | 51 +++++++++++++++++++ .../inspectionData/expected.xml | 30 +++++++++++ .../inspectionData/inspections.test | 1 + .../redundantVisibilityModifier.kt | 22 ++++++++ .../redundantVisibilityModifier/.inspection | 1 + .../redundantVisibilityModifier/simple.kt | 3 ++ .../simple.kt.after | 3 ++ .../codeInsight/InspectionTestGenerated.java | 6 +++ .../idea/quickfix/QuickFixTestGenerated.java | 15 ++++++ 11 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/RedundantVisibilityModifierInspection.kt create mode 100644 idea/testData/inspections/redundantVisibilityModifier/inspectionData/expected.xml create mode 100644 idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test create mode 100644 idea/testData/inspections/redundantVisibilityModifier/redundantVisibilityModifier.kt create mode 100644 idea/testData/quickfix/redundantVisibilityModifier/.inspection create mode 100644 idea/testData/quickfix/redundantVisibilityModifier/simple.kt create mode 100644 idea/testData/quickfix/redundantVisibilityModifier/simple.kt.after diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index ffd67178590..ab369ebfa0c 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -166,6 +166,17 @@ public fun KtClass.getOrCreateCompanionObject() : KtObjectDeclaration { //TODO: code style option whether to insert redundant 'public' keyword or not public fun KtDeclaration.setVisibility(visibilityModifier: KtModifierKeywordToken) { + val defaultVisibilityKeyword = implicitVisibility() + + if (visibilityModifier == defaultVisibilityKeyword) { + this.visibilityModifierType()?.let { removeModifier(it) } + return + } + + addModifier(visibilityModifier) +} + +fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? { val defaultVisibilityKeyword = if (hasModifier(KtTokens.OVERRIDE_KEYWORD)) { (resolveToDescriptor() as? CallableMemberDescriptor) ?.overriddenDescriptors @@ -175,13 +186,7 @@ public fun KtDeclaration.setVisibility(visibilityModifier: KtModifierKeywordToke else { KtTokens.DEFAULT_VISIBILITY_KEYWORD } - - if (visibilityModifier == defaultVisibilityKeyword) { - this.visibilityModifierType()?.let { removeModifier(it) } - return - } - - addModifier(visibilityModifier) + return defaultVisibilityKeyword } fun KtSecondaryConstructor.getOrCreateBody(): KtBlockExpression { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 7401485cc76..6c1a109ddb2 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1308,6 +1308,13 @@ cleanupTool="true" level="WARNING"/> + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantVisibilityModifierInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantVisibilityModifierInspection.kt new file mode 100644 index 00000000000..9f6cec56887 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantVisibilityModifierInspection.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2016 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.inspections + +import com.intellij.codeInspection.* +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.idea.core.implicitVisibility +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtVisitorVoid +import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier + +class RedundantVisibilityModifierInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { + return object : KtVisitorVoid() { + override fun visitDeclaration(dcl: KtDeclaration) { + val visibilityModifier = dcl.visibilityModifier() ?: return + if (visibilityModifier.node.elementType == dcl.implicitVisibility()) { + holder.registerProblem(visibilityModifier, + "Redundant visibility modifier", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + RemoveVisibilityModifierFix()) + } + } + } + } + + class RemoveVisibilityModifierFix : LocalQuickFix { + override fun getName(): String = "Remove redundant visibility modifier" + + override fun getFamilyName(): String = getName() + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + descriptor.psiElement.delete() + } + } +} diff --git a/idea/testData/inspections/redundantVisibilityModifier/inspectionData/expected.xml b/idea/testData/inspections/redundantVisibilityModifier/inspectionData/expected.xml new file mode 100644 index 00000000000..62cb5ff4b2e --- /dev/null +++ b/idea/testData/inspections/redundantVisibilityModifier/inspectionData/expected.xml @@ -0,0 +1,30 @@ + + + redundantVisibilityModifier.kt + 1 + + Redundant visibility modifier + Redundant visibility modifier + + + redundantVisibilityModifier.kt + 2 + + Redundant visibility modifier + Redundant visibility modifier + + + redundantVisibilityModifier.kt + 4 + + Redundant visibility modifier + Redundant visibility modifier + + + redundantVisibilityModifier.kt + 17 + + Redundant visibility modifier + Redundant visibility modifier + + diff --git a/idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test b/idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test new file mode 100644 index 00000000000..f9a57e0f5f8 --- /dev/null +++ b/idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test @@ -0,0 +1 @@ +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.RedundantVisibilityModifierInspection diff --git a/idea/testData/inspections/redundantVisibilityModifier/redundantVisibilityModifier.kt b/idea/testData/inspections/redundantVisibilityModifier/redundantVisibilityModifier.kt new file mode 100644 index 00000000000..fd2bb8c5f3a --- /dev/null +++ b/idea/testData/inspections/redundantVisibilityModifier/redundantVisibilityModifier.kt @@ -0,0 +1,22 @@ +public class C { + public val foo: Int = 0 + + public fun bar() {} + +} + +open class D { + protected open fun willRemainProtected() { + } + + protected open fun willBecomePublic() { + } +} + +class E : D() { + protected override fun willRemainProtected() { + } + + public override fun willBecomePublic() { + } +} diff --git a/idea/testData/quickfix/redundantVisibilityModifier/.inspection b/idea/testData/quickfix/redundantVisibilityModifier/.inspection new file mode 100644 index 00000000000..19adc2428cf --- /dev/null +++ b/idea/testData/quickfix/redundantVisibilityModifier/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.RedundantVisibilityModifierInspection \ No newline at end of file diff --git a/idea/testData/quickfix/redundantVisibilityModifier/simple.kt b/idea/testData/quickfix/redundantVisibilityModifier/simple.kt new file mode 100644 index 00000000000..ba4cdeb5f98 --- /dev/null +++ b/idea/testData/quickfix/redundantVisibilityModifier/simple.kt @@ -0,0 +1,3 @@ +// "Remove redundant visibility modifier" "true" +public class C { +} diff --git a/idea/testData/quickfix/redundantVisibilityModifier/simple.kt.after b/idea/testData/quickfix/redundantVisibilityModifier/simple.kt.after new file mode 100644 index 00000000000..27c1041c890 --- /dev/null +++ b/idea/testData/quickfix/redundantVisibilityModifier/simple.kt.after @@ -0,0 +1,3 @@ +// "Remove redundant visibility modifier" "true" +class C { +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java index 1d09b0273a7..5a1ce2b7d4c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java @@ -118,6 +118,12 @@ public class InspectionTestGenerated extends AbstractInspectionTest { doTest(fileName); } + @TestMetadata("redundantVisibilityModifier/inspectionData/inspections.test") + public void testRedundantVisibilityModifier_inspectionData_Inspections_test() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test"); + doTest(fileName); + } + @TestMetadata("spelling/inspectionData/inspections.test") public void testSpelling_inspectionData_Inspections_test() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/spelling/inspectionData/inspections.test"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 9a67301ffcf..37683af2f5c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5848,6 +5848,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/redundantVisibilityModifier") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RedundantVisibilityModifier extends AbstractQuickFixTest { + public void testAllFilesPresentInRedundantVisibilityModifier() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/redundantVisibilityModifier"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/redundantVisibilityModifier/simple.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/removeUnused") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)