Use LanguageFeatureSettings instead of JVM option for top level sealed classes

This commit is contained in:
Alexander Udalov
2016-05-23 13:46:42 +03:00
parent 98c3e030a1
commit 331a6ee414
4 changed files with 45 additions and 7 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt; import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.config.LanguageFeatureSettings;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor; import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
import org.jetbrains.kotlin.diagnostics.Errors; 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; import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class BodyResolver { public class BodyResolver {
private static final boolean ALLOW_TOP_LEVEL_SEALED_INHERITANCE = true;
@NotNull private final AnnotationChecker annotationChecker; @NotNull private final AnnotationChecker annotationChecker;
@NotNull private final ExpressionTypingServices expressionTypingServices; @NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final CallResolver callResolver; @NotNull private final CallResolver callResolver;
@@ -70,6 +69,7 @@ public class BodyResolver {
@NotNull private final BodyResolveCache bodyResolveCache; @NotNull private final BodyResolveCache bodyResolveCache;
@NotNull private final KotlinBuiltIns builtIns; @NotNull private final KotlinBuiltIns builtIns;
@NotNull private final OverloadChecker overloadChecker; @NotNull private final OverloadChecker overloadChecker;
@NotNull private final LanguageFeatureSettings languageFeatureSettings;
public BodyResolver( public BodyResolver(
@NotNull AnnotationResolver annotationResolver, @NotNull AnnotationResolver annotationResolver,
@@ -84,7 +84,8 @@ public class BodyResolver {
@NotNull ValueParameterResolver valueParameterResolver, @NotNull ValueParameterResolver valueParameterResolver,
@NotNull AnnotationChecker annotationChecker, @NotNull AnnotationChecker annotationChecker,
@NotNull KotlinBuiltIns builtIns, @NotNull KotlinBuiltIns builtIns,
@NotNull OverloadChecker overloadChecker @NotNull OverloadChecker overloadChecker,
@NotNull LanguageFeatureSettings languageFeatureSettings
) { ) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
this.bodyResolveCache = bodyResolveCache; this.bodyResolveCache = bodyResolveCache;
@@ -99,6 +100,7 @@ public class BodyResolver {
this.trace = new ObservableBindingTrace(trace); this.trace = new ObservableBindingTrace(trace);
this.valueParameterResolver = valueParameterResolver; this.valueParameterResolver = valueParameterResolver;
this.builtIns = builtIns; this.builtIns = builtIns;
this.languageFeatureSettings = languageFeatureSettings;
} }
private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext c) { 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 // Returns a set of enum or sealed types of which supertypeOwner is an entry or a member
@NotNull @NotNull
private static Set<TypeConstructor> getAllowedFinalSupertypes( private Set<TypeConstructor> getAllowedFinalSupertypes(
@NotNull ClassDescriptor descriptor, @NotNull ClassDescriptor descriptor,
@NotNull Map<KtTypeReference, KotlinType> supertypes, @NotNull Map<KtTypeReference, KotlinType> supertypes,
@NotNull KtClassOrObject ktClassOrObject @NotNull KtClassOrObject ktClassOrObject
@@ -396,9 +398,10 @@ public class BodyResolver {
if (ktClassOrObject instanceof KtEnumEntry) { if (ktClassOrObject instanceof KtEnumEntry) {
parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()); parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor());
} }
else if (ALLOW_TOP_LEVEL_SEALED_INHERITANCE && DescriptorUtils.isTopLevelDeclaration(descriptor)) { else if (languageFeatureSettings.getTopLevelSealedInheritance() && DescriptorUtils.isTopLevelDeclaration(descriptor)) {
for (KotlinType superType : supertypes.values()) { // TODO: improve diagnostic when top level sealed inheritance is disabled
ClassifierDescriptor classifierDescriptor = superType.getConstructor().getDeclarationDescriptor(); for (KotlinType supertype : supertypes.values()) {
ClassifierDescriptor classifierDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (DescriptorUtils.isSealedClass(classifierDescriptor) && DescriptorUtils.isTopLevelDeclaration(classifierDescriptor)) { if (DescriptorUtils.isSealedClass(classifierDescriptor) && DescriptorUtils.isTopLevelDeclaration(classifierDescriptor)) {
parentEnumOrSealed = Collections.singleton(classifierDescriptor.getTypeConstructor()); parentEnumOrSealed = Collections.singleton(classifierDescriptor.getTypeConstructor());
} }
@@ -0,0 +1,5 @@
// !LANGUAGE: -topLevelSealedInheritance
sealed class Base
class Derived : <!SEALED_SUPERTYPE!>Base<!>()
@@ -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
}
@@ -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") @TestMetadata("compiler/testData/diagnostics/tests/substitutions")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)