From b7d1298f209de833a0b267308decd38b032ddae5 Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Mon, 7 Aug 2023 12:25:36 +0300 Subject: [PATCH] [FIR] Report UNSUPPORTED_SEALED_FUN_INTERFACE ^KT-59957 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 6 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 5 ++++ .../diagnostics/FirDiagnosticsList.kt | 1 + .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../checkers/CommonDeclarationCheckers.kt | 1 + .../FirSealedInterfaceAllowedChecker.kt | 26 +++++++++++++++++++ .../diagnostics/FirErrorsDefaultMessages.kt | 2 ++ .../interfaces/sealedFunInterface.fir.kt | 15 ----------- .../sealed/interfaces/sealedFunInterface.kt | 1 + 10 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedInterfaceAllowedChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 3cc549c4b11..bbc51463141 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 6fc3f28e39c..423a7307a84 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -497,6 +497,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = ClassInheritsJavaSealedClass::class } + interface UnsupportedSealedFunInterface : KtFirDiagnostic { + override val diagnosticClass get() = UnsupportedSealedFunInterface::class + } + interface SupertypeNotAClassOrInterface : KtFirDiagnostic { override val diagnosticClass get() = SupertypeNotAClassOrInterface::class val reason: String diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index a60fa7a3a43..dd9e3218082 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -584,6 +584,11 @@ internal class ClassInheritsJavaSealedClassImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.ClassInheritsJavaSealedClass +internal class UnsupportedSealedFunInterfaceImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnsupportedSealedFunInterface + internal class SupertypeNotAClassOrInterfaceImpl( override val reason: String, firDiagnostic: KtPsiDiagnostic, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 9c8f2615006..1b4fe5a3cbe 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -245,6 +245,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val SEALED_INHERITOR_IN_DIFFERENT_PACKAGE by error() val SEALED_INHERITOR_IN_DIFFERENT_MODULE by error() val CLASS_INHERITS_JAVA_SEALED_CLASS by error() + val UNSUPPORTED_SEALED_FUN_INTERFACE by error() val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error { parameter("reason") } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 0513ffbb14c..fc2236ab663 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -213,6 +213,7 @@ object FirErrors { val SEALED_INHERITOR_IN_DIFFERENT_PACKAGE by error0() val SEALED_INHERITOR_IN_DIFFERENT_MODULE by error0() val CLASS_INHERITS_JAVA_SEALED_CLASS by error0() + val UNSUPPORTED_SEALED_FUN_INTERFACE by error0() val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error1() val UNSUPPORTED_INHERITANCE_FROM_JAVA_MEMBER_REFERENCING_KOTLIN_FUNCTION by error1>(SourceElementPositioningStrategies.DECLARATION_NAME) val CYCLIC_INHERITANCE_HIERARCHY by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 6db588e1fb9..e99f66b04cc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -106,6 +106,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirDynamicSupertypeChecker, FirEnumCompanionInEnumConstructorCallChecker, FirBadInheritedJavaSignaturesChecker, + FirSealedInterfaceAllowedChecker, ) override val regularClassCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedInterfaceAllowedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedInterfaceAllowedChecker.kt new file mode 100644 index 00000000000..4d7a15f1229 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedInterfaceAllowedChecker.kt @@ -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) + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index 0409bbcc1d7..e20f234c51f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -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( diff --git a/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt deleted file mode 100644 index d6f8dbd57e9..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt +++ /dev/null @@ -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() - } -} diff --git a/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt index 4252c1afa5d..501419dfc65 100644 --- a/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt +++ b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed fun interface A { // error fun foo() }