From 5ce36a528ec50cb00ff7a6ef77c3b5ba5232a220 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 16 Feb 2021 12:50:51 +0300 Subject: [PATCH] [FE] Prohibit sealed fun interfaces #KT-44947 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++ .../checkers/SealedInterfaceAllowedChecker.kt | 10 ++++-- .../interfaces/sealedFunInterface.fir.kt | 15 ++++++++ .../sealed/interfaces/sealedFunInterface.kt | 15 ++++++++ .../sealed/interfaces/sealedFunInterface.txt | 34 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.txt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 72dfb47b790..76568acc0cd 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -24496,6 +24496,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/sealed/interfaces/inheritorInDifferentModule.kt"); } + @Test + @TestMetadata("sealedFunInterface.kt") + public void testSealedFunInterface() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt"); + } + @Test @TestMetadata("sealedInterfacesDisabled.kt") public void testSealedInterfacesDisabled() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/SealedInterfaceAllowedChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/SealedInterfaceAllowedChecker.kt index e8da70a6617..c2d661947c8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/SealedInterfaceAllowedChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/SealedInterfaceAllowedChecker.kt @@ -14,10 +14,16 @@ import org.jetbrains.kotlin.psi.KtDeclaration object SealedInterfaceAllowedChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { - if (context.languageVersionSettings.supportsFeature(LanguageFeature.SealedInterfaces)) return if (descriptor !is ClassDescriptor) return if (descriptor.kind != ClassKind.INTERFACE) return val keyword = declaration.modifierList?.getModifier(KtTokens.SEALED_KEYWORD) ?: return - context.trace.report(Errors.UNSUPPORTED_FEATURE.on(keyword, LanguageFeature.SealedInterfaces to context.languageVersionSettings)) + val diagnostic = if (context.languageVersionSettings.supportsFeature(LanguageFeature.SealedInterfaces)) { + if (descriptor.isFun) { + Errors.UNSUPPORTED.on(keyword, "sealed fun interfaces") + } else return + } else { + Errors.UNSUPPORTED_FEATURE.on(keyword, LanguageFeature.SealedInterfaces to context.languageVersionSettings) + } + context.trace.report(diagnostic) } } diff --git a/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt new file mode 100644 index 00000000000..d6f8dbd57e9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.fir.kt @@ -0,0 +1,15 @@ +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 new file mode 100644 index 00000000000..ba4ae885b42 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt @@ -0,0 +1,15 @@ +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.txt b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.txt new file mode 100644 index 00000000000..6c7a6f55aba --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.txt @@ -0,0 +1,34 @@ +package + +public sealed fun interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public sealed interface Base { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public sealed fun interface Derived : Base { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public sealed interface IBase { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public fun interface IDerived : IBase { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 4c1b71b8aba..6e7bb6e4ed0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -24586,6 +24586,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/sealed/interfaces/inheritorInDifferentModule.kt"); } + @Test + @TestMetadata("sealedFunInterface.kt") + public void testSealedFunInterface() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt"); + } + @Test @TestMetadata("sealedInterfacesDisabled.kt") public void testSealedInterfacesDisabled() throws Exception {