Introduction of sealed classes

Sealed classes can be derived only by their own inner classes or objects.
Their constructors cannot be called explicitly, so compiler knows all their descendants.
Incompatible modifier checks (final, abstract). Impossible with interface, object, enum.
A pack of tests provided.
This commit is contained in:
Mikhail Glukhikh
2015-05-12 18:07:17 +03:00
parent 2dea17a3a9
commit 8d25c20169
42 changed files with 432 additions and 12 deletions
@@ -185,6 +185,7 @@ public interface Errors {
DiagnosticFactory0<JetModifierListOwner> OPEN_MODIFIER_IN_TRAIT = DiagnosticFactory0
.create(WARNING, modifierSetPosition(JetTokens.OPEN_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> TRAIT_CAN_NOT_BE_FINAL = DiagnosticFactory0.create(ERROR, FINAL_MODIFIER);
DiagnosticFactory0<JetModifierListOwner> TRAIT_CAN_NOT_BE_SEALED = DiagnosticFactory0.create(ERROR, SEALED_MODIFIER);
DiagnosticFactory0<JetDeclaration> CONSTRUCTOR_IN_TRAIT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
@@ -203,6 +204,8 @@ public interface Errors {
.create(ERROR, modifierSetPosition(JetTokens.OPEN_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> ABSTRACT_MODIFIER_IN_ENUM = DiagnosticFactory0
.create(ERROR, modifierSetPosition(JetTokens.ABSTRACT_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> SEALED_MODIFIER_IN_ENUM = DiagnosticFactory0
.create(ERROR, modifierSetPosition(JetTokens.SEALED_KEYWORD));
DiagnosticFactory0<PsiElement> CLASS_IN_SUPERTYPE_FOR_ENUM = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetTypeParameterList> TYPE_PARAMETERS_IN_ENUM = DiagnosticFactory0.create(ERROR);
@@ -214,6 +217,17 @@ public interface Errors {
DiagnosticFactory1<JetEnumEntry, ClassDescriptor> ENUM_ENTRY_AFTER_ENUM_MEMBER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory0<JetCallExpression> ENUM_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR);
// Sealed-specific
DiagnosticFactory0<JetModifierListOwner> OPEN_MODIFIER_IN_SEALED = DiagnosticFactory0
.create(ERROR, modifierSetPosition(JetTokens.OPEN_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> FINAL_MODIFIER_IN_SEALED = DiagnosticFactory0
.create(ERROR, modifierSetPosition(JetTokens.FINAL_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> ABSTRACT_MODIFIER_IN_SEALED = DiagnosticFactory0
.create(WARNING, modifierSetPosition(JetTokens.ABSTRACT_KEYWORD));
DiagnosticFactory0<JetCallExpression> SEALED_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetTypeReference> SEALED_SUPERTYPE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetTypeReference> SEALED_SUPERTYPE_IN_LOCAL_CLASS = DiagnosticFactory0.create(ERROR);
// Companion objects
DiagnosticFactory0<JetObjectDeclaration> MANY_COMPANION_OBJECTS = DiagnosticFactory0.create(ERROR, COMPANION_OBJECT);
@@ -208,6 +208,8 @@ public object PositioningStrategies {
public val FINAL_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.FINAL_KEYWORD)
public val SEALED_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.SEALED_KEYWORD)
public val VARIANCE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD)
public val FOR_REDECLARATION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
@@ -141,11 +141,16 @@ public class DefaultErrorMessages {
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in interface");
MAP.put(OPEN_MODIFIER_IN_TRAIT, "Modifier ''open'' is redundant in interface");
MAP.put(OPEN_MODIFIER_IN_SEALED, "Modifier ''open'' is not applicable for sealed class");
MAP.put(OPEN_MODIFIER_IN_ENUM, "Modifier ''open'' is not applicable for enum class");
MAP.put(ABSTRACT_MODIFIER_IN_ENUM, "Modifier ''abstract'' is not applicable for enum class");
MAP.put(ABSTRACT_MODIFIER_IN_SEALED, "Modifier ''abstract'' is redundant for sealed class");
MAP.put(SEALED_MODIFIER_IN_ENUM, "Modifier ''sealed'' is not applicable for enum class");
MAP.put(FINAL_MODIFIER_IN_SEALED, "Modifier ''final'' is not applicable for sealed class");
MAP.put(ILLEGAL_ENUM_ANNOTATION, "Annotation ''enum'' is only applicable for class");
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
MAP.put(TRAIT_CAN_NOT_BE_FINAL, "Interface cannot be final");
MAP.put(TRAIT_CAN_NOT_BE_SEALED, "Interface cannot be sealed");
MAP.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters");
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly"); // TODO: message
@@ -292,6 +297,7 @@ public class DefaultErrorMessages {
MAP.put(ENUM_ENTRY_USES_DEPRECATED_SUPER_CONSTRUCTOR, "Enum entry ''{0}'' uses deprecated super constructor syntax, use ENTRY(arguments) instead", NAME);
MAP.put(ENUM_ENTRY_AFTER_ENUM_MEMBER, "Enum entry ''{0}'' is not allowed after a member", NAME);
MAP.put(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated");
MAP.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed types cannot be instantiated");
MAP.put(DELEGATION_IN_TRAIT, "Interfaces cannot use delegation");
MAP.put(DELEGATION_NOT_TO_TRAIT, "Only interfaces can be delegated to");
@@ -430,6 +436,8 @@ public class DefaultErrorMessages {
MAP.put(TRAIT_WITH_SUPERCLASS, "An interface cannot inherit from a class");
MAP.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice");
MAP.put(FINAL_SUPERTYPE, "This type is final, so it cannot be inherited from");
MAP.put(SEALED_SUPERTYPE, "This type is sealed, so it can be inherited by only its own nested classes or objects");
MAP.put(SEALED_SUPERTYPE_IN_LOCAL_CLASS, "Local class cannot extend a sealed class");
MAP.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton");
MAP.put(CYCLIC_CONSTRUCTOR_DELEGATION_CALL, "There's a cycle in the delegation calls chain");
@@ -157,6 +157,7 @@ public interface JetTokens {
JetModifierKeywordToken REIFIED_KEYWORD = JetModifierKeywordToken.softKeywordModifier("reified");
JetModifierKeywordToken DYNAMIC_KEYWORD = JetModifierKeywordToken.softKeywordModifier("dynamic");
JetModifierKeywordToken COMPANION_KEYWORD = JetModifierKeywordToken.softKeywordModifier("companion");
JetModifierKeywordToken SEALED_KEYWORD = JetModifierKeywordToken.softKeywordModifier("sealed");
JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally");
JetModifierKeywordToken FINAL_KEYWORD = JetModifierKeywordToken.softKeywordModifier("final");
@@ -174,7 +175,7 @@ public interface JetTokens {
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD,
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD,
DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD
DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD, SEALED_KEYWORD
);
/*
@@ -186,7 +187,7 @@ public interface JetTokens {
new JetModifierKeywordToken[] {
ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD,
PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD,
REIFIED_KEYWORD, COMPANION_KEYWORD
REIFIED_KEYWORD, COMPANION_KEYWORD, SEALED_KEYWORD
};
TokenSet MODIFIER_KEYWORDS = TokenSet.create(MODIFIER_KEYWORDS_ARRAY);
@@ -394,15 +394,28 @@ public class BodyResolver {
trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getDelegationSpecifierList()));
}
Set<TypeConstructor> parentEnum =
jetClass instanceof JetEnumEntry
? Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor())
: Collections.<TypeConstructor>emptySet();
Set<TypeConstructor> parentEnumOrSealed;
if (jetClass instanceof JetEnumEntry) {
parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor());
}
else {
parentEnumOrSealed = Collections.emptySet();
ClassDescriptor currentDescriptor = descriptor;
while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration();
if (currentDescriptor.getModality() == Modality.SEALED) {
if (parentEnumOrSealed.isEmpty()) {
parentEnumOrSealed = new HashSet<TypeConstructor>();
}
parentEnumOrSealed.add(currentDescriptor.getTypeConstructor());
}
}
}
if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
}
checkSupertypeList(descriptor, supertypes, parentEnum);
checkSupertypeList(descriptor, supertypes, parentEnumOrSealed);
}
private static void recordConstructorDelegationCall(
@@ -464,7 +477,21 @@ public class BodyResolver {
trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
}
else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
trace.report(FINAL_SUPERTYPE.on(typeReference));
if (classDescriptor.getModality() == Modality.SEALED) {
DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
while (containingDescriptor != null && containingDescriptor != classDescriptor) {
containingDescriptor = containingDescriptor.getContainingDeclaration();
}
if (containingDescriptor == null) {
trace.report(SEALED_SUPERTYPE.on(typeReference));
}
else {
trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
}
}
else {
trace.report(FINAL_SUPERTYPE.on(typeReference));
}
}
}
}
@@ -265,6 +265,9 @@ public class DeclarationsChecker {
trace.report(LOCAL_ENUM_NOT_ALLOWED.on(aClass, classDescriptor));
}
}
else if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) {
checkSealedModifiers(aClass);
}
else if (aClass instanceof JetEnumEntry) {
checkEnumEntry((JetEnumEntry) aClass, classDescriptor);
}
@@ -319,6 +322,9 @@ public class DeclarationsChecker {
if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) {
trace.report(Errors.TRAIT_CAN_NOT_BE_FINAL.on(aClass));
}
if (modifierList.hasModifier(JetTokens.SEALED_KEYWORD)) {
trace.report(Errors.TRAIT_CAN_NOT_BE_SEALED.on(aClass));
}
if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
trace.report(Errors.ABSTRACT_MODIFIER_IN_TRAIT.on(aClass));
}
@@ -550,6 +556,21 @@ public class DeclarationsChecker {
if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
trace.report(ABSTRACT_MODIFIER_IN_ENUM.on(aClass));
}
if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) {
trace.report(SEALED_MODIFIER_IN_ENUM.on(aClass));
}
}
private void checkSealedModifiers(JetClass aClass) {
if (aClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
trace.report(OPEN_MODIFIER_IN_SEALED.on(aClass));
}
if (aClass.hasModifier(JetTokens.FINAL_KEYWORD)) {
trace.report(FINAL_MODIFIER_IN_SEALED.on(aClass));
}
if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
trace.report(ABSTRACT_MODIFIER_IN_SEALED.on(aClass));
}
}
// Temporary
@@ -45,7 +45,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
public class ModifiersChecker {
private static final Collection<JetModifierKeywordToken> MODALITY_MODIFIERS =
Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD);
Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD, SEALED_KEYWORD);
private static final Collection<JetModifierKeywordToken> VISIBILITY_MODIFIERS =
Lists.newArrayList(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD);
@@ -370,6 +370,9 @@ public class ModifiersChecker {
boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD);
boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD);
if (modifierList.hasModifier(SEALED_KEYWORD)) {
return Modality.SEALED;
}
if (modifierList.hasModifier(OPEN_KEYWORD)) {
if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) {
return Modality.ABSTRACT;
@@ -211,13 +211,18 @@ public class CallExpressionResolver {
return TypeInfoFactoryPackage.noTypeInfo(context);
}
if (functionDescriptor instanceof ConstructorDescriptor) {
if (DescriptorUtils.isAnnotationClass(functionDescriptor.getContainingDeclaration())
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
if (DescriptorUtils.isAnnotationClass(containingDescriptor)
&& !canInstantiateAnnotationClass(callExpression)) {
context.trace.report(ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(callExpression));
}
if (DescriptorUtils.isEnumClass(functionDescriptor.getContainingDeclaration())) {
if (DescriptorUtils.isEnumClass(containingDescriptor)) {
context.trace.report(ENUM_CLASS_CONSTRUCTOR_CALL.on(callExpression));
}
if (containingDescriptor instanceof ClassDescriptor
&& ((ClassDescriptor) containingDescriptor).getModality() == Modality.SEALED) {
context.trace.report(SEALED_CLASS_CONSTRUCTOR_CALL.on(callExpression));
}
}
JetType type = functionDescriptor.getReturnType();
@@ -0,0 +1,9 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
// It's ALLOWED to inherit Sealed also here
object Fourth: Sealed(78)
}
}
@@ -0,0 +1,52 @@
package
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal 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
internal object First : Sealed {
private constructor First()
internal 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
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: 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
internal object Fourth : Sealed {
private constructor Fourth()
internal 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
}
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: 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
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: 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
}
}
}
+13
View File
@@ -0,0 +1,13 @@
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
object Second: NonFirst()
object Third: NonFirst()
fun foo(): Int {
val s = object: <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Sealed<!>() {}
class Local: <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Sealed<!>() {}
return s.hashCode()
}
}
val p: Sealed = object: <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Sealed<!>() {}
}
+44
View File
@@ -0,0 +1,44 @@
package
internal sealed class Sealed {
public constructor Sealed()
internal final val p: Sealed
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
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val p: Sealed
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
}
internal open class NonFirst : Sealed {
public constructor NonFirst()
internal final override /*1*/ /*fake_override*/ val p: Sealed
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val p: Sealed
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val p: Sealed
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,3 @@
sealed class Base {
fun foo() = <!SEALED_CLASS_CONSTRUCTOR_CALL!>Base()<!>
}
@@ -0,0 +1,9 @@
package
internal sealed class Base {
public constructor Base()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(): Base
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,7 @@
sealed class Base {
}
class Derived: <!SEALED_SUPERTYPE!>Base<!>() {
}
@@ -0,0 +1,15 @@
package
internal sealed class Base {
public 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
}
internal 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
}
@@ -0,0 +1,6 @@
<!SEALED_MODIFIER_IN_ENUM!>sealed<!> enum class SealedEnum {
FIRST,
SECOND;
class Derived: SealedEnum()
}
@@ -0,0 +1,45 @@
package
internal sealed enum class SealedEnum : kotlin.Enum<SealedEnum> {
public enum entry FIRST : SealedEnum {
private constructor FIRST()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public enum entry SECOND : SealedEnum {
private constructor SECOND()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
private constructor SealedEnum()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class Derived : SealedEnum {
public constructor Derived()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SealedEnum
public final /*synthesized*/ fun values(): kotlin.Array<SealedEnum>
}
@@ -0,0 +1,3 @@
<!FINAL_MODIFIER_IN_SEALED!>final<!> sealed class Base {
}
@@ -0,0 +1,8 @@
package
internal sealed class Base {
public 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
}
@@ -0,0 +1,3 @@
<!TRAIT_CAN_NOT_BE_SEALED!>sealed<!> interface Base {
}
@@ -0,0 +1,7 @@
package
internal 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
}
@@ -0,0 +1,3 @@
<!ILLEGAL_MODIFIER!>sealed<!> object Sealed {
}
@@ -0,0 +1,8 @@
package
internal object Sealed {
private constructor Sealed()
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
}
@@ -0,0 +1,3 @@
<!OPEN_MODIFIER_IN_SEALED!>open<!> sealed class Base {
}
@@ -0,0 +1,8 @@
package
internal sealed class Base {
public 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
}
@@ -0,0 +1,3 @@
<!ABSTRACT_MODIFIER_IN_SEALED!>abstract<!> sealed class Base {
}
@@ -0,0 +1,8 @@
package
internal sealed class Base {
public 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
}
@@ -11425,6 +11425,75 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
}
}
@TestMetadata("compiler/testData/diagnostics/tests/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Sealed extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInSealed() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sealed"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("DoubleInner.kt")
public void testDoubleInner() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/DoubleInner.kt");
doTest(fileName);
}
@TestMetadata("Local.kt")
public void testLocal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/Local.kt");
doTest(fileName);
}
@TestMetadata("NeverConstructed.kt")
public void testNeverConstructed() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt");
doTest(fileName);
}
@TestMetadata("NeverDerived.kt")
public void testNeverDerived() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverDerived.kt");
doTest(fileName);
}
@TestMetadata("NeverEnum.kt")
public void testNeverEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverEnum.kt");
doTest(fileName);
}
@TestMetadata("NeverFinal.kt")
public void testNeverFinal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverFinal.kt");
doTest(fileName);
}
@TestMetadata("NeverInterface.kt")
public void testNeverInterface() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverInterface.kt");
doTest(fileName);
}
@TestMetadata("NeverObject.kt")
public void testNeverObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverObject.kt");
doTest(fileName);
}
@TestMetadata("NeverOpen.kt")
public void testNeverOpen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverOpen.kt");
doTest(fileName);
}
@TestMetadata("RedundantAbstract.kt")
public void testRedundantAbstract() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -21,12 +21,13 @@ import org.jetbrains.annotations.NotNull;
public enum Modality {
// THE ORDER OF ENTRIES MATTERS HERE
FINAL(false),
SEALED(false),
OPEN(true),
ABSTRACT(true);
private final boolean overridable;
private Modality(boolean overridable) {
Modality(boolean overridable) {
this.overridable = overridable;
}
@@ -35,4 +35,5 @@ class MouseMovedEventArgs
// EXIST: init
/*why?*/
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
@@ -38,5 +38,6 @@ class B {
// EXIST: vararg
/*why?*/
// EXIST: companion object
// EXIST: sealed
/*TODO*/
// NOTHING_ELSE
+1
View File
@@ -38,4 +38,5 @@ class A {
// EXIST: init
/*why?*/
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
+1
View File
@@ -20,6 +20,7 @@
// EXIST: {"lookupString":"protected","itemText":"protected","attributes":"bold"}
// EXIST: {"lookupString":"public","itemText":"public","attributes":"bold"}
// EXIST: {"lookupString":"reified","itemText":"reified","attributes":"bold"}
// EXIST: {"lookupString":"sealed","itemText":"sealed","attributes":"bold"}
// EXIST: {"lookupString":"val","itemText":"val","attributes":"bold"}
// EXIST: {"lookupString":"var","itemText":"var","attributes":"bold"}
// EXIST: {"lookupString":"vararg","itemText":"vararg","attributes":"bold"}
@@ -38,5 +38,6 @@ var a : Int
// EXIST: vararg
/*why?*/
// EXIST: companion object
// EXIST: sealed
/*TODO*/
// NOTHING_ELSE
@@ -36,4 +36,5 @@ public class Test {
// EXIST: init
/*why?*/
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
@@ -30,4 +30,5 @@ class TestClass {
// EXIST: constructor
// EXIST: init
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
@@ -29,5 +29,6 @@ package Test
// EXIST: vararg
/*why?*/
// EXIST: companion object
// EXIST: sealed
/*TODO*/
// NOTHING_ELSE
@@ -34,4 +34,5 @@ class Some {
// EXIST: constructor
// EXIST: init
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
@@ -34,4 +34,5 @@ class Some {
// EXIST: constructor
// EXIST: init
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
@@ -36,4 +36,5 @@ class Some {
// EXIST: constructor
// EXIST: init
// EXIST: companion object
// EXIST: sealed
// NOTHING_ELSE
+1
View File
@@ -28,5 +28,6 @@
// EXIST: vararg
/*why?*/
// EXIST: companion object
// EXIST: sealed
/*TODO*/
// NOTHING_ELSE