mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[java-highlighting] IDEA-202570 Unreachable statement inspection should highlight whole switch expression
Also, fixed unreachable statement highlighting in different cases GitOrigin-RevId: 20b28272b51c77e3413e1ca143222d35199728bd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ae33969db0
commit
325edf9af2
@@ -91,7 +91,14 @@ public final class HighlightControlFlowUtil {
|
||||
PsiElement keyword = null;
|
||||
if (unreachableStatement instanceof PsiIfStatement ||
|
||||
unreachableStatement instanceof PsiSwitchBlock ||
|
||||
unreachableStatement instanceof PsiLoopStatement) {
|
||||
unreachableStatement instanceof PsiLoopStatement ||
|
||||
unreachableStatement instanceof PsiThrowStatement ||
|
||||
unreachableStatement instanceof PsiReturnStatement ||
|
||||
unreachableStatement instanceof PsiYieldStatement ||
|
||||
unreachableStatement instanceof PsiTryStatement ||
|
||||
unreachableStatement instanceof PsiSynchronizedStatement ||
|
||||
unreachableStatement instanceof PsiAssertStatement ||
|
||||
unreachableStatement instanceof PsiLabeledStatement) {
|
||||
keyword = unreachableStatement.getFirstChild();
|
||||
}
|
||||
final PsiElement element = keyword != null ? keyword : unreachableStatement;
|
||||
|
||||
@@ -1152,7 +1152,9 @@ public final class ControlFlowUtil {
|
||||
PsiElement element = myFlow.getElement(i);
|
||||
|
||||
final PsiElement unreachableParent = getUnreachableExpressionParent(element);
|
||||
if (unreachableParent != null) return unreachableParent;
|
||||
if (unreachableParent != null) {
|
||||
return correctUnreachableStatement(unreachableParent);
|
||||
}
|
||||
|
||||
if (element == null || !PsiUtil.isStatement(element)) continue;
|
||||
if (element.getParent() instanceof PsiExpression) continue;
|
||||
@@ -1179,6 +1181,25 @@ public final class ControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiElement correctUnreachableStatement(PsiElement statement) {
|
||||
if (!(statement instanceof PsiStatement)) return statement;
|
||||
while (true) {
|
||||
PsiElement parent = statement.getParent();
|
||||
if (parent instanceof PsiDoWhileStatement || parent instanceof PsiLabeledStatement) {
|
||||
statement = parent;
|
||||
continue;
|
||||
}
|
||||
if (parent instanceof PsiCodeBlock && PsiTreeUtil.getPrevSiblingOfType(statement, PsiStatement.class) == null) {
|
||||
PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiBlockStatement) {
|
||||
statement = grandParent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement getUnreachableExpressionParent(@Nullable PsiElement element) {
|
||||
if (element instanceof PsiExpression) {
|
||||
@@ -1186,12 +1207,32 @@ public final class ControlFlowUtil {
|
||||
while (expression != null) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
return getUnreachableStatementParent(parent);
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiForStatement) {
|
||||
if (((PsiForStatement)grandParent).getInitialization() == parent) {
|
||||
return grandParent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
if (parent instanceof PsiLocalVariable && ((PsiLocalVariable)parent).getInitializer() == expression) {
|
||||
PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiDeclarationStatement) return grandParent;
|
||||
if (grandParent instanceof PsiResourceList && grandParent.getParent() instanceof PsiTryStatement) {
|
||||
return grandParent.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == expression ||
|
||||
parent instanceof PsiSwitchBlock && ((PsiSwitchBlock)parent).getExpression() == expression ||
|
||||
parent instanceof PsiWhileStatement && ((PsiWhileStatement)parent).getCondition() == expression ||
|
||||
parent instanceof PsiForeachStatement && ((PsiForeachStatement)parent).getIteratedValue() == expression) {
|
||||
parent instanceof PsiForeachStatement && ((PsiForeachStatement)parent).getIteratedValue() == expression ||
|
||||
parent instanceof PsiReturnStatement && ((PsiReturnStatement)parent).getReturnValue() == expression ||
|
||||
parent instanceof PsiYieldStatement && ((PsiYieldStatement)parent).getExpression() == expression ||
|
||||
parent instanceof PsiThrowStatement && ((PsiThrowStatement)parent).getException() == expression ||
|
||||
parent instanceof PsiSynchronizedStatement && ((PsiSynchronizedStatement)parent).getLockExpression() == expression ||
|
||||
parent instanceof PsiAssertStatement && ((PsiAssertStatement)parent).getAssertCondition() == expression) {
|
||||
return parent;
|
||||
}
|
||||
if (parent instanceof PsiExpression) {
|
||||
|
||||
@@ -137,8 +137,42 @@ class WithCondition {
|
||||
while (b);
|
||||
}
|
||||
|
||||
void testDoWhile3(boolean b) {
|
||||
return;
|
||||
<error descr="Unreachable statement">do</error> {
|
||||
if(b) {
|
||||
System.out.println("x");
|
||||
}
|
||||
} while(true);
|
||||
}
|
||||
|
||||
void testDoWhile4() {
|
||||
return;
|
||||
<error descr="Unreachable statement">do</error> do do do {
|
||||
System.out.println("pchela letela");
|
||||
} while(true); while(true); while(true); while(true);
|
||||
}
|
||||
|
||||
void testIfLabeled(boolean b) {
|
||||
return;
|
||||
<error descr="Unreachable statement">LABEL</error>:
|
||||
if (b == true) {
|
||||
break LABEL;
|
||||
}
|
||||
}
|
||||
|
||||
void testDoIfLabeled(boolean b) {
|
||||
return;
|
||||
<error descr="Unreachable statement">do</error> {
|
||||
LABEL:
|
||||
if (b == true) {
|
||||
break LABEL;
|
||||
}
|
||||
} while(true);
|
||||
}
|
||||
|
||||
int testReturn() {
|
||||
return 1;
|
||||
<error descr="Unreachable statement">return 2;</error>
|
||||
<error descr="Unreachable statement">return</error> 2;
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,16 @@ interface ii {}
|
||||
|
||||
int f1() throws Exception {
|
||||
return 2;
|
||||
<error descr="Unreachable statement">return 5;</error>
|
||||
<error descr="Unreachable statement">return</error> 5;
|
||||
}
|
||||
int f2(int i) throws Exception {
|
||||
if (i==2) return 2;
|
||||
throw new Exception();
|
||||
<error descr="Unreachable statement">return 5;</error>
|
||||
<error descr="Unreachable statement">return</error> 5;
|
||||
}
|
||||
int f3(int i) throws Exception {
|
||||
for (;;) return 2;
|
||||
<error descr="Unreachable statement">return 5;</error>
|
||||
<error descr="Unreachable statement">return</error> 5;
|
||||
}
|
||||
int f4(int i) throws Exception {
|
||||
try {
|
||||
@@ -34,7 +34,7 @@ interface ii {}
|
||||
} finally {
|
||||
if (i==6) return 9;
|
||||
}
|
||||
<error descr="Unreachable statement">return 5;</error>
|
||||
<error descr="Unreachable statement">return</error> 5;
|
||||
}
|
||||
|
||||
void f5()
|
||||
@@ -75,7 +75,7 @@ interface ii {}
|
||||
for (;;) {
|
||||
if (e==null) {
|
||||
return;
|
||||
<error descr="Unreachable statement">throw e;</error>
|
||||
<error descr="Unreachable statement">throw</error> e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ interface ii {}
|
||||
void test() {
|
||||
int i;
|
||||
return;
|
||||
<error descr="Unreachable statement">assert i == i;</error>
|
||||
<error descr="Unreachable statement">assert</error> i == i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,15 @@ class Bar {
|
||||
}
|
||||
|
||||
void m() {
|
||||
while (T == "a") {
|
||||
<error descr="Unreachable statement">f();</error>
|
||||
}
|
||||
while (T == "a") <error descr="Unreachable statement">{
|
||||
f();
|
||||
}</error>
|
||||
}
|
||||
|
||||
void m01() {
|
||||
while (T != "") {
|
||||
<error descr="Unreachable statement">f();</error>
|
||||
}
|
||||
while (T != "") <error descr="Unreachable statement">{
|
||||
f();
|
||||
}</error>
|
||||
}
|
||||
|
||||
void m1() {
|
||||
@@ -29,9 +29,9 @@ class Bar {
|
||||
}
|
||||
|
||||
void m2() {
|
||||
while (T != T) {
|
||||
<error descr="Unreachable statement">f();</error>
|
||||
}
|
||||
while (T != T) <error descr="Unreachable statement">{
|
||||
f();
|
||||
}</error>
|
||||
}
|
||||
|
||||
void m3() {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
public class DeadCode {
|
||||
private static String m1(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">return</error> switch (1) {
|
||||
default -> "x";
|
||||
};
|
||||
}
|
||||
|
||||
private static String m2(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">int x = switch (1) {
|
||||
default -> 0;
|
||||
};</error>
|
||||
}
|
||||
|
||||
private static String m3(int n) {
|
||||
int x;
|
||||
return "";
|
||||
<error descr="Unreachable statement">x = switch (1) {
|
||||
default -> 0;
|
||||
};</error>
|
||||
}
|
||||
|
||||
private static String m4(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">throw</error> switch (1) {
|
||||
default -> new RuntimeException();
|
||||
};
|
||||
}
|
||||
|
||||
private static String m5(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">try</error> (AutoCloseable x = switch(1) {default -> () -> {};}) {} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String m6(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">synchronized</error> (switch(1) {default -> "";}) {
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
|
||||
private static String m7(int n) {
|
||||
return "";
|
||||
<error descr="Unreachable statement">if</error>(switch (1) {default -> true;}) {}
|
||||
}
|
||||
|
||||
private static String m8(int n) {
|
||||
return switch (n) {
|
||||
default:
|
||||
yield "x";
|
||||
<error descr="Unreachable statement">yield</error> switch(1) { default -> ""; };
|
||||
};
|
||||
}
|
||||
|
||||
private static String m9() {
|
||||
return "";
|
||||
<error descr="Unreachable statement">assert</error> switch(1) {default -> true;};
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ class C {
|
||||
|
||||
void endlessLoopInBranchWithValueBreak(String arg) {
|
||||
int result = switch (arg) {
|
||||
case "one" -> { while(true); <error descr="Unreachable statement">yield 1;</error>}
|
||||
case "one" -> { while(true); <error descr="Unreachable statement">yield</error> 1;}
|
||||
default -> 0;
|
||||
};
|
||||
System.out.println(result);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class Test {
|
||||
|
||||
public static void test() {
|
||||
for(int a = 1; <warning descr="Condition is always false">fal<caret>se</warning>; System.out.println("Just anything here: will not be executed anyways")) {
|
||||
<error descr="Unreachable statement">System.out.println("Hello");</error>
|
||||
}
|
||||
for(int a = 1; <warning descr="Condition is always false">fal<caret>se</warning>; System.out.println("Just anything here: will not be executed anyways")) <error descr="Unreachable statement">{
|
||||
System.out.println("Hello");
|
||||
}</error>
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
class Test {
|
||||
|
||||
public static void test() {
|
||||
while ((<warning descr="Condition is always false">fa<caret>lse</warning>)) {
|
||||
<error descr="Unreachable statement">System.out.println();</error>
|
||||
}
|
||||
while ((<warning descr="Condition is always false">fa<caret>lse</warning>)) <error descr="Unreachable statement">{
|
||||
System.out.println();
|
||||
}</error>
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ class JavaSwitchExpressionsHighlightingTest : LightJavaCodeInsightFixtureTestCas
|
||||
fun testSwitchExpressionHasResult() = doTest()
|
||||
fun testYieldStatements() = doTest()
|
||||
fun testAssignToFinalInSwitchExpression() = doTest()
|
||||
fun testDeadCode() = doTest()
|
||||
fun testRedundantCastInSwitchBranch() {
|
||||
myFixture.enableInspections(RedundantCastInspection())
|
||||
doTest()
|
||||
|
||||
Reference in New Issue
Block a user