From 5594af0d703a67b7c5cc802cf0feb8c35cf09c81 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Thu, 14 Jan 2021 11:32:05 -0800 Subject: [PATCH] FIR checker: utilize modifier retrievals --- .../declaration/FirModifierChecker.kt | 70 ---------------- .../checkers/declaration/FirModifierUtils.kt | 84 +++++++++++++++++++ 2 files changed, 84 insertions(+), 70 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierUtils.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt index 1f0920854e2..9612745ddc6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt @@ -5,13 +5,8 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.lang.ASTNode -import com.intellij.lang.LighterASTNode -import com.intellij.psi.tree.TokenSet -import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors @@ -19,8 +14,6 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens.* -import org.jetbrains.kotlin.psi.KtModifierList -import org.jetbrains.kotlin.psi.KtModifierListOwner object FirModifierChecker : FirBasicDeclarationChecker() { @@ -201,67 +194,4 @@ object FirModifierChecker : FirBasicDeclarationChecker() { ) { report(FirErrors.INCOMPATIBLE_MODIFIERS.on(modifier.source, firstKeyword, secondKeyword)) } - - private sealed class FirModifierList { - abstract val modifiers: List> - - class FirPsiModifierList(val modifierList: KtModifierList) : FirModifierList() { - override val modifiers: List - get() = modifierList.node.getChildren(MODIFIER_KEYWORD_SET).map { node -> - FirModifier.FirPsiModifier(node, node.elementType as KtModifierKeywordToken) - } - - } - - class FirLightModifierList( - val modifierList: LighterASTNode, - val tree: FlyweightCapableTreeStructure - ) : FirModifierList() { - override val modifiers: List - get() { - val modifierNodes = modifierList.getChildren(tree) - return modifierNodes.filterNotNull() - .filter { it.tokenType is KtModifierKeywordToken } - .map { FirModifier.FirLightModifier(it, it.tokenType as KtModifierKeywordToken, tree) } - } - } - - companion object { - fun FirSourceElement?.getModifierList(): FirModifierList? { - return when (this) { - null -> null - is FirPsiSourceElement<*> -> (psi as? KtModifierListOwner)?.modifierList?.let { FirPsiModifierList(it) } - is FirLightSourceElement -> { - val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST } - ?: return null - FirLightModifierList(modifierListNode, treeStructure) - } - } - } - } - } - - private val MODIFIER_KEYWORD_SET = TokenSet.orSet(SOFT_KEYWORDS, TokenSet.create(IN_KEYWORD, FUN_KEYWORD)) - - sealed class FirModifier(val node: Node, val token: KtModifierKeywordToken) { - - class FirPsiModifier( - node: ASTNode, - token: KtModifierKeywordToken - ) : FirModifier(node, token) { - override val source: FirSourceElement - get() = node.psi.toFirPsiSourceElement() - } - - class FirLightModifier( - node: LighterASTNode, - token: KtModifierKeywordToken, - val tree: FlyweightCapableTreeStructure - ) : FirModifier(node, token) { - override val source: FirSourceElement - get() = node.toFirLightSourceElement(tree) - } - - abstract val source: FirSourceElement - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierUtils.kt new file mode 100644 index 00000000000..2aed20a46d7 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierUtils.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import com.intellij.lang.ASTNode +import com.intellij.lang.LighterASTNode +import com.intellij.psi.tree.TokenSet +import com.intellij.util.diff.FlyweightCapableTreeStructure +import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.analysis.checkers.getChildren +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtModifierList +import org.jetbrains.kotlin.psi.KtModifierListOwner + +// DO +// - use this to retrieve modifiers on the source and confirm a certain modifier indeed appears +// DON'T +// - don't use this to report an error or warning *on* that specific modifier. Use positioning strategies instead. +internal sealed class FirModifierList { + abstract val modifiers: List> + + class FirPsiModifierList(val modifierList: KtModifierList) : FirModifierList() { + override val modifiers: List + get() = modifierList.node.getChildren(MODIFIER_KEYWORD_SET).map { node -> + FirModifier.FirPsiModifier(node, node.elementType as KtModifierKeywordToken) + } + } + + class FirLightModifierList( + val modifierList: LighterASTNode, + val tree: FlyweightCapableTreeStructure + ) : FirModifierList() { + override val modifiers: List + get() { + val modifierNodes = modifierList.getChildren(tree) + return modifierNodes.filterNotNull() + .filter { it.tokenType is KtModifierKeywordToken } + .map { FirModifier.FirLightModifier(it, it.tokenType as KtModifierKeywordToken, tree) } + } + } + + companion object { + fun FirSourceElement?.getModifierList(): FirModifierList? { + return when (this) { + null -> null + is FirPsiSourceElement<*> -> (psi as? KtModifierListOwner)?.modifierList?.let { FirPsiModifierList(it) } + is FirLightSourceElement -> { + val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST } + ?: return null + FirLightModifierList(modifierListNode, treeStructure) + } + } + } + } +} + +private val MODIFIER_KEYWORD_SET = TokenSet.orSet(KtTokens.SOFT_KEYWORDS, TokenSet.create(KtTokens.IN_KEYWORD, KtTokens.FUN_KEYWORD)) + +internal sealed class FirModifier(val node: Node, val token: KtModifierKeywordToken) { + + class FirPsiModifier( + node: ASTNode, + token: KtModifierKeywordToken + ) : FirModifier(node, token) { + override val source: FirSourceElement + get() = node.psi.toFirPsiSourceElement() + } + + class FirLightModifier( + node: LighterASTNode, + token: KtModifierKeywordToken, + val tree: FlyweightCapableTreeStructure + ) : FirModifier(node, token) { + override val source: FirSourceElement + get() = node.toFirLightSourceElement(tree) + } + + abstract val source: FirSourceElement +}