[FIR] KT-54507 Report REDUNDANT_MODALITY_MODIFIER for open interface
- `REDUNDANT_MODIFIER_FOR_TARGET` is already reported for `open` interfaces, but for consistency and IDE support, the compiler now reports `REDUNDANT_MODALITY_MODIFIER` as well via the extended checker. - `REDUNDANT_MODIFIER_FOR_TARGET` cannot be disabled for this case because it's reported via a basic checker while `REDUNDANT_MODALITY_MODIFIER` is reported via an extended checker. - Rename `implicitModality` to `redundantModalities` and return a set of modalities. The idea of a *single* implicit/redundant modality doesn't stand up to scrutiny. For example, for interfaces with `ABSTRACT` implicit modality, `OPEN` is also a redundant modifier. But this is not necessarily the case for all kinds of declarations. Hypothetically, if it was possible to declare a class that is abstract by default, adding an `open` modifier to that class would not be redundant, as it would make the class instantiable.
This commit is contained in:
committed by
Space Team
parent
76ca96d2e2
commit
5909b191a5
@@ -221,25 +221,26 @@ fun FirClass.modality(): Modality? {
|
||||
}
|
||||
|
||||
/**
|
||||
* returns implicit modality by FirMemberDeclaration<*>
|
||||
* Returns a set of [Modality] modifiers which are redundant for the given [FirMemberDeclaration]. If a modality modifier is redundant, the
|
||||
* declaration's modality won't be changed by the modifier.
|
||||
*/
|
||||
fun FirMemberDeclaration.implicitModality(context: CheckerContext): Modality {
|
||||
fun FirMemberDeclaration.redundantModalities(context: CheckerContext): Set<Modality> {
|
||||
if (this is FirRegularClass) {
|
||||
return when (classKind) {
|
||||
ClassKind.INTERFACE -> Modality.ABSTRACT
|
||||
else -> Modality.FINAL
|
||||
ClassKind.INTERFACE -> setOf(Modality.ABSTRACT, Modality.OPEN)
|
||||
else -> setOf(Modality.FINAL)
|
||||
}
|
||||
}
|
||||
|
||||
val containingClass = context.findClosestClassOrObject() ?: return Modality.FINAL
|
||||
val containingClass = context.findClosestClassOrObject() ?: return setOf(Modality.FINAL)
|
||||
|
||||
return when {
|
||||
isOverride && !containingClass.isFinal -> Modality.OPEN
|
||||
isOverride && !containingClass.isFinal -> setOf(Modality.OPEN)
|
||||
containingClass.isInterface -> when {
|
||||
hasBody() -> Modality.OPEN
|
||||
else -> Modality.ABSTRACT
|
||||
hasBody() -> setOf(Modality.OPEN)
|
||||
else -> setOf(Modality.ABSTRACT, Modality.OPEN)
|
||||
}
|
||||
else -> Modality.FINAL
|
||||
else -> setOf(Modality.FINAL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -10,13 +10,13 @@ import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.implicitModality
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDeclarationSyntaxChecker
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
||||
import org.jetbrains.kotlin.diagnostics.modalityModifier
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.redundantModalities
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDeclarationSyntaxChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
@@ -46,8 +46,8 @@ object RedundantModalityModifierSyntaxChecker : FirDeclarationSyntaxChecker<FirD
|
||||
) return
|
||||
|
||||
if (source.treeStructure.modalityModifier(source.lighterASTNode) == null) return
|
||||
val implicitModality = element.implicitModality(context)
|
||||
if (modality == implicitModality) {
|
||||
val redundantModalities = element.redundantModalities(context)
|
||||
if (redundantModalities.contains(modality)) {
|
||||
reporter.reportOn(source, REDUNDANT_MODALITY_MODIFIER, context)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user