Redundant visibility modifier: do not report for public modifier that overrides protected setter visibility
#KT-33580 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
e8effe6727
commit
449c406e24
+40
-14
@@ -7,19 +7,27 @@ package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.idea.core.implicitVisibility
|
||||
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.declarationVisitor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
class RedundantVisibilityModifierInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||
return declarationVisitor { declaration ->
|
||||
if (declaration is KtPropertyAccessor && declaration.isGetter) return@declarationVisitor // There is a quick fix for REDUNDANT_MODIFIER_IN_GETTER
|
||||
val visibilityModifier = declaration.visibilityModifier() ?: return@declarationVisitor
|
||||
return declarationVisitor(fun(declaration: KtDeclaration) {
|
||||
if (declaration is KtPropertyAccessor && declaration.isGetter) return // There is a quick fix for REDUNDANT_MODIFIER_IN_GETTER
|
||||
val visibilityModifier = declaration.visibilityModifier() ?: return
|
||||
val implicitVisibility = declaration.implicitVisibility()
|
||||
val redundantVisibility = when {
|
||||
visibilityModifier.node.elementType == implicitVisibility ->
|
||||
@@ -28,18 +36,36 @@ class RedundantVisibilityModifierInspection : AbstractKotlinInspection(), Cleanu
|
||||
KtTokens.INTERNAL_KEYWORD
|
||||
else ->
|
||||
null
|
||||
}
|
||||
if (redundantVisibility != null) {
|
||||
holder.registerProblem(
|
||||
visibilityModifier,
|
||||
"Redundant visibility modifier",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
|
||||
IntentionWrapper(
|
||||
RemoveModifierFix(declaration, redundantVisibility, isRedundant = true),
|
||||
declaration.containingFile
|
||||
)
|
||||
} ?: return
|
||||
|
||||
if (redundantVisibility == KtTokens.PUBLIC_KEYWORD
|
||||
&& declaration is KtProperty
|
||||
&& declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)
|
||||
&& declaration.isVar
|
||||
&& declaration.setterVisibility().let { it != null && it != Visibilities.PUBLIC }
|
||||
) return
|
||||
|
||||
holder.registerProblem(
|
||||
visibilityModifier,
|
||||
"Redundant visibility modifier",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
|
||||
IntentionWrapper(
|
||||
RemoveModifierFix(declaration, redundantVisibility, isRedundant = true),
|
||||
declaration.containingFile
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
private fun KtProperty.setterVisibility(): Visibility? {
|
||||
val descriptor = descriptor as? PropertyDescriptor ?: return null
|
||||
if (setter?.visibilityModifier() != null) {
|
||||
val visibility = descriptor.setter?.visibility
|
||||
if (visibility != null) return visibility
|
||||
}
|
||||
return (descriptor as? CallableMemberDescriptor)
|
||||
?.overriddenDescriptors
|
||||
?.firstNotNullResult { (it as? PropertyDescriptor)?.setter }
|
||||
?.visibility
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
// PROBLEM: none
|
||||
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
class C : A() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// PROBLEM: none
|
||||
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
class C : A() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
set
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
class C : A() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
public set
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
class C : A() {
|
||||
override var attribute = super.attribute
|
||||
public set
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// PROBLEM: none
|
||||
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
abstract class B : A() {
|
||||
override var attribute = "b"
|
||||
}
|
||||
|
||||
class C : B() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
// PROBLEM: none
|
||||
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
abstract class B : A() {
|
||||
override var attribute = "b"
|
||||
set
|
||||
}
|
||||
|
||||
class C : B() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
abstract class B : A() {
|
||||
override var attribute = "b"
|
||||
public set
|
||||
}
|
||||
|
||||
class C : B() {
|
||||
<caret>public override var attribute = super.attribute
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
abstract class A {
|
||||
open var attribute = "a"
|
||||
protected set
|
||||
}
|
||||
|
||||
abstract class B : A() {
|
||||
override var attribute = "b"
|
||||
public set
|
||||
}
|
||||
|
||||
class C : B() {
|
||||
override var attribute = super.attribute
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val c = C()
|
||||
c.attribute = "test"
|
||||
}
|
||||
+30
@@ -7863,6 +7863,36 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
public void testOverridePropertySetter() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/overridePropertySetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter.kt")
|
||||
public void testPublicOverrideProtectedSetter() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter2.kt")
|
||||
public void testPublicOverrideProtectedSetter2() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter3.kt")
|
||||
public void testPublicOverrideProtectedSetter3() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter4.kt")
|
||||
public void testPublicOverrideProtectedSetter4() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter5.kt")
|
||||
public void testPublicOverrideProtectedSetter5() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter5.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicOverrideProtectedSetter6.kt")
|
||||
public void testPublicOverrideProtectedSetter6() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantVisibilityModifier/publicOverrideProtectedSetter6.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/redundantWith")
|
||||
|
||||
Reference in New Issue
Block a user