KT-322 Prohibit inheriting classes from enums
#KT-322 Fixed
This commit is contained in:
@@ -68,6 +68,8 @@ public interface Errors {
|
|||||||
.create(WARNING, ABSTRACT_MODIFIER);
|
.create(WARNING, ABSTRACT_MODIFIER);
|
||||||
SimpleDiagnosticFactory<JetModifierListOwner> OPEN_MODIFIER_IN_TRAIT = SimpleDiagnosticFactory
|
SimpleDiagnosticFactory<JetModifierListOwner> OPEN_MODIFIER_IN_TRAIT = SimpleDiagnosticFactory
|
||||||
.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD));
|
.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD));
|
||||||
|
SimpleDiagnosticFactory<JetModifierListOwner> OPEN_MODIFIER_IN_ENUM = SimpleDiagnosticFactory
|
||||||
|
.create(ERROR, positionModifier(JetTokens.OPEN_KEYWORD));
|
||||||
SimpleDiagnosticFactory<PsiElement>
|
SimpleDiagnosticFactory<PsiElement>
|
||||||
REDUNDANT_MODIFIER_IN_GETTER = SimpleDiagnosticFactory.create(WARNING);
|
REDUNDANT_MODIFIER_IN_GETTER = SimpleDiagnosticFactory.create(WARNING);
|
||||||
SimpleDiagnosticFactory<PsiElement> TRAIT_CAN_NOT_BE_FINAL = SimpleDiagnosticFactory.create(ERROR);
|
SimpleDiagnosticFactory<PsiElement> TRAIT_CAN_NOT_BE_FINAL = SimpleDiagnosticFactory.create(ERROR);
|
||||||
|
|||||||
+1
@@ -81,6 +81,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
|
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 trait");
|
MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in trait");
|
||||||
MAP.put(OPEN_MODIFIER_IN_TRAIT, "Modifier ''open'' is redundant in trait");
|
MAP.put(OPEN_MODIFIER_IN_TRAIT, "Modifier ''open'' is redundant in trait");
|
||||||
|
MAP.put(OPEN_MODIFIER_IN_ENUM, "Modifier ''open'' is not applicable for enum class");
|
||||||
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
||||||
MAP.put(TRAIT_CAN_NOT_BE_FINAL, "Trait cannot be final");
|
MAP.put(TRAIT_CAN_NOT_BE_FINAL, "Trait cannot be final");
|
||||||
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
|
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -94,12 +93,18 @@ public class DeclarationsChecker {
|
|||||||
|
|
||||||
private void checkClass(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
private void checkClass(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
||||||
checkOpenMembers(classDescriptor);
|
checkOpenMembers(classDescriptor);
|
||||||
checkTraitModifiers(aClass);
|
if (aClass.isTrait()) {
|
||||||
checkEnum(aClass, classDescriptor);
|
checkTraitModifiers(aClass);
|
||||||
|
}
|
||||||
|
else if (aClass.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||||
|
checkEnumModifiers(aClass);
|
||||||
|
}
|
||||||
|
else if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
|
checkEnumEntry(aClass, classDescriptor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTraitModifiers(JetClass aClass) {
|
private void checkTraitModifiers(JetClass aClass) {
|
||||||
if (!aClass.isTrait()) return;
|
|
||||||
JetModifierList modifierList = aClass.getModifierList();
|
JetModifierList modifierList = aClass.getModifierList();
|
||||||
if (modifierList == null) return;
|
if (modifierList == null) return;
|
||||||
if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) {
|
if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) {
|
||||||
@@ -295,11 +300,13 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkEnumModifiers(JetClass aClass) {
|
||||||
|
if (aClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
||||||
|
trace.report(OPEN_MODIFIER_IN_ENUM.on(aClass));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkEnumEntry(JetClass aClass, ClassDescriptor classDescriptor) {
|
||||||
private void checkEnum(JetClass aClass, ClassDescriptor classDescriptor) {
|
|
||||||
if (classDescriptor.getKind() != ClassKind.ENUM_ENTRY) return;
|
|
||||||
|
|
||||||
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration().getContainingDeclaration();
|
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration().getContainingDeclaration();
|
||||||
assert declaration instanceof ClassDescriptor;
|
assert declaration instanceof ClassDescriptor;
|
||||||
ClassDescriptorFromSource enumClass = (ClassDescriptorFromSource) declaration;
|
ClassDescriptorFromSource enumClass = (ClassDescriptorFromSource) declaration;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ trait T {}
|
|||||||
|
|
||||||
class Br(t : T) : T by t {}
|
class Br(t : T) : T by t {}
|
||||||
|
|
||||||
open enum class EN() {
|
<!OPEN_MODIFIER_IN_ENUM!>open<!> enum class EN() {
|
||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package kt1193
|
package kt1193
|
||||||
|
|
||||||
open enum class MyEnum(val i: Int) {
|
enum class MyEnum(val i: Int) {
|
||||||
A : MyEnum(12)
|
A : MyEnum(12)
|
||||||
<!ENUM_ENTRY_SHOULD_BE_INITIALIZED!>B<!> //no error
|
<!ENUM_ENTRY_SHOULD_BE_INITIALIZED!>B<!> //no error
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// FILE: MyJavaEnum.java
|
||||||
|
public enum MyJavaEnum {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
<!OPEN_MODIFIER_IN_ENUM!>open<!> enum class MyEnum() {
|
||||||
|
A: MyEnum()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MyEnum2() {}
|
||||||
|
|
||||||
|
class MyClass(): <!INVISIBLE_MEMBER, FINAL_SUPERTYPE!>MyEnum2<!>() {}
|
||||||
|
|
||||||
|
class MyClass2(): <!FINAL_SUPERTYPE!>MyJavaEnum<!>() {}
|
||||||
@@ -1244,6 +1244,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt");
|
doTest("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritanceFromEnum.kt")
|
||||||
|
public void testInheritanceFromEnum() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/enum/inheritanceFromEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaEnumValueOfMethod.kt")
|
@TestMetadata("javaEnumValueOfMethod.kt")
|
||||||
public void testJavaEnumValueOfMethod() throws Exception {
|
public void testJavaEnumValueOfMethod() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/enum/javaEnumValueOfMethod.kt");
|
doTest("compiler/testData/diagnostics/tests/enum/javaEnumValueOfMethod.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user