FE: report DECLARATION_CANT_BE_INLINED at 'inline' modifier
#KT-44022 Fixed
This commit is contained in:
+58
-10
@@ -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)!!
|
||||
|
||||
|
||||
+20
-5
@@ -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> {
|
||||
|
||||
+5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user