Prohibit 'override' on classes and all modality on objects

#KT-3464 Fixed
This commit is contained in:
Alexander Udalov
2014-10-20 15:47:36 +04:00
parent 093dedcd85
commit 4d9ef1042d
4 changed files with 136 additions and 4 deletions
@@ -85,7 +85,7 @@ public class ModifiersChecker {
}
else {
checkInnerModifier(modifierListOwner, descriptor);
checkModalityModifiers(modifierListOwner.getModifierList());
checkModalityModifiers(modifierListOwner);
checkVisibilityModifiers(modifierListOwner, descriptor);
}
checkPlatformNameApplicability(descriptor);
@@ -107,12 +107,21 @@ public class ModifiersChecker {
checkIllegalInThisContextModifiers(modifierListOwner, VISIBILITY_MODIFIERS);
}
private void checkModalityModifiers(@Nullable JetModifierList modifierList) {
private void checkModalityModifiers(@NotNull JetModifierListOwner modifierListOwner) {
JetModifierList modifierList = modifierListOwner.getModifierList();
if (modifierList == null) return;
checkRedundantModifier(modifierList, Pair.create(OPEN_KEYWORD, ABSTRACT_KEYWORD), Pair.create(OPEN_KEYWORD, OVERRIDE_KEYWORD));
checkCompatibility(modifierList, Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD),
Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD));
checkCompatibility(modifierList, Arrays.asList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD),
Arrays.asList(ABSTRACT_KEYWORD, OPEN_KEYWORD));
if (modifierListOwner.getParent() instanceof JetClassObject || modifierListOwner instanceof JetObjectDeclaration) {
checkIllegalModalityModifiers(modifierListOwner);
}
else if (modifierListOwner instanceof JetClassOrObject) {
checkIllegalInThisContextModifiers(modifierListOwner, Collections.singletonList(OVERRIDE_KEYWORD));
}
}
private void checkVisibilityModifiers(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
@@ -0,0 +1,19 @@
// !DIAGNOSTICS: -MANY_CLASS_OBJECTS
// KT-3464 Front-end shouldn't allow override modifier in class declaration
<!ILLEGAL_MODIFIER!>override<!> class A {
<!ILLEGAL_MODIFIER!>override<!> class object {}
<!ILLEGAL_MODIFIER!>open<!> class object {}
<!ILLEGAL_MODIFIER!>abstract<!> class object {}
<!ILLEGAL_MODIFIER!>final<!> class object {}
}
<!ILLEGAL_MODIFIER!>override<!> object B1 {}
<!ILLEGAL_MODIFIER!>open<!> object B2 {}
<!ILLEGAL_MODIFIER!>abstract<!> object B3 {}
<!ILLEGAL_MODIFIER!>final<!> object B4 {}
<!ILLEGAL_MODIFIER!>override<!> enum class C {}
<!ILLEGAL_MODIFIER!>override<!> trait D {}
<!ILLEGAL_MODIFIER!>override<!> annotation class E
@@ -0,0 +1,98 @@
package
internal open class A {
public constructor A()
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 class object <class-object-for-A> {
private constructor <class-object-for-A>()
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 B1 {
private constructor B1()
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 class object <class-object-for-B1> : B1 {
private constructor <class-object-for-B1>()
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 B2 {
private constructor B2()
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 class object <class-object-for-B2> : B2 {
private constructor <class-object-for-B2>()
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 B3 {
private constructor B3()
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 class object <class-object-for-B3> : B3 {
private constructor <class-object-for-B3>()
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 B4 {
private constructor B4()
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 class object <class-object-for-B4> : B4 {
private constructor <class-object-for-B4>()
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 enum class C : kotlin.Enum<C> {
private constructor C()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: C): 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): C
public final /*synthesized*/ fun values(): kotlin.Array<C>
}
internal trait D {
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 annotation class E : kotlin.Annotation {
public constructor E()
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
}
@@ -2678,6 +2678,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("illegalModifiersOnClass.kt")
public void testIllegalModifiersOnClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.kt");
doTest(fileName);
}
@TestMetadata("kt1141.kt")
public void testKt1141() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/kt1141.kt");