[FIR] Introduce & use VISIBILITY_MODIFIER positioning strategy

This commit is contained in:
Mikhail Glukhikh
2020-11-24 17:07:33 +03:00
parent 7f1b539011
commit b1c9d4b046
5 changed files with 29 additions and 7 deletions
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
@@ -56,7 +55,7 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
&& declaration.setter?.visibility == Visibilities.Public
) return
reporter.report(declaration.source?.getChild(KtTokens.VISIBILITY_MODIFIERS), FirErrors.REDUNDANT_VISIBILITY_MODIFIER)
reporter.report(declaration.source, FirErrors.REDUNDANT_VISIBILITY_MODIFIER)
}
private fun FirDeclaration.implicitVisibility(context: CheckerContext): Visibility {
@@ -154,7 +154,7 @@ object FirErrors {
val WRONG_IMPLIES_CONDITION by error0<FirSourceElement, PsiElement>()
// Extended checkers group
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, PsiElement>()
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, PsiElement>()
val REDUNDANT_RETURN_UNIT_TYPE by warning0<FirSourceElement, PsiTypeElement>()
val REDUNDANT_EXPLICIT_TYPE by warning0<FirSourceElement, PsiElement>()
@@ -143,6 +143,22 @@ object LightTreePositioningStrategies {
}
}
val VISIBILITY_MODIFIER: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): List<TextRange> {
tree.visibilityModifier(node)?.let { return markElement(it, tree) }
tree.nameIdentifier(node)?.let { return markElement(it, tree) }
return when (node.tokenType) {
KtNodeTypes.OBJECT_DECLARATION -> {
markElement(tree.objectKeyword(node)!!, tree)
}
KtNodeTypes.PROPERTY_ACCESSOR -> {
markElement(tree.accessorNamePlaceholder(node), tree)
}
else -> markElement(node, tree)
}
}
}
val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): List<TextRange> {
return markElement(tree.operationReference(node) ?: node, tree)
@@ -180,6 +196,9 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.objectKeyword(node: Li
private fun FlyweightCapableTreeStructure<LighterASTNode>.valOrVarKeyword(node: LighterASTNode): LighterASTNode? =
findChildByType(node, VAL_VAR_TOKEN_SET)
private fun FlyweightCapableTreeStructure<LighterASTNode>.visibilityModifier(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtTokens.VISIBILITY_MODIFIERS)
private fun FlyweightCapableTreeStructure<LighterASTNode>.accessorNamePlaceholder(node: LighterASTNode): LighterASTNode =
findChildByType(node, KtTokens.GET_KEYWORD) ?: findChildByType(node, KtTokens.SET_KEYWORD)!!
@@ -33,6 +33,11 @@ object SourceElementPositioningStrategies {
PositioningStrategies.DECLARATION_SIGNATURE
)
val VISIBILITY_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.VISIBILITY_MODIFIER,
PositioningStrategies.VISIBILITY_MODIFIER
)
val OPERATOR = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR,
PositioningStrategies.OPERATOR
@@ -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.VISIBILITY_MODIFIERS
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compatibility.Incompatible
@@ -405,12 +406,10 @@ object PositioningStrategies {
@JvmField
val VISIBILITY_MODIFIER: PositioningStrategy<KtModifierListOwner> = object : PositioningStrategy<KtModifierListOwner>() {
override fun mark(element: KtModifierListOwner): List<TextRange> {
val visibilityTokens =
listOf(KtTokens.PRIVATE_KEYWORD, KtTokens.PROTECTED_KEYWORD, KtTokens.PUBLIC_KEYWORD, KtTokens.INTERNAL_KEYWORD)
val modifierList = element.modifierList
val result = visibilityTokens.mapNotNull { modifierList?.getModifier(it)?.textRange }
if (!result.isEmpty()) return result
val result = VISIBILITY_MODIFIERS.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
if (element is PsiNameIdentifierOwner) {