[java-highlighting] Allow statics inside inner since Java 16 (IDEA-257410)

Also remove redundant record tests

GitOrigin-RevId: ce57189891b3df3ba4659e8e3a2ded125234911a
This commit is contained in:
Tagir Valeev
2020-12-25 17:24:24 +07:00
committed by intellij-monorepo-bot
parent 6362ce9276
commit 5d20b5dbb9
19 changed files with 173 additions and 81 deletions

View File

@@ -123,6 +123,7 @@ feature.patterns.instanceof=Patterns in 'instanceof'
feature.sealed.classes=Sealed classes
feature.local.interfaces=Local interfaces
feature.local.enums=Local enums
feature.inner.statics=Static declarations in inner classes
find.searching.for.references.to.class.progress=Searching for references to class {0}...
find.usages.panel.title.derived.classes=Derived Classes

View File

@@ -371,8 +371,8 @@ public final class HighlightClassUtil {
return null;
}
String message = JavaErrorBundle.message("static.declaration.in.inner.class");
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(keyword).descriptionAndTooltip(message).create();
HighlightInfo result = HighlightUtil.checkFeature(keyword, HighlightingFeature.INNER_STATICS,
PsiUtil.getLanguageLevel(field), field.getContainingFile());
QuickFixAction.registerQuickFixAction(result, QUICK_FIX_FACTORY.createModifierListFix(field, PsiModifier.STATIC, false, false));
registerMakeInnerClassStatic(field.getContainingClass(), result);
@@ -392,8 +392,8 @@ public final class HighlightClassUtil {
}
PsiMethod method = (PsiMethod)keyword.getParent().getParent();
if (PsiUtilCore.hasErrorElementChild(method)) return null;
String message = JavaErrorBundle.message("static.declaration.in.inner.class");
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(keyword).descriptionAndTooltip(message).create();
HighlightInfo result = HighlightUtil.checkFeature(keyword, HighlightingFeature.INNER_STATICS,
PsiUtil.getLanguageLevel(method), method.getContainingFile());
QuickFixAction.registerQuickFixAction(result, QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.STATIC, false, false));
registerMakeInnerClassStatic((PsiClass)keyword.getParent().getParent().getParent(), result);
return result;
@@ -405,8 +405,8 @@ public final class HighlightClassUtil {
}
PsiClassInitializer initializer = (PsiClassInitializer)keyword.getParent().getParent();
if (PsiUtilCore.hasErrorElementChild(initializer)) return null;
String message = JavaErrorBundle.message("static.declaration.in.inner.class");
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(keyword).descriptionAndTooltip(message).create();
HighlightInfo result = HighlightUtil.checkFeature(keyword, HighlightingFeature.INNER_STATICS,
PsiUtil.getLanguageLevel(initializer), initializer.getContainingFile());
QuickFixAction.registerQuickFixAction(result, QUICK_FIX_FACTORY.createModifierListFix(initializer, PsiModifier.STATIC, false, false));
registerMakeInnerClassStatic((PsiClass)keyword.getParent().getParent().getParent(), result);
return result;
@@ -451,11 +451,13 @@ public final class HighlightClassUtil {
}
}
}
TextRange range = context != null ? context.getTextRange() : HighlightNamesUtil.getClassDeclarationTextRange(aClass);
String message = JavaErrorBundle.message("static.declaration.in.inner.class");
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(message).create();
HighlightInfo info = HighlightUtil.checkFeature(range, HighlightingFeature.INNER_STATICS,
PsiUtil.getLanguageLevel(aClass), aClass.getContainingFile());
if (context != keyword) {
QuickFixAction.registerQuickFixActions(info, null, JvmElementActionFactories.createModifierActions(aClass, MemberRequestsKt.modifierRequest(JvmModifier.STATIC, false)));
QuickFixAction.registerQuickFixActions(info, null, JvmElementActionFactories
.createModifierActions(aClass, MemberRequestsKt.modifierRequest(JvmModifier.STATIC, false)));
}
PsiClass containingClass = aClass.getContainingClass();
registerMakeInnerClassStatic(containingClass, info);

View File

