[java-highlighting] IDEA-340211 Unnamed variables, turn on for java 22 (JEP 456)

- turn on for java 22
- add more tests for java 22

GitOrigin-RevId: 62b25e768ef827da94acffc8a9054c6b5775254e
This commit is contained in:
Mikhail Pyltsin
2023-12-08 17:13:29 +00:00
committed by intellij-monorepo-bot
parent ebf9bb5b23
commit 9aa54b1fd4
10 changed files with 161 additions and 13 deletions
@@ -89,7 +89,12 @@ public enum HighlightingFeature {
},
ENUM_QUALIFIED_NAME_IN_SWITCH(LanguageLevel.JDK_21, "feature.enum.qualified.name.in.switch"),
STRING_TEMPLATES(LanguageLevel.JDK_21_PREVIEW, "feature.string.templates"),
UNNAMED_PATTERNS_AND_VARIABLES(LanguageLevel.JDK_21_PREVIEW, "feature.unnamed.vars"),
UNNAMED_PATTERNS_AND_VARIABLES(LanguageLevel.JDK_22, "feature.unnamed.vars") {
@Override
boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
return super.isSufficient(useSiteLevel) || LanguageLevel.JDK_21_PREVIEW == useSiteLevel;
}
},
UNNAMED_CLASSES(LanguageLevel.JDK_21_PREVIEW, "feature.unnamed.classes");
public static final @NonNls String JDK_INTERNAL_PREVIEW_FEATURE = "jdk.internal.PreviewFeature";
@@ -0,0 +1,47 @@
public class UnnamedPatterns {
record R(int a, int b) {}
void test(Object obj) {
if (obj instanceof <error descr="Using '_' as a reference is not allowed">_</error>) {}
if (obj instanceof R(_, _)) {}
if (obj instanceof R(int a, _)) {
System.out.println(a);
}
if (obj instanceof R(_, int b)) {
System.out.println(b);
}
if (obj instanceof R(_, _, <error descr="Incorrect number of nested patterns: expected 2 but found 3">_)</error>) {
}
}
void testSwitch(Object obj) {
switch (obj) {
case R(_, var b) -> {
}
case <error descr="Label is dominated by a preceding case label 'R(_, var b)'">R(var c, var b)</error> -> {
}
case <error descr="Label is dominated by a preceding case label 'R(_, var b)'">R(int a, _)</error> -> {
}
default -> {
}
}
}
void testExhaustiveness(I a) {
boolean r3 = switch (a) {
case R1(_) -> true;
case R2(_) -> false;
};
}
void testNonExhaustiveness(I a) {
boolean r3 = switch (<error descr="'switch' expression does not cover all possible input values">a</error>) {
case R1(_) -> true;
};
}
sealed interface I {};
record R1(int n1) implements I {};
record R2(int n1) implements I {};
}
@@ -0,0 +1,57 @@
import java.util.function.*;
public class UnnamedVariables {
void testParameter(<error descr="Unnamed method parameter is not allowed">int _</error>, <error descr="Unnamed method parameter is not allowed">String _</error>) {
System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>);
}
<error descr="Unnamed field is not allowed">int _</error> = 123;
String s = <error descr="Using '_' as a reference is not allowed">_</error>;
void testLambda() {
Consumer<String> consumer = _ -> System.out.println("Hello");
Consumer<String> consumer2 = _ -> System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>);
Consumer<String> consumer3 = _ -> System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>.trim());
Consumer<String> consumer4 = _ -> {
var v = <error descr="Using '_' as a reference is not allowed">_</error>;
System.out.println(v.<error descr="Cannot resolve method 'trim()'" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">trim</error>());
};
BiConsumer<String, String> consumer5 = (_,_) -> {};
}
void testWhen(Object obj) {
switch (obj) {
case String _ when <error descr="Using '_' as a reference is not allowed">_</error>.isEmpty() -> {}
}
}
void testLocal() {
int _ = 10;
int _ = 20;
int _<error descr="Brackets are not allowed after unnamed variable declaration ">[]</error> = {30};
int[] _ = {40};
var _ = "string";
for (int _ = 1;;) {}
}
void testNoInitializer() {
<error descr="Unnamed variable declaration must have an initializer">int _</error>;
for(<error descr="Unnamed variable declaration must have an initializer">int _</error>;;) {}
}
void testCatch() {
try {
System.out.println();
}
catch (Exception _) {
System.out.println("ignore");
}
catch (Error _) {
int _ = 1;
for(int _:new int[10]) {
System.out.println("oops");
}
}
}
}
@@ -0,0 +1,25 @@
class Test {
public static String testReach(Object o1, Object o2) {
return switch (o1) {
case String _ when o2 instanceof String s: yield s;
case Object _: yield "strange";
};
}
record R(int x, int y) {}
void test(Object obj) {
if (obj instanceof R(_, var b)) {
return;
}
if (<warning descr="Condition 'obj instanceof R(var a, var b)' is always 'false'">obj instanceof R(var a, var b)</warning>) {
return;
}
if (<warning descr="Condition 'obj instanceof R(int a, _)' is always 'false'">obj instanceof R(int a, _)</warning>) {
return;
}
}
public static void main(String[] args) {
System.out.println(testReach("1", "2"));
}
}
@@ -6,7 +6,7 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21;
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_22;
public class ChangeToUnnamedPatternTest extends LightIntentionActionTestCase {
@Override
@@ -18,7 +18,7 @@ public class ChangeToUnnamedPatternTest extends LightIntentionActionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
return JAVA_22;
}
@Override
@@ -3,11 +3,10 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21;
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_22;
public class RenameToUnnamedVariableTest extends LightIntentionActionTestCase {
@Override
@@ -19,7 +18,7 @@ public class RenameToUnnamedVariableTest extends LightIntentionActionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
return JAVA_22;
}
@Override
@@ -98,9 +98,13 @@ public class LightPatternsHighlightingTest extends LightJavaCodeInsightFixtureTe
}
public void testUnnamedPatterns() {
doTest();
}
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21_PREVIEW, this::doTest);
}
public void testUnnamedPatternsJava22() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_22, this::doTest);
}
public void testUnnamedPatternsUnavailable() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20, this::doTest);
}
@@ -16,13 +16,17 @@ public class LightUnnamedVariablesHighlightingTest extends LightJavaCodeInsightF
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
return JAVA_22;
}
public void testUnnamedVariables() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21_PREVIEW, () -> doTest());
}
public void testUnnamedVariablesJava22() {
doTest();
}
}
public void testUnnamedVariablesInGuard() {
doTest();
}
@@ -2,6 +2,8 @@
package com.intellij.java.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
@@ -55,7 +57,11 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
public void testUnnamedPatterns() {
doTest();
}
public void testUnnamedPatternsJava22() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_22, this::doTest);
}
public void testPatternInStreamNotComplex() {
doTest();
}
@@ -90,6 +90,7 @@ public abstract class LightJavaCodeInsightFixtureTestCase extends UsefulTestCase
public static final @NotNull LightProjectDescriptor JAVA_19 = new ProjectDescriptor(LanguageLevel.JDK_19);
public static final @NotNull LightProjectDescriptor JAVA_20 = new ProjectDescriptor(LanguageLevel.JDK_20_PREVIEW);
public static final @NotNull LightProjectDescriptor JAVA_21 = new ProjectDescriptor(LanguageLevel.JDK_21_PREVIEW);
public static final @NotNull LightProjectDescriptor JAVA_22 = new ProjectDescriptor(LanguageLevel.JDK_22_PREVIEW);
public static final @NotNull LightProjectDescriptor JAVA_X = new ProjectDescriptor(LanguageLevel.JDK_X);
public static final @NotNull LightProjectDescriptor JAVA_LATEST = new ProjectDescriptor(LanguageLevel.HIGHEST) {