From 7c61ddc72b754cf5d7615403555cb82b65e8ee47 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 11 Feb 2021 11:57:02 +0300 Subject: [PATCH] [FE] Allow declaring protected constructors in sealed classes #KT-44865 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 12 ++ .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/DeclarationsChecker.kt | 22 +++- .../tests/sealed/NonPrivateConstructor.kt | 4 +- .../protectedConstructors_disabled.fir.kt | 41 ++++++ .../sealed/protectedConstructors_disabled.kt | 41 ++++++ .../sealed/protectedConstructors_disabled.txt | 119 ++++++++++++++++++ .../protectedConstructors_enabled.fir.kt | 41 ++++++ .../sealed/protectedConstructors_enabled.kt | 41 ++++++ .../sealed/protectedConstructors_enabled.txt | 119 ++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++ .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 1 + 13 files changed, 447 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.fir.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.fir.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.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 7bda4473beb..2979176d3f9 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 @@ -24511,6 +24511,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/sealed/OperationWhen.kt"); } + @Test + @TestMetadata("protectedConstructors_disabled.kt") + public void testProtectedConstructors_disabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt"); + } + + @Test + @TestMetadata("protectedConstructors_enabled.kt") + public void testProtectedConstructors_enabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt"); + } + @Test @TestMetadata("RedundantAbstract.kt") public void testRedundantAbstract() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 6c449bc8fc9..57e046bbc90 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -346,6 +346,7 @@ public interface Errors { DiagnosticFactory0 NON_PRIVATE_CONSTRUCTOR_IN_ENUM = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NON_PRIVATE_CONSTRUCTOR_IN_SEALED = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED = DiagnosticFactory0.create(ERROR); // Inline and value classes diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 6647df6c551..94e0885959a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -705,6 +705,7 @@ public class DefaultErrorMessages { MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class"); MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class"); + MAP.put(NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED, "Constructor must be private or protected in sealed class"); MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner"); MAP.put(INLINE_CLASS_NOT_FINAL, "Inline classes can be only final"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index f7220cd0efe..39e42e8a342 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -289,12 +289,22 @@ class DeclarationsChecker( private fun checkConstructorVisibility(constructorDescriptor: ClassConstructorDescriptor, declaration: KtDeclaration) { val visibilityModifier = declaration.visibilityModifier() - if (visibilityModifier != null && visibilityModifier.node?.elementType != KtTokens.PRIVATE_KEYWORD) { - val classDescriptor = constructorDescriptor.containingDeclaration - if (classDescriptor.kind == ClassKind.ENUM_CLASS) { - trace.report(NON_PRIVATE_CONSTRUCTOR_IN_ENUM.on(visibilityModifier)) - } else if (classDescriptor.modality == Modality.SEALED) { - trace.report(NON_PRIVATE_CONSTRUCTOR_IN_SEALED.on(visibilityModifier)) + val visibilityKeyword = visibilityModifier?.node?.elementType ?: return + val classDescriptor = constructorDescriptor.containingDeclaration + + when { + classDescriptor.kind == ClassKind.ENUM_CLASS -> { + if (visibilityKeyword != KtTokens.PRIVATE_KEYWORD) { + trace.report(NON_PRIVATE_CONSTRUCTOR_IN_ENUM.on(visibilityModifier)) + } + } + classDescriptor.modality == Modality.SEALED -> { + val protectedIsAllowed = + languageVersionSettings.supportsFeature(LanguageFeature.AllowSealedInheritorsInDifferentFilesOfSamePackage) + if (!(visibilityKeyword == KtTokens.PRIVATE_KEYWORD || (protectedIsAllowed && visibilityKeyword == KtTokens.PROTECTED_KEYWORD))) { + val factory = if (protectedIsAllowed) NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED else NON_PRIVATE_CONSTRUCTOR_IN_SEALED + trace.report(factory.on(visibilityModifier)) + } } } } diff --git a/compiler/testData/diagnostics/tests/sealed/NonPrivateConstructor.kt b/compiler/testData/diagnostics/tests/sealed/NonPrivateConstructor.kt index 97fb24a6e2c..4cbc7791eb8 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonPrivateConstructor.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonPrivateConstructor.kt @@ -1,7 +1,7 @@ -sealed class Sealed protected constructor(val x: Int) { +sealed class Sealed protected constructor(val x: Int) { object FIRST : Sealed() - public constructor(): this(42) + public constructor(): this(42) constructor(y: Int, z: Int): this(y + z) } diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.fir.kt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.fir.kt new file mode 100644 index 00000000000..1cf4934b52c --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.fir.kt @@ -0,0 +1,41 @@ +// LANGUAGE: -AllowSealedInheritorsInDifferentFilesOfSamePackage +// DIAGNOSTICS: -UNUSED_PARAMETER + +sealed class Case1(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case1(10) + class Inheritor2 : Case1("Hello") +} + +sealed class Case2 protected constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case2(10) + class Inheritor2 : Case2("Hello") +} + +sealed class Case3 private constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case3(10) // should OK + class Inheritor2 : Case3("Hello") +} + +class Case3Inheritor3 : Case3(20) // should be an error in 1.6 (?) + +sealed class Case4 { + protected constructor(x: Int) + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case4(10) + class Inheritor2 : Case4("Hello") +} + +sealed class Case5() { + private constructor(x: Int) : this() + protected constructor(x: Byte) : this() + internal constructor(x: Short) : this() + public constructor(x: Long) : this() + constructor(x: Double) : this() +} diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt new file mode 100644 index 00000000000..441c2ade829 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt @@ -0,0 +1,41 @@ +// LANGUAGE: -AllowSealedInheritorsInDifferentFilesOfSamePackage +// DIAGNOSTICS: -UNUSED_PARAMETER + +sealed class Case1(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case1(10) + class Inheritor2 : Case1("Hello") +} + +sealed class Case2 protected constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case2(10) + class Inheritor2 : Case2("Hello") +} + +sealed class Case3 private constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case3(10) // should OK + class Inheritor2 : Case3("Hello") +} + +class Case3Inheritor3 : Case3(20) // should be an error in 1.6 (?) + +sealed class Case4 { + protected constructor(x: Int) + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case4(10) + class Inheritor2 : Case4("Hello") +} + +sealed class Case5() { + private constructor(x: Int) : this() + protected constructor(x: Byte) : this() + internal constructor(x: Short) : this() + public constructor(x: Long) : this() + constructor(x: Double) : this() +} diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.txt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.txt new file mode 100644 index 00000000000..fbfa35e07cc --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.txt @@ -0,0 +1,119 @@ +package + +public sealed class Case1 { + private constructor Case1(/*0*/ x: kotlin.Int) + protected constructor Case1(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case1 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case1 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case2 { + protected constructor Case2(/*0*/ x: kotlin.Int) + protected constructor Case2(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case2 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case2 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case3 { + private constructor Case3(/*0*/ x: kotlin.Int) + protected constructor Case3(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case3 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case3 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Case3Inheritor3 : Case3 { + public constructor Case3Inheritor3() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case4 { + protected constructor Case4(/*0*/ x: kotlin.Int) + protected constructor Case4(/*0*/ s: kotlin.String) + 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 final class Inheritor1 : Case4 { + public constructor Inheritor1() + 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 final class Inheritor2 : Case4 { + public constructor Inheritor2() + 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 class Case5 { + private constructor Case5() + protected constructor Case5(/*0*/ x: kotlin.Byte) + private constructor Case5(/*0*/ x: kotlin.Double) + private constructor Case5(/*0*/ x: kotlin.Int) + public constructor Case5(/*0*/ x: kotlin.Long) + internal constructor Case5(/*0*/ x: kotlin.Short) + 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 +} + diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.fir.kt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.fir.kt new file mode 100644 index 00000000000..f8993d384b7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.fir.kt @@ -0,0 +1,41 @@ +// LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage +// DIAGNOSTICS: -UNUSED_PARAMETER + +sealed class Case1(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case1(10) + class Inheritor2 : Case1("Hello") +} + +sealed class Case2 protected constructor(val x: Int) { // should be REDUNDANT_MODIFIER + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case2(10) + class Inheritor2 : Case2("Hello") +} + +sealed class Case3 private constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case3(10) // should OK + class Inheritor2 : Case3("Hello") +} + +class Case3Inheritor3 : Case3(20) // should be an error in 1.6 (?) + +sealed class Case4 { + protected constructor(x: Int) + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case4(10) + class Inheritor2 : Case4("Hello") +} + +sealed class Case5() { + private constructor(x: Int) : this() + protected constructor(x: Byte) : this() + internal constructor(x: Short) : this() + public constructor(x: Long) : this() + constructor(x: Double) : this() +} diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt new file mode 100644 index 00000000000..6cec7e5a60f --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt @@ -0,0 +1,41 @@ +// LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage +// DIAGNOSTICS: -UNUSED_PARAMETER + +sealed class Case1(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case1(10) + class Inheritor2 : Case1("Hello") +} + +sealed class Case2 protected constructor(val x: Int) { // should be REDUNDANT_MODIFIER + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case2(10) + class Inheritor2 : Case2("Hello") +} + +sealed class Case3 private constructor(val x: Int) { + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case3(10) // should OK + class Inheritor2 : Case3("Hello") +} + +class Case3Inheritor3 : Case3(20) // should be an error in 1.6 (?) + +sealed class Case4 { + protected constructor(x: Int) + protected constructor(s: String) : this(s.length) + + class Inheritor1 : Case4(10) + class Inheritor2 : Case4("Hello") +} + +sealed class Case5() { + private constructor(x: Int) : this() + protected constructor(x: Byte) : this() + internal constructor(x: Short) : this() + public constructor(x: Long) : this() + constructor(x: Double) : this() +} diff --git a/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.txt b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.txt new file mode 100644 index 00000000000..14f18fc82ca --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.txt @@ -0,0 +1,119 @@ +package + +public sealed class Case1 { + protected constructor Case1(/*0*/ x: kotlin.Int) + protected constructor Case1(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case1 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case1 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case2 { + protected constructor Case2(/*0*/ x: kotlin.Int) + protected constructor Case2(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case2 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case2 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case3 { + private constructor Case3(/*0*/ x: kotlin.Int) + protected constructor Case3(/*0*/ s: kotlin.String) + public final val x: kotlin.Int + 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 final class Inheritor1 : Case3 { + public constructor Inheritor1() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Inheritor2 : Case3 { + public constructor Inheritor2() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 final class Case3Inheritor3 : Case3 { + public constructor Case3Inheritor3() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + 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 class Case4 { + protected constructor Case4(/*0*/ x: kotlin.Int) + protected constructor Case4(/*0*/ s: kotlin.String) + 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 final class Inheritor1 : Case4 { + public constructor Inheritor1() + 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 final class Inheritor2 : Case4 { + public constructor Inheritor2() + 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 class Case5 { + protected constructor Case5() + protected constructor Case5(/*0*/ x: kotlin.Byte) + protected constructor Case5(/*0*/ x: kotlin.Double) + private constructor Case5(/*0*/ x: kotlin.Int) + public constructor Case5(/*0*/ x: kotlin.Long) + internal constructor Case5(/*0*/ x: kotlin.Short) + 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 +} + 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 f0355b8a1ec..b41b5ab81ca 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 @@ -24601,6 +24601,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/sealed/OperationWhen.kt"); } + @Test + @TestMetadata("protectedConstructors_disabled.kt") + public void testProtectedConstructors_disabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/protectedConstructors_disabled.kt"); + } + + @Test + @TestMetadata("protectedConstructors_enabled.kt") + public void testProtectedConstructors_enabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/protectedConstructors_enabled.kt"); + } + @Test @TestMetadata("RedundantAbstract.kt") public void testRedundantAbstract() throws Exception { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index bb41288f250..0c4d532b0a1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -149,6 +149,7 @@ class QuickFixRegistrar : QuickFixContributor { REPEATED_MODIFIER.registerFactory(removeModifierFactory) NON_PRIVATE_CONSTRUCTOR_IN_ENUM.registerFactory(removeModifierFactory) NON_PRIVATE_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory) + NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory) TYPE_CANT_BE_USED_FOR_CONST_VAL.registerFactory(removeModifierFactory) DEPRECATED_BINARY_MOD.registerFactory(removeModifierFactory) DEPRECATED_BINARY_MOD.registerFactory(RenameModToRemFix.Factory) -- GitLab