FE: report DECLARATION_CANT_BE_INLINED at 'inline' modifier
#KT-44022 Fixed
This commit is contained in:
+1
-1
@@ -1320,7 +1320,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<Symbol>("symbol")
|
||||
}
|
||||
|
||||
val DECLARATION_CANT_BE_INLINED by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
val DECLARATION_CANT_BE_INLINED by error<KtDeclaration>(PositioningStrategy.INLINE_FUN_MODIFIER)
|
||||
|
||||
val OVERRIDE_BY_INLINE by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
|
||||
|
||||
+1
@@ -112,6 +112,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
IMPORT_ALIAS,
|
||||
DECLARATION_START_TO_NAME,
|
||||
REDUNDANT_NULLABLE,
|
||||
INLINE_FUN_MODIFIER,
|
||||
|
||||
;
|
||||
|
||||
|
||||
+1
-1
@@ -689,7 +689,7 @@ object FirErrors {
|
||||
val PROTECTED_CALL_FROM_PUBLIC_INLINE by warning2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PRIVATE_CLASS_MEMBER_FROM_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val SUPER_CALL_FROM_PUBLIC_INLINE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val DECLARATION_CANT_BE_INLINED by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
val DECLARATION_CANT_BE_INLINED by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_FUN_MODIFIER)
|
||||
val OVERRIDE_BY_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
val NON_INTERNAL_PUBLISHED_API by error0<KtElement>()
|
||||
val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error2<KtElement, FirExpression, FirValueParameterSymbol>()
|
||||
|
||||
+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
|
||||
|
||||
@@ -1163,7 +1163,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<KtElement, KtExpression, DeclarationDescriptor> USAGE_IS_NOT_INLINABLE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<KtElement, KtElement, DeclarationDescriptor> NULLABLE_INLINE_PARAMETER = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<KtElement, KtElement, DeclarationDescriptor> RECURSION_IN_INLINE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory0<KtDeclaration> DECLARATION_CANT_BE_INLINED = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> DECLARATION_CANT_BE_INLINED = DiagnosticFactory0.create(ERROR, INLINE_FUN_MODIFIER);
|
||||
DiagnosticFactory0<KtDeclaration> OVERRIDE_BY_INLINE = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<PsiElement> REIFIED_TYPE_PARAMETER_IN_OVERRIDE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, CallableDescriptor> INLINE_CALL_CYCLE = DiagnosticFactory1.create(ERROR, DEFAULT);
|
||||
|
||||
+13
-13
@@ -14,17 +14,17 @@ abstract class A {
|
||||
inline final fun good4() {}
|
||||
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open protected fun wrong1()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open protected fun wrong1() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open public fun wrong2()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open public fun wrong2() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open fun wrong3()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open fun wrong3() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline abstract protected fun wrong4()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> abstract protected fun wrong4()
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline abstract public fun wrong5()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> abstract public fun wrong5()
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline abstract fun wrong6()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> abstract fun wrong6()
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,17 @@ interface B {
|
||||
|
||||
inline private fun good1() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline fun wrong1()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> fun wrong1() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open fun wrong2()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open fun wrong2() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open public fun wrong3()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open public fun wrong3() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open fun wrong4()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open fun wrong4() {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline fun wrong5()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> fun wrong5()
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline public fun wrong6()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> public fun wrong6()
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline fun wrong7()<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> fun wrong7()
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@ class CDerived : IBase {
|
||||
|
||||
open class COpen : IBase {
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
|
||||
override <!DECLARATION_CANT_BE_INLINED!>inline<!> fun bar() {}
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
|
||||
|
||||
open class COpenNested : IBase {
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
|
||||
override <!DECLARATION_CANT_BE_INLINED!>inline<!> fun bar() {}
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ open class COpen : IBase {
|
||||
fun aMethod() {
|
||||
open class COpenLocal : IBase {
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
|
||||
override <!DECLARATION_CANT_BE_INLINED!>inline<!> fun bar() {}
|
||||
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,23 +17,23 @@ final class FinalProperty {
|
||||
|
||||
|
||||
open class OpenProperty {
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open val valProp: Int<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open val valProp: Int
|
||||
get() = 1
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>open val valProp_1: Int<!>
|
||||
inline get() = 1
|
||||
open val valProp_1: Int
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> get() = 1
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline open var varProp: Int<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> open var varProp: Int
|
||||
get() = 1
|
||||
set(p: Int) {}
|
||||
|
||||
<!DECLARATION_CANT_BE_INLINED!>open var varProp_2: Int<!>
|
||||
open var varProp_2: Int
|
||||
get() = 1
|
||||
inline set(p: Int) {}
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> set(p: Int) {}
|
||||
}
|
||||
|
||||
|
||||
interface AbstractProperty {
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline abstract val valProp: Int<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline abstract var varProp: Int<!>
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> abstract val valProp: Int
|
||||
<!DECLARATION_CANT_BE_INLINED!>inline<!> abstract var varProp: Int
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user