From 3be5f2b843e4df5a5dc15a4f4f3059449fcb25dd Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 28 Aug 2018 06:52:12 +0300 Subject: [PATCH] "Redundant visibility": Fix false positive for overridden setter #KT-26051 Fixed --- .../kotlin/idea/core/psiModificationUtils.kt | 18 ++++++++++++++++-- .../redundantVisibilityModifier/.inspection | 1 + .../overridePropertySetter.kt | 16 ++++++++++++++++ .../LocalInspectionTestGenerated.java | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 idea/testData/inspectionsLocal/redundantVisibilityModifier/.inspection create mode 100644 idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt 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 8c9ef33d5c3..48f895054a6 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 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens @@ -251,8 +252,20 @@ fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken addModifier(visibilityModifier) } -fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? = - when { +fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? { + if (this is KtPropertyAccessor && this.isSetter) { + val property = this.property + if (property.hasModifier(KtTokens.OVERRIDE_KEYWORD)) { + val visibility = (property.descriptor as? PropertyDescriptor) + ?.overriddenDescriptors + ?.firstOrNull() + ?.setter + ?.visibility + ?.toKeywordToken() + if (visibility != null) return visibility + } + } + return when { this is KtConstructor<*> -> { val klass = getContainingClassOrObject() if (klass is KtClass && (klass.isEnum() || klass.isSealed())) KtTokens.PRIVATE_KEYWORD @@ -268,6 +281,7 @@ fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? = KtTokens.DEFAULT_VISIBILITY_KEYWORD } } +} fun KtModifierListOwner.canBePrivate() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) != true diff --git a/idea/testData/inspectionsLocal/redundantVisibilityModifier/.inspection b/idea/testData/inspectionsLocal/redundantVisibilityModifier/.inspection new file mode 100644 index 00000000000..19adc2428cf --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantVisibilityModifier/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.RedundantVisibilityModifierInspection \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt b/idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt new file mode 100644 index 00000000000..ee96fa2977d --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt @@ -0,0 +1,16 @@ +// PROBLEM: none + +abstract class Foo { + abstract var id: Int + protected set +} + +class Bar : Foo() { + override var id: Int = 1 + public set +} + +fun test() { + val bar = Bar() + bar.id = 1 +} \ 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 bf2e2ed1076..59ec8cb366e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -4595,6 +4595,24 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } + @TestMetadata("idea/testData/inspectionsLocal/redundantVisibilityModifier") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RedundantVisibilityModifier extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInRedundantVisibilityModifier() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/redundantVisibilityModifier"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); + } + + @TestMetadata("overridePropertySetter.kt") + public void testOverridePropertySetter() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt"); + } + } + @TestMetadata("idea/testData/inspectionsLocal/redundantWith") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)