FIR: fix positioning in fun interface checker
This commit is contained in:
@@ -53,3 +53,9 @@ FILE: funInterfaceDeclaration.kt
|
||||
public abstract fun test(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface Test14 : R|kotlin/Any| {
|
||||
public abstract suspend fun test(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface Test15 : R|Test14| {
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// !LANGUAGE: -SuspendFunctionsInFunInterfaces
|
||||
|
||||
<!FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS!>fun<!> interface Test1{
|
||||
fun foo()
|
||||
fun boo()
|
||||
@@ -8,13 +10,13 @@ fun interface Test3 {
|
||||
fun foo()
|
||||
}
|
||||
fun interface Test4{
|
||||
fun <<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!>T<!>> foo(a: T)
|
||||
fun <!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!><T><!> foo(a: T)
|
||||
}
|
||||
fun interface Test5{
|
||||
fun foo(<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE!>a: Int = 5<!>)
|
||||
}
|
||||
fun interface Test6{
|
||||
suspend fun foo()
|
||||
<!FUN_INTERFACE_WITH_SUSPEND_FUNCTION!>suspend<!> fun foo()
|
||||
}
|
||||
fun interface Test7{
|
||||
fun foo()
|
||||
@@ -36,3 +38,8 @@ interface Test11 {
|
||||
<!FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES!>fun<!> interface Test12 : Test11 {
|
||||
fun test()
|
||||
}
|
||||
interface Test14 {
|
||||
suspend fun test()
|
||||
}
|
||||
<!FUN_INTERFACE_WITH_SUSPEND_FUNCTION!>fun<!> interface Test15 : Test14
|
||||
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
TYPE_PARAMETERS_LIST,
|
||||
FUN_MODIFIER,
|
||||
SUSPEND_MODIFIER,
|
||||
FUN_INTERFACE_ABSTRACT_PROPERTY,
|
||||
FUN_INTERFACE,
|
||||
|
||||
;
|
||||
|
||||
|
||||
+4
-4
@@ -500,10 +500,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val FUN_INTERFACES by object : DiagnosticGroup("Fun interfaces") {
|
||||
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
||||
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error<KtClass>(PositioningStrategy.FUN_MODIFIER)
|
||||
val FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES by error<KtDeclaration>(PositioningStrategy.FUN_INTERFACE_ABSTRACT_PROPERTY)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS by error<PsiElement>()
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE by error<PsiElement>()
|
||||
val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error<KtFunction>(PositioningStrategy.SUSPEND_MODIFIER)
|
||||
val FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES by error<KtDeclaration>(PositioningStrategy.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS by error<KtDeclaration>(PositioningStrategy.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE by error<KtDeclaration>(PositioningStrategy.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error<KtDeclaration>(PositioningStrategy.FUN_INTERFACE)
|
||||
}
|
||||
|
||||
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
||||
|
||||
+4
-4
@@ -311,10 +311,10 @@ object FirErrors {
|
||||
// Fun interfaces
|
||||
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error0<KtClass>(SourceElementPositioningStrategies.FUN_MODIFIER)
|
||||
val FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE_ABSTRACT_PROPERTY)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS by error0<PsiElement>()
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE by error0<PsiElement>()
|
||||
val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error0<KtFunction>(SourceElementPositioningStrategies.SUSPEND_MODIFIER)
|
||||
val FUN_INTERFACE_CANNOT_HAVE_ABSTRACT_PROPERTIES by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE)
|
||||
val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE)
|
||||
|
||||
// Properties & accessors
|
||||
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||
|
||||
+13
-3
@@ -63,23 +63,33 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
|
||||
return
|
||||
}
|
||||
|
||||
val inFunInterface = abstractFunction.getContainingClass(context) === declaration
|
||||
|
||||
when {
|
||||
abstractFunction.typeParameters.isNotEmpty() ->
|
||||
reporter.reportOn(
|
||||
abstractFunction.typeParameters.first().source,
|
||||
if (inFunInterface) abstractFunction.source else declaration.source,
|
||||
FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS,
|
||||
context
|
||||
)
|
||||
|
||||
abstractFunction.isSuspend ->
|
||||
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.SuspendFunctionsInFunInterfaces)) {
|
||||
reporter.reportOn(abstractFunction.source, FUN_INTERFACE_WITH_SUSPEND_FUNCTION, context)
|
||||
reporter.reportOn(
|
||||
if (inFunInterface) abstractFunction.source else declaration.source,
|
||||
FUN_INTERFACE_WITH_SUSPEND_FUNCTION,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
abstractFunction.valueParameters.forEach {
|
||||
if (it.defaultValue != null) {
|
||||
reporter.reportOn(it.source, FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE, context)
|
||||
reporter.reportOn(
|
||||
if (inFunInterface) it.source else declaration.source,
|
||||
FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-3
@@ -346,6 +346,9 @@ object LightTreePositioningStrategies {
|
||||
val SUSPEND_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.SUSPEND_KEYWORD))
|
||||
|
||||
private val SUSPEND_OR_FUN_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.SUSPEND_KEYWORD, KtTokens.FUN_KEYWORD))
|
||||
|
||||
val INLINE_OR_VALUE_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD))
|
||||
|
||||
@@ -449,7 +452,7 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val FUN_INTERFACE_ABSTRACT_PROPERTY: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
val FUN_INTERFACE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
@@ -459,6 +462,13 @@ object LightTreePositioningStrategies {
|
||||
return when (node.tokenType) {
|
||||
KtNodeTypes.CLASS -> FUN_MODIFIER.mark(node, startOffset, endOffset, tree)
|
||||
KtNodeTypes.PROPERTY -> VAL_OR_VAR_NODE.mark(node, startOffset, endOffset, tree)
|
||||
KtNodeTypes.FUN -> {
|
||||
if (tree.typeParametersList(node) != null) {
|
||||
TYPE_PARAMETERS_LIST.mark(node, startOffset, endOffset, tree)
|
||||
} else {
|
||||
SUSPEND_OR_FUN_MODIFIER.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
}
|
||||
else -> DEFAULT.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
}
|
||||
@@ -498,7 +508,7 @@ object LightTreePositioningStrategies {
|
||||
when (selector.tokenType) {
|
||||
KtNodeTypes.REFERENCE_EXPRESSION ->
|
||||
return markElement(selector, startOffset, endOffset, tree, node)
|
||||
KtNodeTypes.CALL_EXPRESSION, KtNodeTypes.CONSTRUCTOR_DELEGATION_CALL,KtNodeTypes.SUPER_TYPE_CALL_ENTRY ->
|
||||
KtNodeTypes.CALL_EXPRESSION, KtNodeTypes.CONSTRUCTOR_DELEGATION_CALL, KtNodeTypes.SUPER_TYPE_CALL_ENTRY ->
|
||||
return markElement(
|
||||
tree.referenceExpression(selector, locateReferencedName) ?: selector,
|
||||
startOffset,
|
||||
@@ -603,7 +613,7 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val WHOLE_ELEMENT = object : LightTreePositioningStrategy() { }
|
||||
val WHOLE_ELEMENT = object : LightTreePositioningStrategy() {}
|
||||
|
||||
val LONG_LITERAL_SUFFIX = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
|
||||
+3
-3
@@ -18,9 +18,9 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.VAL_OR_VAR_NODE
|
||||
)
|
||||
|
||||
val FUN_INTERFACE_ABSTRACT_PROPERTY = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.FUN_INTERFACE_ABSTRACT_PROPERTY,
|
||||
PositioningStrategies.FUN_INTERFACE_ABSTRACT_PROPERTY
|
||||
val FUN_INTERFACE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.FUN_INTERFACE,
|
||||
PositioningStrategies.FUN_INTERFACE
|
||||
)
|
||||
|
||||
val COMPANION_OBJECT = SourceElementPositioningStrategy(
|
||||
|
||||
@@ -784,12 +784,20 @@ object PositioningStrategies {
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val FUN_INTERFACE_ABSTRACT_PROPERTY: PositioningStrategy<KtDeclaration> = object : PositioningStrategy<KtDeclaration>() {
|
||||
val FUN_INTERFACE: PositioningStrategy<KtDeclaration> = object : PositioningStrategy<KtDeclaration>() {
|
||||
override fun mark(element: KtDeclaration): List<TextRange> {
|
||||
return when (element) {
|
||||
is KtClass -> FUN_MODIFIER.mark(element)
|
||||
is KtProperty -> markElement(element.valOrVarKeyword)
|
||||
else -> error("Expect interface or property, but was " + element.getElementTextWithContext())
|
||||
is KtNamedFunction -> {
|
||||
val typeParameterList = element.typeParameterList
|
||||
when {
|
||||
typeParameterList != null -> markElement(typeParameterList)
|
||||
element.hasModifier(KtTokens.SUSPEND_KEYWORD) -> SUSPEND_MODIFIER.mark(element)
|
||||
else -> markElement(element.funKeyword ?: element)
|
||||
}
|
||||
}
|
||||
else -> markElement(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -55,7 +55,7 @@ fun interface GoodWithPropAndBase : BaseWithSAM {
|
||||
}
|
||||
|
||||
fun interface Foo8 {
|
||||
fun <<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!>T<!>> invoke(x: T)
|
||||
fun <!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!><T><!> invoke(x: T)
|
||||
}
|
||||
|
||||
fun interface GoodGeneric<T> {
|
||||
@@ -63,10 +63,10 @@ fun interface GoodGeneric<T> {
|
||||
}
|
||||
|
||||
interface BaseWithGeneric {
|
||||
fun <<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!>T<!>> invoke(x: T)
|
||||
fun <T> invoke(x: T)
|
||||
}
|
||||
|
||||
fun interface Foo9 : BaseWithGeneric
|
||||
<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS!>fun<!> interface Foo9 : BaseWithGeneric
|
||||
|
||||
fun interface GoodExtensionGeneric : GoodGeneric<String>
|
||||
|
||||
@@ -97,8 +97,8 @@ fun interface WithDefaultValue {
|
||||
}
|
||||
|
||||
interface BaseWithDefaultValue {
|
||||
fun invoke(<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE!>s: String = ""<!>)
|
||||
fun invoke(s: String = "")
|
||||
}
|
||||
|
||||
fun interface DeriveDefault : BaseWithDefaultValue
|
||||
<!FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE!>fun<!> interface DeriveDefault : BaseWithDefaultValue
|
||||
|
||||
|
||||
+3
-3
@@ -1006,15 +1006,15 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = FunInterfaceCannotHaveAbstractProperties::class
|
||||
}
|
||||
|
||||
abstract class FunInterfaceAbstractMethodWithTypeParameters : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class FunInterfaceAbstractMethodWithTypeParameters : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = FunInterfaceAbstractMethodWithTypeParameters::class
|
||||
}
|
||||
|
||||
abstract class FunInterfaceAbstractMethodWithDefaultValue : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class FunInterfaceAbstractMethodWithDefaultValue : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = FunInterfaceAbstractMethodWithDefaultValue::class
|
||||
}
|
||||
|
||||
abstract class FunInterfaceWithSuspendFunction : KtFirDiagnostic<KtFunction>() {
|
||||
abstract class FunInterfaceWithSuspendFunction : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = FunInterfaceWithSuspendFunction::class
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1625,21 +1625,21 @@ internal class FunInterfaceCannotHaveAbstractPropertiesImpl(
|
||||
internal class FunInterfaceAbstractMethodWithTypeParametersImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.FunInterfaceAbstractMethodWithTypeParameters(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.FunInterfaceAbstractMethodWithTypeParameters(), KtAbstractFirDiagnostic<KtDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class FunInterfaceAbstractMethodWithDefaultValueImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.FunInterfaceAbstractMethodWithDefaultValue(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.FunInterfaceAbstractMethodWithDefaultValue(), KtAbstractFirDiagnostic<KtDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class FunInterfaceWithSuspendFunctionImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.FunInterfaceWithSuspendFunction(), KtAbstractFirDiagnostic<KtFunction> {
|
||||
) : KtFirDiagnostic.FunInterfaceWithSuspendFunction(), KtAbstractFirDiagnostic<KtDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user