From 0380b6cd88151158572d1848fd7a0ceb3730b551 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 26 Jul 2016 16:19:26 +0300 Subject: [PATCH] Never resolve modality of members to SEALED --- .../kotlin/resolve/DescriptorResolver.java | 10 ++--- .../resolve/FunctionDescriptorResolver.kt | 7 +-- .../kotlin/resolve/ModifiersChecker.java | 10 +++-- .../lazy/descriptors/LazyClassDescriptor.java | 7 ++- .../declarationChecks/sealedOnMembers.kt | 18 ++++++++ .../declarationChecks/sealedOnMembers.txt | 43 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++ 7 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.kt create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 9e33fc83583..edfb8133919 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -66,7 +66,7 @@ import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.lexer.KtTokens.*; import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; -import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveModalityFromModifiers; +import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveMemberModalityFromModifiers; import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers; public class DescriptorResolver { @@ -781,7 +781,7 @@ public class DescriptorResolver { boolean hasBody = hasBody(property); Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration)); Modality modality = containingDeclaration instanceof ClassDescriptor - ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody)) + ? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody)) : Modality.FINAL; final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(property); @@ -922,7 +922,7 @@ public class DescriptorResolver { setterDescriptor = new PropertySetterDescriptorImpl( propertyDescriptor, annotations, - resolveModalityFromModifiers(setter, propertyDescriptor.getModality()), + resolveMemberModalityFromModifiers(setter, propertyDescriptor.getModality()), resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()), /* isDefault = */ false, setter.hasModifier(EXTERNAL_KEYWORD), property.hasModifier(KtTokens.INLINE_KEYWORD) || setter.hasModifier(KtTokens.INLINE_KEYWORD), @@ -1004,7 +1004,7 @@ public class DescriptorResolver { getterDescriptor = new PropertyGetterDescriptorImpl( propertyDescriptor, getterAnnotations, - resolveModalityFromModifiers(getter, propertyDescriptor.getModality()), + resolveMemberModalityFromModifiers(getter, propertyDescriptor.getModality()), resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()), /* isDefault = */ false, getter.hasModifier(EXTERNAL_KEYWORD), property.hasModifier(KtTokens.INLINE_KEYWORD) || getter.hasModifier(KtTokens.INLINE_KEYWORD), @@ -1113,7 +1113,7 @@ public class DescriptorResolver { PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create( classDescriptor, propertyAnnotations, - resolveModalityFromModifiers(parameter, Modality.FINAL), + resolveMemberModalityFromModifiers(parameter, Modality.FINAL), resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)), isMutable, name, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 744a51d35e3..6baf15b9c8e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -31,9 +31,10 @@ import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.DescriptorResolver.* +import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultModality +import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultVisibility import org.jetbrains.kotlin.resolve.DescriptorUtils.getDispatchReceiverParameterIfNeeded -import org.jetbrains.kotlin.resolve.ModifiersChecker.resolveModalityFromModifiers +import org.jetbrains.kotlin.resolve.ModifiersChecker.resolveMemberModalityFromModifiers import org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo @@ -164,7 +165,7 @@ class FunctionDescriptorResolver( val returnType = function.typeReference?.let { typeResolver.resolveType(innerScope, it, trace, true) } val visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, containingDescriptor)) - val modality = resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, visibility, function.hasBody())) + val modality = resolveMemberModalityFromModifiers(function, getDefaultModality(containingDescriptor, visibility, function.hasBody())) functionDescriptor.initialize( receiverType, getDispatchReceiverParameterIfNeeded(containingDescriptor), diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index f7c09114377..404238a504f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -98,20 +98,22 @@ public class ModifiersChecker { } @NotNull - public static Modality resolveModalityFromModifiers( + public static Modality resolveMemberModalityFromModifiers( @NotNull KtModifierListOwner modifierListOwner, @NotNull Modality defaultModality ) { - return resolveModalityFromModifiers(modifierListOwner.getModifierList(), defaultModality); + return resolveModalityFromModifiers(modifierListOwner.getModifierList(), defaultModality, /* allowSealed = */ false); } @NotNull - public static Modality resolveModalityFromModifiers(@Nullable KtModifierList modifierList, @NotNull Modality defaultModality) { + public static Modality resolveModalityFromModifiers( + @Nullable KtModifierList modifierList, @NotNull Modality defaultModality, boolean allowSealed + ) { if (modifierList == null) return defaultModality; boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD); boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD); - if (modifierList.hasModifier(SEALED_KEYWORD)) { + if (allowSealed && modifierList.hasModifier(SEALED_KEYWORD)) { return Modality.SEALED; } if (modifierList.hasModifier(OPEN_KEYWORD)) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index d144f10d240..6b22e534b82 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -54,7 +54,10 @@ import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.NullableLazyValue; import org.jetbrains.kotlin.storage.StorageManager; -import org.jetbrains.kotlin.types.*; +import org.jetbrains.kotlin.types.AbstractClassTypeConstructor; +import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.TypeConstructor; +import org.jetbrains.kotlin.types.TypeUtils; import java.util.ArrayList; import java.util.Collection; @@ -137,7 +140,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes } else { Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL; - this.modality = resolveModalityFromModifiers(modifierList, defaultModality); + this.modality = resolveModalityFromModifiers(modifierList, defaultModality, /* allowSealed = */ true); } boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject); diff --git a/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.kt b/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.kt new file mode 100644 index 00000000000..0066841bbb6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.kt @@ -0,0 +1,18 @@ +interface A { + sealed fun foo() + sealed var bar: Unit +} + +interface B { + abstract fun foo() + abstract var bar: Unit +} + +interface C : A, B + +abstract class D(sealed var x: Int) { + abstract var y: Unit + sealed set +} + +abstract class E : D(42) diff --git a/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.txt b/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.txt new file mode 100644 index 00000000000..b4971c65288 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.txt @@ -0,0 +1,43 @@ +package + +public interface A { + public abstract var bar: kotlin.Unit + 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 interface B { + public abstract var bar: kotlin.Unit + 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 interface C : A, B { + public abstract override /*2*/ /*fake_override*/ var bar: kotlin.Unit + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class D { + public constructor D(/*0*/ x: kotlin.Int) + public final var x: kotlin.Int + public abstract var y: kotlin.Unit + 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 abstract class E : D { + public constructor E() + public final override /*1*/ /*fake_override*/ var x: kotlin.Int + public abstract override /*1*/ /*fake_override*/ var y: kotlin.Unit + 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 28b45bf4d52..c1b42767a7f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -4956,6 +4956,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("sealedOnMembers.kt") + public void testSealedOnMembers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/sealedOnMembers.kt"); + doTest(fileName); + } + @TestMetadata("unambiguousObjectExpressionType.kt") public void testUnambiguousObjectExpressionType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.kt");