FE: report DECLARATION_CANT_BE_INLINED at 'inline' modifier

#KT-44022 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-11-25 10:45:54 +03:00
parent 4df937ff7f
commit 2f1d415e4d
10 changed files with 111 additions and 42 deletions
@@ -15,8 +15,7 @@ import org.jetbrains.kotlin.KtNodeType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
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.lexer.KtTokens.*
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType
@@ -339,18 +338,33 @@ object LightTreePositioningStrategies {
false
}
private class ModifierSetBasedLightTreePositioningStrategy(private val modifierSet: TokenSet) : LightTreePositioningStrategy() {
private open class ModifierSetBasedLightTreePositioningStrategy(private val modifierSet: TokenSet) : LightTreePositioningStrategy() {
protected fun markModifier(
node: LighterASTNode?,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>,
baseNode: LighterASTNode
): List<TextRange>? {
if (node == null) return null
val modifierList = tree.modifierList(node)
if (modifierList != null) {
tree.findChildByType(modifierList, modifierSet)?.let {
return markElement(it, startOffset, endOffset, tree, baseNode)
}
}
return null
}
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val modifierList = tree.modifierList(node)
if (modifierList != null) {
tree.findChildByType(modifierList, modifierSet)?.let {
return markElement(it, startOffset, endOffset, tree, node)
}
val modifierListRange = markModifier(node, startOffset, endOffset, tree, node)
if (modifierListRange != null) {
return modifierListRange
}
tree.nameIdentifier(node)?.let {
return markElement(it, startOffset, endOffset, tree, node)
@@ -367,6 +381,22 @@ object LightTreePositioningStrategies {
}
}
private class InlineFunLightTreePositioningStrategy : ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(INLINE_KEYWORD)) {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
if (node.tokenType == KtNodeTypes.PROPERTY) {
return markModifier(tree.getter(node), startOffset, endOffset, tree, node)
?: markModifier(tree.setter(node), startOffset, endOffset, tree, node)
?: super.mark(node, startOffset, endOffset, tree)
}
return super.mark(node, startOffset, endOffset, tree)
}
}
val VISIBILITY_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(VISIBILITY_MODIFIERS)
val MODALITY_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(MODALITY_MODIFIERS)
@@ -402,7 +432,7 @@ object LightTreePositioningStrategies {
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.SUSPEND_KEYWORD, KtTokens.FUN_KEYWORD))
val INLINE_OR_VALUE_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(INLINE_KEYWORD, KtTokens.VALUE_KEYWORD))
val INNER_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INNER_KEYWORD))
@@ -442,6 +472,8 @@ object LightTreePositioningStrategies {
val INLINE_PARAMETER_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
val INLINE_FUN_MODIFIER: LightTreePositioningStrategy = InlineFunLightTreePositioningStrategy()
val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
@@ -1222,7 +1254,7 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.overrideModifier(declaration:
modifierList(declaration)?.let { findChildByType(it, KtTokens.OVERRIDE_KEYWORD) }
fun FlyweightCapableTreeStructure<LighterASTNode>.inlineModifier(declaration: LighterASTNode): LighterASTNode? =
modifierList(declaration)?.let { findChildByType(it, KtTokens.INLINE_KEYWORD) }
modifierList(declaration)?.let { findChildByType(it, INLINE_KEYWORD) }
fun FlyweightCapableTreeStructure<LighterASTNode>.typeParametersList(declaration: LighterASTNode): LighterASTNode? =
findChildByType(declaration, KtNodeTypes.TYPE_PARAMETER_LIST)
@@ -1241,6 +1273,22 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.userType(node: LighterASTNode)
private fun FlyweightCapableTreeStructure<LighterASTNode>.supertypesList(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtNodeTypes.SUPER_TYPE_LIST)
private fun FlyweightCapableTreeStructure<LighterASTNode>.getter(node: LighterASTNode): LighterASTNode? {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)
return childrenRef.get()?.firstOrNull {
it != null && it.tokenType == KtNodeTypes.PROPERTY_ACCESSOR && findChildByType(it, GET_KEYWORD) != null
}
}
private fun FlyweightCapableTreeStructure<LighterASTNode>.setter(node: LighterASTNode): LighterASTNode? {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)
return childrenRef.get()?.firstOrNull {
it != null && it.tokenType == KtNodeTypes.PROPERTY_ACCESSOR && findChildByType(it, SET_KEYWORD) != null
}
}
private fun FlyweightCapableTreeStructure<LighterASTNode>.accessorNamePlaceholder(node: LighterASTNode): LighterASTNode =
findChildByType(node, KtTokens.GET_KEYWORD) ?: findChildByType(node, KtTokens.SET_KEYWORD)!!
@@ -399,12 +399,15 @@ object PositioningStrategies {
}
}
private class ModifierSetBasedPositioningStrategy(private val modifierSet: TokenSet) : PositioningStrategy<KtModifierListOwner>() {
override fun mark(element: KtModifierListOwner): List<TextRange> {
val modifierList = element.modifierList
private open class ModifierSetBasedPositioningStrategy(private val modifierSet: TokenSet) : PositioningStrategy<KtModifierListOwner>() {
protected fun markModifier(element: KtModifierListOwner?): List<TextRange>? =
modifierSet.types.mapNotNull {
element?.modifierList?.getModifier(it as KtModifierKeywordToken)?.textRange
}.takeIf { it.isNotEmpty() }
val result = modifierSet.types.mapNotNull { modifierList?.getModifier(it as KtModifierKeywordToken)?.textRange }
if (result.isNotEmpty()) return result
override fun mark(element: KtModifierListOwner): List<TextRange> {
val result = markModifier(element)
if (result != null) return result
// Try to resolve situation when there's no visibility modifiers written before element
if (element is PsiNameIdentifierOwner) {
@@ -426,6 +429,15 @@ object PositioningStrategies {
}
}
private class InlineFunPositioningStrategy : ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD)) {
override fun mark(element: KtModifierListOwner): List<TextRange> {
if (element is KtProperty) {
return markModifier(element.getter) ?: markModifier(element.setter) ?: super.mark(element)
}
return super.mark(element)
}
}
@JvmField
val VISIBILITY_MODIFIER: PositioningStrategy<KtModifierListOwner> = ModifierSetBasedPositioningStrategy(VISIBILITY_MODIFIERS)
@@ -444,6 +456,9 @@ object PositioningStrategies {
val INLINE_PARAMETER_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
@JvmField
val INLINE_FUN_MODIFIER: PositioningStrategy<KtModifierListOwner> = InlineFunPositioningStrategy()
@JvmField
val VARIANCE_IN_PROJECTION: PositioningStrategy<KtTypeProjection> = object : PositioningStrategy<KtTypeProjection>() {
override fun mark(element: KtTypeProjection): List<TextRange> {
@@ -315,6 +315,11 @@ object SourceElementPositioningStrategies {
PositioningStrategies.INLINE_PARAMETER_MODIFIER
)
val INLINE_FUN_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.INLINE_FUN_MODIFIER,
PositioningStrategies.INLINE_FUN_MODIFIER
)
val OPERATOR_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR_MODIFIER,
PositioningStrategies.OPERATOR_MODIFIER