From be0b01a1e620a976475eed49a4ea9314d1d1828d Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Fri, 28 Jul 2017 13:44:58 +0900 Subject: [PATCH] Do not report "can be private" on effectively private / local elements So #KT-18822 Fixed --- .../kotlin/descriptors/EffectiveVisibility.kt | 1 - .../MemberVisibilityCanPrivateInspection.kt | 18 +++-- .../inspectionData/expected.xml | 81 ++++++++++--------- .../memberVisibilityCanBePrivate/test.kt | 66 +++++++++++++-- 4 files changed, 119 insertions(+), 47 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index 3cf9d7d4e57..358c19a9a6d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.descriptors -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.descriptors.EffectiveVisibility.* diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt index c65f1f46a3e..c5544a59e06 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt @@ -26,6 +26,9 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiSearchHelper import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.util.Processor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility +import org.jetbrains.kotlin.descriptors.EffectiveVisibility +import org.jetbrains.kotlin.descriptors.effectiveVisibility import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.isOverridable @@ -58,22 +61,27 @@ class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { override fun visitParameter(parameter: KtParameter) { super.visitParameter(parameter) - if (parameter.isConstructorDeclaredProperty()) { - if ((parameter.ownerFunction?.parent as? KtClass)?.isPrivate() == true) return - if (canBePrivate(parameter)) registerProblem(holder, parameter) + if (parameter.isConstructorDeclaredProperty() && canBePrivate(parameter)) { + registerProblem(holder, parameter) } } } } - private fun canBePrivate(declaration: KtNamedDeclaration): Boolean { if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD) || declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false + + val descriptor = (declaration.toDescriptor() as? DeclarationDescriptorWithVisibility) ?: return false + when (descriptor.effectiveVisibility()) { + EffectiveVisibility.Private, EffectiveVisibility.Local -> return false + } + val classOrObject = declaration.containingClassOrObject ?: return false val inheritable = classOrObject is KtClass && classOrObject.isInheritable() if (!inheritable && declaration.hasModifier(KtTokens.PROTECTED_KEYWORD)) return false //reported by ProtectedInFinalInspection if (declaration.isOverridable()) return false - if (declaration.toDescriptor()?.hasJvmFieldAnnotation() != false) return false + + if (descriptor.hasJvmFieldAnnotation()) return false val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(declaration.project) val useScope = declaration.useScope diff --git a/idea/testData/inspections/memberVisibilityCanBePrivate/inspectionData/expected.xml b/idea/testData/inspections/memberVisibilityCanBePrivate/inspectionData/expected.xml index 68a6e1c82d5..09a5cc3257c 100644 --- a/idea/testData/inspections/memberVisibilityCanBePrivate/inspectionData/expected.xml +++ b/idea/testData/inspections/memberVisibilityCanBePrivate/inspectionData/expected.xml @@ -72,42 +72,6 @@ Property 'c' can be private - - test.kt - 109 - light_idea_test_case - - Can have 'private' visibility - Property 'a' can be private - - - - test.kt - 110 - light_idea_test_case - - Can have 'private' visibility - Property 'b' can be private - - - - test.kt - 114 - light_idea_test_case - - Can have 'private' visibility - Function 'f1' can be private - - - - test.kt - 115 - light_idea_test_case - - Can have 'private' visibility - Function 'f2' can be private - - test.kt 135 @@ -116,4 +80,49 @@ Can have 'private' visibility Property 'bar' can be private + + + test.kt + 180 + light_idea_test_case + + Class member can have 'private' visibility + Property 'a' can be private + + + + test.kt + 181 + light_idea_test_case + + Class member can have 'private' visibility + Property 'b' can be private + + + + test.kt + 182 + light_idea_test_case + + Class member can have 'private' visibility + Function 'c' can be private + + + + test.kt + 190 + light_idea_test_case + + Class member can have 'private' visibility + Property 'b' can be private + + + + test.kt + 191 + light_idea_test_case + + Class member can have 'private' visibility + Function 'c' can be private + diff --git a/idea/testData/inspections/memberVisibilityCanBePrivate/test.kt b/idea/testData/inspections/memberVisibilityCanBePrivate/test.kt index 7ce6078f71f..5371137015d 100644 --- a/idea/testData/inspections/memberVisibilityCanBePrivate/test.kt +++ b/idea/testData/inspections/memberVisibilityCanBePrivate/test.kt @@ -137,15 +137,71 @@ class G(val bar: Int) { } private class H(val a: String = "", - var b: String = "", - internal val c: String = "", - protected val d: String = "", - private val e: String = "") { + var b: String = "", + internal val c: String = "", + protected val d: String = "", + private val e: String = "") { + + var f: String = "" + fun g(): String = "" + fun foo() { println(a) println(b) println(c) println(d) println(e) + println(f) + println(g()) } -} \ No newline at end of file +} + +private class I { + class NestedCls(val a: String) { + var b: String = "" + fun c(): String = "" + fun foo() { + println(a) + println(b) + println(c()) + } + } + object NestedObj { + var b: String = "" + fun c(): String = "" + fun foo() { + println(b) + println(c()) + } + } +} + +class J { + class NestedCls(val a: String) { + var b: String = "" + fun c(): String = "" + fun foo() { + println(a) + println(b) + println(c()) + } + } + object NestedObj { + var b: String = "" + fun c(): String = "" + fun foo() { + println(b) + println(c()) + } + } +} + +fun withLocal(): Int { + class Local(val x: Int) { + val y = x + fun res() = x + y + } + + val local = Local(42) + return local.res() +}