Records extend the Record class (IDEA-228460)

GitOrigin-RevId: f99f9cfbe07cec22bc34596366c97d62d024e4b2
This commit is contained in:
Tagir Valeev
2019-12-19 06:13:56 +00:00
committed by intellij-monorepo-bot
parent 18c9b23282
commit 4bc45f31f0
10 changed files with 52 additions and 13 deletions
@@ -1206,16 +1206,6 @@ public class GenericsHighlightUtil {
return null;
}
static HighlightInfo checkCannotInheritFromEnum(@NotNull PsiClass superClass, @NotNull PsiElement elementToHighlight) {
HighlightInfo errorResult = null;
if (Comparing.strEqual("java.lang.Enum", superClass.getQualifiedName())) {
String message = JavaErrorMessages.message("classes.extends.enum");
errorResult =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(elementToHighlight).descriptionAndTooltip(message).create();
}
return errorResult;
}
static HighlightInfo checkGenericCannotExtendException(@NotNull PsiReferenceList list) {
PsiElement parent = list.getParent();
if (parent instanceof PsiClass) {
@@ -105,7 +105,7 @@ public class HighlightClassUtil {
if (aClass.isEnum()) {
if (hasEnumConstantsWithInitializer(aClass)) return null;
}
else if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) || aClass.getRBrace() == null ) {
else if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) || aClass.getRBrace() == null || aClass.isRecord()) {
return null;
}
return checkClassWithAbstractMethods(aClass, textRange);
@@ -910,4 +910,25 @@ public class HighlightClassUtil {
}
return null;
}
static HighlightInfo checkExtendsProhibitedClass(@NotNull PsiClass superClass, @NotNull PsiElement elementToHighlight) {
String qualifiedName = superClass.getQualifiedName();
if (CommonClassNames.JAVA_LANG_ENUM.equals(qualifiedName) || CommonClassNames.JAVA_LANG_RECORD.equals(qualifiedName)) {
String message = JavaErrorMessages.message("classes.extends.prohibited.super", qualifiedName);
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(elementToHighlight).descriptionAndTooltip(message).create();
}
return null;
}
public static HighlightInfo checkAnonymousInheritProhibited(PsiNewExpression expression) {
PsiAnonymousClass aClass = expression.getAnonymousClass();
if (aClass != null) {
PsiClass superClass = aClass.getSuperClass();
PsiJavaCodeReferenceElement reference = expression.getClassOrAnonymousClassReference();
if (superClass != null && reference != null) {
return checkExtendsProhibitedClass(superClass, reference);
}
}
return null;
}
}
@@ -3033,7 +3033,7 @@ public class HighlightUtil extends HighlightUtilBase {
highlightInfo = HighlightClassUtil.checkCannotInheritFromFinal(aClass, ref);
}
if (highlightInfo == null) {
highlightInfo = GenericsHighlightUtil.checkCannotInheritFromEnum(aClass, ref);
highlightInfo = HighlightClassUtil.checkExtendsProhibitedClass(aClass, ref);
}
if (highlightInfo == null) {
highlightInfo = GenericsHighlightUtil.checkCannotInheritFromTypeParameter(aClass, ref);
@@ -1042,6 +1042,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
PsiJavaCodeReferenceElement classReference = expression.getClassReference();
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, classReference != null ? classReference.getTextRange() : null));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritProhibited(expression));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression, type, aClass));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression, type, aClass));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
@@ -704,6 +704,9 @@ public class PsiClassImplUtil {
if (psiClass.isEnum()) {
return findSpecialSuperClass(psiClass, CommonClassNames.JAVA_LANG_ENUM);
}
if (psiClass.isRecord()) {
return findSpecialSuperClass(psiClass, CommonClassNames.JAVA_LANG_RECORD);
}
if (psiClass instanceof PsiAnonymousClass) {
PsiClassType baseClassReference = ((PsiAnonymousClass)psiClass).getBaseClassType();
@@ -941,6 +944,14 @@ public class PsiClassImplUtil {
PsiClassType enumSuperType = getEnumSuperType(psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()));
return enumSuperType == null ? PsiClassType.EMPTY_ARRAY : new PsiClassType[]{enumSuperType};
}
if (psiClass.isRecord()) {
final PsiClass recordClass = findSpecialSuperClass(psiClass, CommonClassNames.JAVA_LANG_RECORD);
if (recordClass != null) {
return new PsiClassType[]{new PsiImmediateClassType(recordClass, PsiSubstitutor.EMPTY)};
}
PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject());
return new PsiClassType[]{factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_RECORD, psiClass.getResolveScope())};
}
if (psiClass.isAnnotationType()) {
return new PsiClassType[]{getAnnotationSuperType(psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()))};
}
@@ -110,7 +110,7 @@ vararg.not.last.parameter=Vararg parameter must be the last in the list
modifiers.for.enum.constants=No modifiers allowed for enum constants
generics.type.arguments.on.raw.type=Type arguments given on a raw type
generics.type.arguments.on.raw.method=Type arguments given on a raw method
classes.extends.enum=Classes cannot directly extend 'java.lang.Enum'
classes.extends.prohibited.super=Classes cannot directly extend ''{0}''
unchecked.overriding.incompatible.return.type=Unchecked overriding: return type requires unchecked conversion. Found ''{0}'', required ''{1}''
local.enum=Enum must not be local
@@ -7,6 +7,14 @@ class ClassWithComponents2<error descr="Record header declared for non-record">(
<error descr="Modifier 'abstract' not allowed here">abstract</error> record AbstractRecord() {}
record ExtendsObject() <error descr="No extends clause allowed for record">extends Object</error> {}
class ExtendsRecord extends <error descr="Cannot inherit from final 'NoComponents'">NoComponents</error> {}
abstract class ExtendsJLR extends <error descr="Classes cannot directly extend 'java.lang.Record'">Record</error> {}
class AnonymousExtendsJLR {
Record r = new <error descr="Classes cannot directly extend 'java.lang.Record'">Record</error>() {
public boolean equals(Object other) {return this == other;}
public int hashCode() {return 0;}
public String toString() {return "";}
};
}
record ComponentModifiers(
<error descr="Modifier 'public' not allowed here">public</error> int x,
@@ -123,6 +123,8 @@ class X extends <error descr="Classes cannot directly extend 'java.lang.Enum'">E
public X(String name, int ordinal) {
super(name, ordinal);
}
Enum e = new <error descr="Classes cannot directly extend 'java.lang.Enum'">Enum</error>("", 0) {};
}
enum StaticInEnumConstantInitializer {
@@ -32,6 +32,11 @@ public class LightRecordsHighlightingTest extends LightJavaCodeInsightFixtureTes
}
private void doTest() {
myFixture.addClass("package java.lang; public abstract class Record {" +
"public abstract boolean equals(Object obj);" +
"public abstract int hashCode();" +
"public abstract String toString();" +
"}");
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
}
@@ -12,6 +12,7 @@ public interface CommonClassNames {
String JAVA_LANG_CLASS = "java.lang.Class";
String JAVA_LANG_OVERRIDE = "java.lang.Override";
String JAVA_LANG_ENUM = "java.lang.Enum";
String JAVA_LANG_RECORD = "java.lang.Record";
String JAVA_LANG_VOID = "java.lang.Void";
String JAVA_UTIL_OBJECTS = "java.util.Objects";