[FIR] Fix redundant visibility checker

This commit is contained in:
vladislavf7@gmail.com
2020-07-13 16:05:43 +03:00
committed by Mikhail Glukhikh
parent 9b8128aaa8
commit d96772444e
3 changed files with 77 additions and 11 deletions
@@ -50,3 +50,23 @@ fun f() {
}
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> var baz = 0
open class J {
protected val baz = 0
<!REDUNDANT_VISIBILITY_MODIFIER!>protected<!> get() = field * 2
var baf = 0
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> get() = 1
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> set(value) {
field = value
}
var buf = 0
private get() = 42
protected set(value) {
field = value
}
var bar = 0
get() = 3.1415926535
set(value) {}
}
@@ -114,3 +114,37 @@ FILE: RedundantVisibilityModifierChecker.kt
public final var baz: R|kotlin/Int| = Int(0)
public get(): R|kotlin/Int|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
public open class J : R|kotlin/Any| {
public constructor(): R|J| {
super<R|kotlin/Any|>()
}
protected final val baz: R|kotlin/Int| = Int(0)
protected get(): R|kotlin/Int| {
^ this@R|/J|.F|/J.baz|.R|kotlin/Int.times|(Int(2))
}
public final var baf: R|kotlin/Int| = Int(0)
public get(): R|kotlin/Int| {
^ Int(1)
}
public set(value: R|kotlin/Int|): R|kotlin/Unit| {
this@R|/J|.F|/J.baf| = R|<local>/value|
}
public final var buf: R|kotlin/Int| = Int(0)
private get(): R|kotlin/Int| {
^ Int(42)
}
protected set(value: R|kotlin/Int|): R|kotlin/Unit| {
this@R|/J|.F|/J.buf| = R|<local>/value|
}
public final var bar: R|kotlin/Int| = Int(0)
public get(): R|kotlin/Int| {
^ Double(3.1415926535)
}
public set(value: R|kotlin/Int|): R|kotlin/Unit| {
}
}
@@ -23,27 +23,30 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
override val isExtended = true
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration is FirPropertyAccessor && declaration.isGetter) return
if (declaration !is FirMemberDeclaration) return
if (declaration is FirConstructor && declaration.source is FirFakeSourceElement<*>) return
if (declaration.source is FirFakeSourceElement<*>) return
if (
declaration !is FirMemberDeclaration
&& !(declaration is FirPropertyAccessor
&& declaration.visibility == (context.containingDeclarations.last() as FirProperty).visibility)
) return
val modifierList = (declaration.source.getModifierList() as? FirPsiModifierList)?.modifierList ?: return
val visibilityModifier = modifierList.getVisibility()
val visibilityModifier = modifierList.getVisibility() ?: return
val implicitVisibility = declaration.implicitVisibility(context)
val containingMemberDeclaration = context.containingDeclarations.getOrNull(1) as? FirMemberDeclaration
val containingMemberDeclaration = context.findClosest<FirMemberDeclaration>()
val redundantVisibility = when {
visibilityModifier == implicitVisibility -> implicitVisibility
visibilityModifier == Visibilities.INTERNAL
&& containingMemberDeclaration?.visibility == Visibilities.PRIVATE
|| declaration.visibility == Visibilities.INTERNAL -> Visibilities.INTERNAL
|| declaration.visibilityForDeclarationAndPropertyAccessor == Visibilities.INTERNAL -> Visibilities.INTERNAL
else -> null
} ?: return
if (redundantVisibility == Visibilities.PUBLIC
&& declaration is FirProperty
&& declaration.isVar
&& declaration.setter?.visibility.let { it != null && it != Visibilities.PUBLIC }
&& declaration is FirPropertyAccessor
&& declaration.source is FirFakeSourceElement<*>
) return
val source = modifierList.visibilityModifier()?.toFirPsiSourceElement()
@@ -52,8 +55,10 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
private fun FirDeclaration.implicitVisibility(context: CheckerContext): Visibility {
return when {
this is FirPropertyAccessor && isSetter && status.isOverride -> {
this.visibility
this is FirPropertyAccessor && isSetter && status.isOverride -> this.visibility
this is FirPropertyAccessor -> {
context.findClosest<FirProperty>()?.visibility ?: Visibilities.DEFAULT_VISIBILITY
}
this is FirConstructor -> {
@@ -69,7 +74,7 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
}
this is FirSimpleFunction
&& context.containingDeclarations.getOrNull(1) is FirClass<*>
&& context.containingDeclarations.last() is FirClass<*>
&& this.isOverride -> findFunctionVisibility(this, context)
else -> Visibilities.DEFAULT_VISIBILITY
@@ -102,4 +107,11 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
}
return null
}
private val FirDeclaration.visibilityForDeclarationAndPropertyAccessor
get() = when (this) {
is FirMemberDeclaration -> status.visibility
is FirPropertyAccessor -> status.visibility
else -> null
}
}