diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index 12843dd8a6e..aef734d5467 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.FunctionTypesKt; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.config.LanguageFeatureSettings; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor; import org.jetbrains.kotlin.diagnostics.Errors; @@ -55,8 +56,6 @@ import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE; public class BodyResolver { - private static final boolean ALLOW_TOP_LEVEL_SEALED_INHERITANCE = true; - @NotNull private final AnnotationChecker annotationChecker; @NotNull private final ExpressionTypingServices expressionTypingServices; @NotNull private final CallResolver callResolver; @@ -70,6 +69,7 @@ public class BodyResolver { @NotNull private final BodyResolveCache bodyResolveCache; @NotNull private final KotlinBuiltIns builtIns; @NotNull private final OverloadChecker overloadChecker; + @NotNull private final LanguageFeatureSettings languageFeatureSettings; public BodyResolver( @NotNull AnnotationResolver annotationResolver, @@ -84,7 +84,8 @@ public class BodyResolver { @NotNull ValueParameterResolver valueParameterResolver, @NotNull AnnotationChecker annotationChecker, @NotNull KotlinBuiltIns builtIns, - @NotNull OverloadChecker overloadChecker + @NotNull OverloadChecker overloadChecker, + @NotNull LanguageFeatureSettings languageFeatureSettings ) { this.annotationResolver = annotationResolver; this.bodyResolveCache = bodyResolveCache; @@ -99,6 +100,7 @@ public class BodyResolver { this.trace = new ObservableBindingTrace(trace); this.valueParameterResolver = valueParameterResolver; this.builtIns = builtIns; + this.languageFeatureSettings = languageFeatureSettings; } private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext c) { @@ -387,7 +389,7 @@ public class BodyResolver { // Returns a set of enum or sealed types of which supertypeOwner is an entry or a member @NotNull - private static Set getAllowedFinalSupertypes( + private Set getAllowedFinalSupertypes( @NotNull ClassDescriptor descriptor, @NotNull Map supertypes, @NotNull KtClassOrObject ktClassOrObject @@ -396,9 +398,10 @@ public class BodyResolver { if (ktClassOrObject instanceof KtEnumEntry) { parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()); } - else if (ALLOW_TOP_LEVEL_SEALED_INHERITANCE && DescriptorUtils.isTopLevelDeclaration(descriptor)) { - for (KotlinType superType : supertypes.values()) { - ClassifierDescriptor classifierDescriptor = superType.getConstructor().getDeclarationDescriptor(); + else if (languageFeatureSettings.getTopLevelSealedInheritance() && DescriptorUtils.isTopLevelDeclaration(descriptor)) { + // TODO: improve diagnostic when top level sealed inheritance is disabled + for (KotlinType supertype : supertypes.values()) { + ClassifierDescriptor classifierDescriptor = supertype.getConstructor().getDeclarationDescriptor(); if (DescriptorUtils.isSealedClass(classifierDescriptor) && DescriptorUtils.isTopLevelDeclaration(classifierDescriptor)) { parentEnumOrSealed = Collections.singleton(classifierDescriptor.getTypeConstructor()); } diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt new file mode 100644 index 00000000000..4cd0e3a8cf6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt @@ -0,0 +1,5 @@ +// !LANGUAGE: -topLevelSealedInheritance + +sealed class Base + +class Derived : Base() diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.txt new file mode 100644 index 00000000000..6e259fee7a3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.txt @@ -0,0 +1,15 @@ +package + +public sealed class Base { + private constructor 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 final class Derived : Base { + public constructor Derived() + 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/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7c7c993b746..3e03c3415dd 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -18181,6 +18181,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/sourceCompatibility") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SourceCompatibility extends AbstractDiagnosticsTest { + public void testAllFilesPresentInSourceCompatibility() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sourceCompatibility"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("noTopLevelSealedInheritance.kt") + public void testNoTopLevelSealedInheritance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/substitutions") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)