From 5fbdc0af5e6a89d52d50a7b3eca3d497ebc04e79 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 25 Nov 2020 13:51:22 +0300 Subject: [PATCH] [FIR] Introduce & use MODALITY_MODIFIER positioning strategy --- .../RedundantModalityModifierChecker.kt | 11 +++++------ .../fir/analysis/diagnostics/FirErrors.kt | 2 +- .../LightTreePositioningStrategies.kt | 17 +++++++++++++---- .../SourceElementPositioningStrategies.kt | 5 +++++ .../kotlin/diagnostics/PositioningStrategies.kt | 12 +++++++++--- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt index 3915541e22b..deaaf10ead8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt @@ -11,17 +11,17 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMemberDeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.implicitModality -import org.jetbrains.kotlin.fir.analysis.checkers.toToken import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER -import org.jetbrains.kotlin.fir.analysis.getChild +import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.modality object RedundantModalityModifierChecker : FirMemberDeclarationChecker() { override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { - if (declaration.source?.kind is FirFakeSourceElementKind) return + val source = declaration.source + if (source?.kind is FirFakeSourceElementKind) return val modality = declaration.modality ?: return if ( @@ -29,11 +29,10 @@ object RedundantModalityModifierChecker : FirMemberDeclarationChecker() { && (context.containingDeclarations.last() as? FirClass<*>)?.classKind == ClassKind.INTERFACE ) return + if (source != null && source.treeStructure.modalityModifier(source.lighterASTNode) == null) return val implicitModality = declaration.implicitModality(context) - if (modality != implicitModality) return - val modalityModifierSource = declaration.source?.getChild(modality.toToken(), depth = 2) - reporter.report(modalityModifierSource, REDUNDANT_MODALITY_MODIFIER) + reporter.report(source, REDUNDANT_MODALITY_MODIFIER) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 536e4bd3711..981469e9b4b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -155,7 +155,7 @@ object FirErrors { // Extended checkers group val REDUNDANT_VISIBILITY_MODIFIER by warning0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) - val REDUNDANT_MODALITY_MODIFIER by warning0() + val REDUNDANT_MODALITY_MODIFIER by warning0(SourceElementPositioningStrategies.MODALITY_MODIFIER) val REDUNDANT_RETURN_UNIT_TYPE by warning0() val REDUNDANT_EXPLICIT_TYPE by warning0() val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index 43f112837f7..b4418cf6948 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -14,6 +14,8 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS +import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET object LightTreePositioningStrategies { @@ -143,9 +145,9 @@ object LightTreePositioningStrategies { } } - val VISIBILITY_MODIFIER: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { + private class ModifierSetBasedLightTreePositioningStrategy(private val modifierSet: TokenSet) : LightTreePositioningStrategy() { override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure): List { - tree.visibilityModifier(node)?.let { return markElement(it, tree) } + tree.findChildByType(node, modifierSet)?.let { return markElement(it, tree) } tree.nameIdentifier(node)?.let { return markElement(it, tree) } return when (node.tokenType) { KtNodeTypes.OBJECT_DECLARATION -> { @@ -159,6 +161,10 @@ object LightTreePositioningStrategies { } } + val VISIBILITY_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(VISIBILITY_MODIFIERS) + + val MODALITY_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(MODALITY_MODIFIERS) + val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure): List { return markElement(tree.operationReference(node) ?: node, tree) @@ -196,8 +202,11 @@ private fun FlyweightCapableTreeStructure.objectKeyword(node: Li private fun FlyweightCapableTreeStructure.valOrVarKeyword(node: LighterASTNode): LighterASTNode? = findChildByType(node, VAL_VAR_TOKEN_SET) -private fun FlyweightCapableTreeStructure.visibilityModifier(node: LighterASTNode): LighterASTNode? = - findChildByType(node, KtTokens.VISIBILITY_MODIFIERS) +internal fun FlyweightCapableTreeStructure.visibilityModifier(declaration: LighterASTNode): LighterASTNode? = + modifierList(declaration)?.let { findChildByType(it, VISIBILITY_MODIFIERS) } + +internal fun FlyweightCapableTreeStructure.modalityModifier(declaration: LighterASTNode): LighterASTNode? = + modifierList(declaration)?.let { findChildByType(it, MODALITY_MODIFIERS) } private fun FlyweightCapableTreeStructure.accessorNamePlaceholder(node: LighterASTNode): LighterASTNode = findChildByType(node, KtTokens.GET_KEYWORD) ?: findChildByType(node, KtTokens.SET_KEYWORD)!! diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index f5efd5b8b60..f5eb8792cea 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -38,6 +38,11 @@ object SourceElementPositioningStrategies { PositioningStrategies.VISIBILITY_MODIFIER ) + val MODALITY_MODIFIER = SourceElementPositioningStrategy( + LightTreePositioningStrategies.MODALITY_MODIFIER, + PositioningStrategies.MODALITY_MODIFIER + ) + val OPERATOR = SourceElementPositioningStrategy( LightTreePositioningStrategies.OPERATOR, PositioningStrategies.OPERATOR diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 721d31e708a..ade1bd61250 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.diagnostics.Errors.ACTUAL_WITHOUT_EXPECT import org.jetbrains.kotlin.diagnostics.Errors.NO_ACTUAL_FOR_EXPECT import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* @@ -403,12 +404,11 @@ object PositioningStrategies { } } - @JvmField - val VISIBILITY_MODIFIER: PositioningStrategy = object : PositioningStrategy() { + private class ModifierSetBasedPositioningStrategy(private val modifierSet: TokenSet) : PositioningStrategy() { override fun mark(element: KtModifierListOwner): List { val modifierList = element.modifierList - val result = VISIBILITY_MODIFIERS.types.mapNotNull { modifierList?.getModifier(it as KtModifierKeywordToken)?.textRange } + val result = modifierSet.types.mapNotNull { modifierList?.getModifier(it as KtModifierKeywordToken)?.textRange } if (result.isNotEmpty()) return result // Try to resolve situation when there's no visibility modifiers written before element @@ -431,6 +431,12 @@ object PositioningStrategies { } } + @JvmField + val VISIBILITY_MODIFIER: PositioningStrategy = ModifierSetBasedPositioningStrategy(VISIBILITY_MODIFIERS) + + @JvmField + val MODALITY_MODIFIER: PositioningStrategy = ModifierSetBasedPositioningStrategy(MODALITY_MODIFIERS) + @JvmField val VARIANCE_IN_PROJECTION: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: KtTypeProjection): List {