[FIR] KT-54507: Report redundant for abstract interfaces
^KT-54507 Fixed Merge-request: KT-MR-8490 Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
7ef7d0e062
commit
5994a99dbb
+15
@@ -83,6 +83,9 @@ FILE: RedundantModalityModifierChecker.kt
|
||||
public open override val gav: R|kotlin/Int| = Int(13)
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
private final fun fan(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public final class Final : R|kotlin/Any| {
|
||||
public constructor(): R|Final| {
|
||||
@@ -136,3 +139,15 @@ FILE: RedundantModalityModifierChecker.kt
|
||||
}
|
||||
public open interface OpenInterface : R|kotlin/Any| {
|
||||
}
|
||||
public final class FinalDerived2 : R|Base| {
|
||||
public constructor(gav: R|kotlin/Int|): R|FinalDerived2| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
public final override val gav: R|kotlin/Int| = R|<local>/gav|
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public open override fun bar(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+7
-1
@@ -55,6 +55,8 @@ open class OpenDerived : Base() {
|
||||
override final fun bar() {}
|
||||
// Redundant open
|
||||
override <!REDUNDANT_MODALITY_MODIFIER!>open<!> val gav = 13
|
||||
|
||||
private <!REDUNDANT_MODALITY_MODIFIER!>final<!> fun fan() {}
|
||||
}
|
||||
// Redundant final
|
||||
<!REDUNDANT_MODALITY_MODIFIER!>final<!> class Final
|
||||
@@ -78,8 +80,12 @@ abstract class AbstractDerived2 : Interface {
|
||||
override <!REDUNDANT_MODALITY_MODIFIER!>open<!> val gav = 13
|
||||
}
|
||||
// Redundant abstract interface
|
||||
abstract interface AbstractInterface
|
||||
<!REDUNDANT_MODALITY_MODIFIER!>abstract<!> interface AbstractInterface
|
||||
// Redundant final object
|
||||
<!REDUNDANT_MODALITY_MODIFIER!>final<!> object FinalObject
|
||||
// Open interface
|
||||
<!REDUNDANT_MODIFIER_FOR_TARGET!>open<!> interface OpenInterface
|
||||
|
||||
class FinalDerived2(override <!REDUNDANT_MODALITY_MODIFIER!>final<!> val gav: Int) : Base() {
|
||||
override fun bar() {}
|
||||
}
|
||||
|
||||
+13
-23
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
|
||||
@@ -225,32 +224,23 @@ fun FirClass.modality(): Modality? {
|
||||
* returns implicit modality by FirMemberDeclaration<*>
|
||||
*/
|
||||
fun FirMemberDeclaration.implicitModality(context: CheckerContext): Modality {
|
||||
if (this is FirRegularClass && (this.classKind == ClassKind.CLASS || this.classKind == ClassKind.OBJECT)) {
|
||||
if (this.classKind == ClassKind.INTERFACE) return Modality.ABSTRACT
|
||||
return Modality.FINAL
|
||||
}
|
||||
|
||||
val klass = context.findClosestClassOrObject() ?: return Modality.FINAL
|
||||
val source = source ?: return Modality.FINAL
|
||||
val tree = source.treeStructure
|
||||
if (tree.overrideModifier(source.lighterASTNode) != null) {
|
||||
val klassModalityTokenType = klass.source?.let { tree.modalityModifier(it.lighterASTNode)?.tokenType }
|
||||
if (klassModalityTokenType == KtTokens.ABSTRACT_KEYWORD ||
|
||||
klassModalityTokenType == KtTokens.OPEN_KEYWORD ||
|
||||
klassModalityTokenType == KtTokens.SEALED_KEYWORD
|
||||
) {
|
||||
return Modality.OPEN
|
||||
if (this is FirRegularClass) {
|
||||
return when (classKind) {
|
||||
ClassKind.INTERFACE -> Modality.ABSTRACT
|
||||
else -> Modality.FINAL
|
||||
}
|
||||
}
|
||||
|
||||
if (klass is FirRegularClass
|
||||
&& klass.classKind == ClassKind.INTERFACE
|
||||
&& tree.visibilityModifier(source.lighterASTNode)?.tokenType != KtTokens.PRIVATE_KEYWORD
|
||||
) {
|
||||
return if (this.hasBody()) Modality.OPEN else Modality.ABSTRACT
|
||||
}
|
||||
val containingClass = context.findClosestClassOrObject() ?: return Modality.FINAL
|
||||
|
||||
return Modality.FINAL
|
||||
return when {
|
||||
isOverride && !containingClass.isFinal -> Modality.OPEN
|
||||
containingClass.isInterface -> when {
|
||||
hasBody() -> Modality.OPEN
|
||||
else -> Modality.ABSTRACT
|
||||
}
|
||||
else -> Modality.FINAL
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.hasBody(): Boolean = when (this) {
|
||||
|
||||
+6
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -19,13 +20,17 @@ import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
|
||||
object RedundantModalityModifierSyntaxChecker : FirDeclarationSyntaxChecker<FirDeclaration, KtDeclaration>() {
|
||||
|
||||
override fun isApplicable(element: FirDeclaration, source: KtSourceElement): Boolean =
|
||||
source.kind !is KtFakeSourceElementKind && element is FirMemberDeclaration
|
||||
element.isMemberWithRealSource && element !is FirValueParameter
|
||||
|| element.source?.kind == KtFakeSourceElementKind.PropertyFromParameter
|
||||
|
||||
private val FirDeclaration.isMemberWithRealSource get() = this is FirMemberDeclaration && source?.kind is KtRealSourceElementKind
|
||||
|
||||
override fun checkPsiOrLightTree(
|
||||
element: FirDeclaration,
|
||||
|
||||
Reference in New Issue
Block a user