diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java index d33171a4e40..958cb9487ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java @@ -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) { diff --git a/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.kt b/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.kt new file mode 100644 index 00000000000..742f3a7e1ec --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.kt @@ -0,0 +1,19 @@ +// !DIAGNOSTICS: -MANY_CLASS_OBJECTS + +// KT-3464 Front-end shouldn't allow override modifier in class declaration + +override class A { + override class object {} + open class object {} + abstract class object {} + final class object {} +} + +override object B1 {} +open object B2 {} +abstract object B3 {} +final object B4 {} + +override enum class C {} +override trait D {} +override annotation class E diff --git a/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.txt b/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.txt new file mode 100644 index 00000000000..94687fa79d6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/illegalModifiersOnClass.txt @@ -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 { + private constructor () + 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 : B1 { + private constructor () + 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 : B2 { + private constructor () + 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 : B3 { + private constructor () + 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 : B4 { + private constructor () + 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 { + 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 +} + +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 +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 70874cd5e91..ede881624cd 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -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");