[FIR] Report UNSUPPORTED_SEALED_FUN_INTERFACE

^KT-59957 Fixed
This commit is contained in:
Nikolay Lunyak
2023-08-07 12:25:36 +03:00
committed by Space Team
parent 8be98da1d3
commit b7d1298f20
10 changed files with 47 additions and 15 deletions
@@ -650,6 +650,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.UNSUPPORTED_SEALED_FUN_INTERFACE) { firDiagnostic ->
UnsupportedSealedFunInterfaceImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE) { firDiagnostic ->
SupertypeNotAClassOrInterfaceImpl(
firDiagnostic.a,
@@ -497,6 +497,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ClassInheritsJavaSealedClass::class
}
interface UnsupportedSealedFunInterface : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = UnsupportedSealedFunInterface::class
}
interface SupertypeNotAClassOrInterface : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = SupertypeNotAClassOrInterface::class
val reason: String
@@ -584,6 +584,11 @@ internal class ClassInheritsJavaSealedClassImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtTypeReference>(firDiagnostic, token), KtFirDiagnostic.ClassInheritsJavaSealedClass
internal class UnsupportedSealedFunInterfaceImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UnsupportedSealedFunInterface
internal class SupertypeNotAClassOrInterfaceImpl(
override val reason: String,
firDiagnostic: KtPsiDiagnostic,
@@ -245,6 +245,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val SEALED_INHERITOR_IN_DIFFERENT_PACKAGE by error<KtTypeReference>()
val SEALED_INHERITOR_IN_DIFFERENT_MODULE by error<KtTypeReference>()
val CLASS_INHERITS_JAVA_SEALED_CLASS by error<KtTypeReference>()
val UNSUPPORTED_SEALED_FUN_INTERFACE by error<PsiElement>()
val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error<KtElement> {
parameter<String>("reason")
}
@@ -213,6 +213,7 @@ object FirErrors {
val SEALED_INHERITOR_IN_DIFFERENT_PACKAGE by error0<KtTypeReference>()
val SEALED_INHERITOR_IN_DIFFERENT_MODULE by error0<KtTypeReference>()
val CLASS_INHERITS_JAVA_SEALED_CLASS by error0<KtTypeReference>()
val UNSUPPORTED_SEALED_FUN_INTERFACE by error0<PsiElement>()
val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error1<KtElement, String>()
val UNSUPPORTED_INHERITANCE_FROM_JAVA_MEMBER_REFERENCING_KOTLIN_FUNCTION by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val CYCLIC_INHERITANCE_HIERARCHY by error0<PsiElement>()
@@ -106,6 +106,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirDynamicSupertypeChecker,
FirEnumCompanionInEnumConstructorCallChecker,
FirBadInheritedJavaSignaturesChecker,
FirSealedInterfaceAllowedChecker,
)
override val regularClassCheckers: Set<FirRegularClassChecker>
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2023 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 org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.utils.isFun
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.lexer.KtTokens
object FirSealedInterfaceAllowedChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isInterface || !declaration.isFun) {
return
}
val keyword = declaration.getModifier(KtTokens.SEALED_KEYWORD) ?: return
reporter.reportOn(keyword.source, FirErrors.UNSUPPORTED_SEALED_FUN_INTERFACE, context)
}
}
@@ -121,6 +121,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAST_NEVER_SUCCEE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_INHERITS_JAVA_SEALED_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSUPPORTED_SEALED_FUN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT
@@ -819,6 +820,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
)
map.put(SEALED_INHERITOR_IN_DIFFERENT_MODULE, "Inheritance of sealed classes or interfaces from different module is prohibited")
map.put(CLASS_INHERITS_JAVA_SEALED_CLASS, "Inheritance of Java sealed classes is prohibited")
map.put(UNSUPPORTED_SEALED_FUN_INTERFACE, "'sealed fun interface' is unsupported")
map.put(SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, "Supertype is not a class or interface", TO_STRING)
map.put(
@@ -1,15 +0,0 @@
sealed fun interface A { // error
fun foo()
}
sealed interface Base {
sealed fun interface Derived : Base { // error
fun foo()
}
}
sealed interface IBase {
fun interface IDerived : IBase { // OK
fun foo()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
<!UNSUPPORTED_SEALED_FUN_INTERFACE!>sealed<!> fun interface A { // error
fun foo()
}