[java-highlighting] IDEA-324405 Not take into account guarded cases for dominating

GitOrigin-RevId: 980851746c2e1c1e0f644540867c970598224d2a
This commit is contained in:
Mikhail Pyltsin
2023-07-05 13:24:59 +02:00
committed by intellij-monorepo-bot
parent a3e6bf2822
commit f92fe33afa
6 changed files with 46 additions and 19 deletions

View File

@@ -701,12 +701,11 @@ public class SwitchBlockHighlightingModel {
for (int j = i + 1; j < switchLabels.size(); j++) {
PsiElement next = switchLabels.get(j);
if (!(next instanceof PsiCaseLabelElement nextElement)) continue;
if (PsiUtil.getLanguageLevel(current).isAtLeast(LanguageLevel.JDK_20_PREVIEW) &&
!JavaPsiPatternUtil.isUnconditionalForType(nextElement, mySelectorType) &&
if (!JavaPsiPatternUtil.isUnconditionalForType(nextElement, mySelectorType) &&
((!(next instanceof PsiExpression expression) || ExpressionUtils.isNullLiteral(expression)) &&
current instanceof PsiKeyword &&
PsiKeyword.DEFAULT.equals(current.getText()) || isInCaseNullDefaultLabel(current))) {
// JEP 432
// JEP 440-441
// A 'default' label dominates a case label with a case pattern,
// and it also dominates a case label with a null case constant.
// A 'case null, default' label dominates all other switch labels.
@@ -716,16 +715,10 @@ public class SwitchBlockHighlightingModel {
if (isConstantLabelElement(nextElement)) {
PsiExpression constExpr = ObjectUtils.tryCast(nextElement, PsiExpression.class);
assert constExpr != null;
if ((PsiUtil.getLanguageLevel(constExpr).isAtLeast(LanguageLevel.JDK_20_PREVIEW) ||
JavaPsiPatternUtil.isUnconditionalForType(currentElement, mySelectorType)) &&
JavaPsiPatternUtil.dominates(currentElement, constExpr.getType())) {
if (JavaPsiPatternUtil.dominatesOverConstant(currentElement, constExpr.getType())) {
result.put(nextElement, current);
}
}
else if (isNullType(nextElement) && JavaPsiPatternUtil.isUnconditionalForType(currentElement, mySelectorType)
&& PsiUtil.getLanguageLevel(nextElement).isLessThan(LanguageLevel.JDK_20_PREVIEW)) {
result.put(nextElement, current);
}
else if (JavaPsiPatternUtil.dominates(currentElement, nextElement)) {
result.put(nextElement, current);
}

View File

@@ -4,6 +4,7 @@ package com.intellij.psi.util;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
@@ -331,10 +332,14 @@ public final class JavaPsiPatternUtil {
/**
* 14.11.1 Switch Blocks
* @param overWhom - type of constant
*/
@Contract(value = "_,null -> false", pure = true)
public static boolean dominates(@NotNull PsiCaseLabelElement who, @Nullable PsiType overWhom) {
public static boolean dominatesOverConstant(@NotNull PsiCaseLabelElement who, @Nullable PsiType overWhom) {
if (overWhom == null) return false;
if (PsiUtil.getLanguageLevel(who) != LanguageLevel.JDK_20_PREVIEW){
who = findUnconditionalPattern(who);
}
PsiType whoType = TypeConversionUtil.erasure(getPatternType(who));
if (whoType == null) return false;
PsiType overWhomType = null;

View File

@@ -213,7 +213,7 @@ class Main {
}
str = switch (ii) {
case Integer in when in != null -> "";
case <error descr="Label is dominated by a preceding case label 'Integer in when in != null'">1</error> -> "";
case 1 -> "";
default -> "";
};
switch (d) {
@@ -230,10 +230,10 @@ class Main {
// If the type of the selector expression is an enum type E
String str;
switch (d) {
switch (<error descr="'switch' statement does not cover all possible input values">d</error>) {
case Day dd when dd != null:
System.out.println("ok");
case <error descr="Label is dominated by a preceding case label 'Day dd when dd != null'">MONDAY</error>:
case MONDAY:
System.out.println("mon");
};
switch (<error descr="'switch' statement does not cover all possible input values">d</error>) {

View File

@@ -63,5 +63,34 @@ class X {
}
}
void dd6(String str) {
switch (str) {
case String i when i.length() == 2 -> System.out.println(2);
case String i -> System.out.println(2);
}
}
void dd7(String str) {
switch (str) {
case String i -> System.out.println(2);
case <error descr="Label is dominated by a preceding case label 'String i'">String i when i.length() == 2</error> -> System.out.println(2);
}
}
int testC(String str) {
switch (str) {
case String s when s.isEmpty()==true: return 1;
case "": return -1;
default: return 0;
}
}
int testC2(String str) {
switch (str) {
case String s: return 1;
case <error descr="Label is dominated by a preceding case label 'String s'">""</error>: return -1;
}
}
native static boolean predicate();
}

View File

@@ -35,7 +35,7 @@ class Dominance {
switch (integer) {
case Integer i when i > 0 -> {
}
case <error descr="Label is dominated by a preceding case label 'Integer i when i > 0'">1</error> -> {
case 1 -> {
}
default -> {
}

View File

@@ -216,8 +216,8 @@ class Main {
}
str = switch (ii) {
case Integer in when in != null -> "";
case <error descr="Label is dominated by a preceding case label 'Integer in when in != null'">1</error> -> "";
default -> "";
case 1 -> "";
default -> "";
};
switch (d) {
case Day dd when true:
@@ -235,10 +235,10 @@ class Main {
// If the type of the selector expression is an enum type E
String str;
switch (d) {
switch (<error descr="'switch' statement does not cover all possible input values">d</error>) {
case Day dd when dd != null:
System.out.println("ok");
case <error descr="Label is dominated by a preceding case label 'Day dd when dd != null'">MONDAY</error>:
case MONDAY:
System.out.println("mon");
}
switch (<error descr="'switch' statement does not cover all possible input values">d</error>) {