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()
+}