@@ -992,7 +992,8 @@ public final class HighlightUtil {
else {
//noinspection DuplicateExpressions
if (PsiModifier.STATIC.equals(modifier) || privateOrProtected || PsiModifier.PACKAGE_LOCAL.equals(modifier)) {
isAllowed = modifierOwnerParent instanceof PsiClass && ((PsiClass)modifierOwnerParent).getQualifiedName() != null ||
isAllowed = modifierOwnerParent instanceof PsiClass &&
(PsiModifier.STATIC.equals(modifier) || ((PsiClass)modifierOwnerParent).getQualifiedName() != null) ||
FileTypeUtils.isInServerPageFile(modifierOwnerParent) ||
// non-physical dummy holder might not have FQN
!modifierOwnerParent.isPhysical();

View File

@@ -82,7 +82,8 @@ public enum HighlightingFeature {
LanguageLevel getStandardLevel() {
return LanguageLevel.JDK_16;
}
};
},
INNER_STATICS(LanguageLevel.JDK_16, "feature.inner.statics");
public static final @NonNls String JDK_INTERNAL_PREVIEW_FEATURE = "jdk.internal.PreviewFeature";

View File

@@ -94,7 +94,6 @@ class.expected=Class name expected here
implements.after.interface=No implements clause allowed for interface
extends.after.enum=No extends clause allowed for enum
permits.after.enum=No permits clause allowed for enum
static.declaration.in.inner.class=Inner classes cannot have static declarations
class.must.be.abstract=Class ''{0}'' must either be declared abstract or implement abstract method ''{1}'' in ''{2}''
enum.constant.must.implement.method=Enum constant ''{0}'' must implement abstract method ''{1}'' in ''{2}''
class.must.implement.method=Class ''{0}'' must implement abstract method ''{1}'' in ''{2}''

View File

@@ -5,26 +5,26 @@ public class a {
static final int ix = x== null ? 4 : 3;
class ic {
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int i;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f2 = x instanceof Integer ? 1 : 0;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
class a_ic_c {}
<error descr="Inner classes cannot have static declarations">interface a_ic_i</error> {}
<error descr="Inner classes cannot have static declarations">static</error> interface a_ic_i2 {}
<error descr="Static declarations in inner classes are not supported at language level '1.4'">interface a_ic_i</error> {}
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error> interface a_ic_i2 {}
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int a_ic_m(String s) { return 0; }
// static initializer
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
{}
}
@@ -39,22 +39,22 @@ public class a {
// static inside class inside code block
void f() {
class ic2 {
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int i;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f2 = x instanceof Integer ? 1 : 0;
<error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
class a_ic_c2 {}
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int a_ic_m2(String s) { return 0; }
// static initializer
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
{}
}
}
@@ -62,26 +62,26 @@ public class a {
void f1()
{
new a() {
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int i;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
// its not a compile time constant
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final Object o = null;
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
final int f2 = x instanceof Integer ? 1 : 0;
<error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
class a_ic_c2 {}
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
int a_ic_m2(String s) { return 0; }
// static initializer
<error descr="Inner classes cannot have static declarations">static</error>
<error descr="Static declarations in inner classes are not supported at language level '1.4'">static</error>
{}
};
}
@@ -93,12 +93,12 @@ public class a {
}
void ff() {
class inn {
<error descr="Inner classes cannot have static declarations">interface i</error> {}
<error descr="Static declarations in inner classes are not supported at language level '1.4'">interface i</error> {}
}
}
Object o = new Runnable() {
<error descr="Inner classes cannot have static declarations">interface i</error> {}
<error descr="Static declarations in inner classes are not supported at language level '1.4'">interface i</error> {}
public void run() {}
};
}

View File

@@ -0,0 +1,94 @@
//statics in inner
public class a {
static final Number x = null;
static final int ix = x== null ? 4 : 3;
class ic {
static int i;
static final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
static final int f2 = x instanceof Integer ? 1 : 0;
static class a_ic_c {}
interface a_ic_i {}
static interface a_ic_i2 {}
static int a_ic_m(String s) { return 0; }
// static initializer
static {}
}
interface ii {
static int i = 9;
void f();
// since nested interface is implicitly static:
static class ii_c {}
}
// static inside class inside code block
void f() {
class ic2 {
static int i;
static final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
static final int f2 = x instanceof Integer ? 1 : 0;
static class a_ic_c2 {}
static int a_ic_m2(String s) { return 0; }
// static initializer
static {}
}
}
void f1()
{
new a() {
static int i;
static final int f1 = 3 < 4 ? (a.ix==5 ? 1 : 3) / 4 + 18 : 0;
static final Object o = null;
static final int f2 = x instanceof Integer ? 1 : 0;
static class a_ic_c2 {}
static int a_ic_m2(String s) { return 0; }
// static initializer
static {}
};
}
// local interface
class cc {
void f() {
interface i {}
}
void ff() {
class inn {
interface i {}
}
}
Object o = new Runnable() {
interface i {}
public void run() {}
};
}
void withanonymous() {
new Object() {
<error descr="Modifier 'private' not allowed here">private</error> class RT {}
private void method() {}
private int myI;
};
}
}

View File

@@ -4,7 +4,7 @@ class Test {
final Object o = null;
class A {
static final String t = s;
<error descr="Inner classes cannot have static declarations">static</error> final Object j = <error descr="Non-static variable 'o' cannot be referenced from a static context">o</error>;
<error descr="Static declarations in inner classes are not supported at language level '6'">static</error> final Object j = <error descr="Non-static variable 'o' cannot be referenced from a static context">o</error>;
}
}

View File

@@ -1,4 +0,0 @@
record CheckOverride(int x) {
@Override public int x() { return x; }
<error descr="Method does not override method from its superclass">@Override</error> public int y() { return x; }
}

View File

@@ -55,7 +55,7 @@ record AnnotatedComponents(
class Outer {
record NestedRecord() {}
class Inner {
<error descr="Inner classes cannot have static declarations">record InnerRecord()</error> {}
<error descr="Static declarations in inner classes are not supported at language level '15'">record InnerRecord()</error> {}
}
}
@@ -72,4 +72,6 @@ record StaticFieldCollides(int i) {
}
record Incomplete(@<error descr="Class reference expected">i</error>nt a) {}
record CStyle(int a<error descr="C-style record component declaration is not allowed">[]</error>) {}
record CStyle2(int[] a<error descr="C-style record component declaration is not allowed">[] []</error> ) {}
record JavaStyle(int[] [] a) {}
record SafeVarargComponent(<error descr="@SafeVarargs annotation cannot be applied for a record component">@SafeVarargs</error> int... component) {}

View File

@@ -1,5 +0,0 @@
import java.lang.annotation.*;
record CStyle(int a<error descr="C-style record component declaration is not allowed">[]</error>) {}
record CStyle2(int[] a<error descr="C-style record component declaration is not allowed">[] []</error> ) {}
record JavaStyle(int[] [] a) {}

View File

@@ -0,0 +1,6 @@
class Outer {
record NestedRecord() {}
class Inner {
record InnerRecord() {}
}
}

View File

@@ -47,4 +47,20 @@ record CompactAndCanonical(int x, int y) {
<error descr="'CompactAndCanonical(int, int)' is already defined in 'CompactAndCanonical'">public CompactAndCanonical</error> {
}
}
record WrittenFields(int x,
int y,
int z) {
public WrittenFields {
<error descr="Cannot assign a value to final variable 'x'">this.x</error> = 0;
if (Math.random() > 0.5) <error descr="Cannot assign a value to final variable 'y'">this.y</error> = 1;
}
}
// IDEA-256804
record CompactCtorDelegate(String a) {
public CompactCtorDelegate {}
public CompactCtorDelegate() {
this("hello");
System.out.println(String.valueOf(this.a.charAt(0)));
}
}

View File

@@ -1,16 +0,0 @@
record WrittenFields(int x,
int y,
int z) {
public WrittenFields {
<error descr="Cannot assign a value to final variable 'x'">this.x</error> = 0;
if (Math.random() > 0.5) <error descr="Cannot assign a value to final variable 'y'">this.y</error> = 1;
}
}
// IDEA-256804
record CompactCtorDelegate(String a) {
public CompactCtorDelegate {}
public CompactCtorDelegate() {
this("hello");
System.out.println(String.valueOf(this.a.charAt(0)));
}
}

View File

@@ -129,8 +129,8 @@ class X extends <error descr="Classes cannot directly extend 'java.lang.Enum'">E
enum StaticInEnumConstantInitializer {
AN {
<error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error> class s { }
private <error descr="Inner classes cannot have static declarations">static</error> final String t = String.valueOf(1);
<error descr="Static declarations in inner classes are not supported at language level '5'">static</error> class s { }
private <error descr="Static declarations in inner classes are not supported at language level '5'">static</error> final String t = String.valueOf(1);
};
}
@@ -204,7 +204,7 @@ class NestedEnums {
enum E1 { }
class C2 {
<error descr="Inner classes cannot have static declarations">enum E2</error> { }
<error descr="Static declarations in inner classes are not supported at language level '5'">enum E2</error> { }
}
static class C3 {
@@ -213,7 +213,7 @@ class NestedEnums {
{
new C3() {
<error descr="Inner classes cannot have static declarations">enum E2</error> { }
<error descr="Static declarations in inner classes are not supported at language level '5'">enum E2</error> { }
};
}
}

View File

@@ -115,8 +115,8 @@ class X extends <error descr="Classes cannot directly extend 'java.lang.Enum'">E
enum StaticInEnumConstantInitializer {
AN {
<error descr="Inner classes cannot have static declarations"><error descr="Modifier 'static' not allowed here">static</error></error> class s { }
private <error descr="Inner classes cannot have static declarations">static</error> final String t = String.valueOf(1);
<error descr="Static declarations in inner classes are not supported at language level '8'">static</error> class s { }
private <error descr="Static declarations in inner classes are not supported at language level '8'">static</error> final String t = String.valueOf(1);
};
}
@@ -190,7 +190,7 @@ class NestedEnums {
enum E1 { }
class C2 {
<error descr="Inner classes cannot have static declarations">enum E2</error> { }
<error descr="Static declarations in inner classes are not supported at language level '8'">enum E2</error> { }
}
static class C3 {
@@ -199,7 +199,7 @@ class NestedEnums {
{
new C3() {
<error descr="Inner classes cannot have static declarations">enum E2</error> { }
<error descr="Static declarations in inner classes are not supported at language level '8'">enum E2</error> { }
};
}
}

View File

@@ -89,6 +89,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testDuplicateClassMethod() { doTest(false); }
public void testStringLiterals() { doTest(false); }
public void testStaticInInner() { doTest(false); }
public void testStaticInInnerJava16() { IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_16, () -> doTest(false)); }
public void testInvalidExpressions() { doTest(false); }
public void testIllegalVoidType() { doTest(false); }
public void testIllegalType() { doTest(false); }

View File

@@ -26,27 +26,21 @@ public class LightRecordsHighlightingTest extends LightJavaCodeInsightFixtureTes
public void testRecordBasics() {
doTest();
}
public void testRecordBasicsJava15() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_15_PREVIEW, this::doTest);
public void testRecordBasicsJava16() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_16, this::doTest);
}
public void testRecordAccessors() {
doTest();
}
public void testRecordAccessorsJava15() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_15_PREVIEW, this::doTest);
}
public void testRecordConstructors() {
doTest();
}
public void testRecordConstructorAccessJava15() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_15_PREVIEW, this::doTest);
doTest();
}
public void testRecordCompactConstructors() {
doTest();
}
public void testRecordCompactConstructorsJava15() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_15_PREVIEW, this::doTest);
}
public void testLocalRecords() {
doTest();
}

View File

@@ -99,10 +99,10 @@ public class UnnecessaryParenthesesInspection
}
class ParenthesesAroundLambda {
<error descr="Inner classes cannot have static declarations">interface I</error> {
<error descr="Static declarations in inner classes are not supported at language level '15'">interface I</error> {
void foo(int x, int y);
}
<error descr="Inner classes cannot have static declarations">interface J</error> {
<error descr="Static declarations in inner classes are not supported at language level '15'">interface J</error> {
void foo(int x);
}