From 5994a99dbb76eb54e757e58a48fd2ca299b7f278 Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Mon, 30 Jan 2023 16:45:20 +0000 Subject: [PATCH] [FIR] KT-54507: Report redundant for abstract interfaces ^KT-54507 Fixed Merge-request: KT-MR-8490 Merged-by: Nikolay Lunyak --- .../RedundantModalityModifierChecker.fir.txt | 15 ++++++++ .../RedundantModalityModifierChecker.kt | 8 ++++- .../fir/analysis/checkers/FirHelpers.kt | 36 +++++++------------ .../RedundantModalityModifierSyntaxChecker.kt | 7 +++- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.fir.txt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.fir.txt index e21c1110b95..eb9b6be8d6f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.fir.txt @@ -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() + } + + public final override val gav: R|kotlin/Int| = R|/gav| + public get(): R|kotlin/Int| + + public open override fun bar(): R|kotlin/Unit| { + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.kt index fd0cdf04d80..14e11b07b99 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantModalityModifierChecker.kt @@ -55,6 +55,8 @@ open class OpenDerived : Base() { override final fun bar() {} // Redundant open override open val gav = 13 + + private final fun fan() {} } // Redundant final final class Final @@ -78,8 +80,12 @@ abstract class AbstractDerived2 : Interface { override open val gav = 13 } // Redundant abstract interface -abstract interface AbstractInterface +abstract interface AbstractInterface // Redundant final object final object FinalObject // Open interface open interface OpenInterface + +class FinalDerived2(override final val gav: Int) : Base() { + override fun bar() {} +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index dc4f0f7fd63..39befc2da89 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -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) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierSyntaxChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierSyntaxChecker.kt index 384c0156934..052fed98b87 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierSyntaxChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierSyntaxChecker.kt @@ -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() { 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,