diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 87a287b337cf..ebd0ecbb6a75 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -848,13 +848,30 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { startElement(switchStmt); PsiExpression caseExpression = switchStmt.getExpression(); Set enumValues = null; - if (caseExpression != null /*&& !(caseExpression instanceof PsiReferenceExpression)*/) { - caseExpression.accept(this); + DfaVariableValue expressionValue = null; + if (caseExpression != null) { + PsiType targetType = caseExpression.getType(); + PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(targetType); + if (unboxedType != null) { + targetType = unboxedType; + } + expressionValue = getFactory().getVarFactory().createVariableValue(new DfaVariableSource() { + @Override + public boolean isStable() { + return true; + } - generateBoxingUnboxingInstructionFor(caseExpression, PsiType.INT); - final PsiClass psiClass = PsiUtil.resolveClassInType(caseExpression.getType()); + @Override + public String toString() { + return "switch$var"; + } + }, targetType); + addInstruction(new PushInstruction(expressionValue, null, true)); + caseExpression.accept(this); + generateBoxingUnboxingInstructionFor(caseExpression, targetType); + final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(targetType); if (psiClass != null) { - addInstruction(new DereferenceInstruction(caseExpression)); + addInstruction(new CheckNotNullInstruction(NullabilityProblemKind.fieldAccessNPE.problem(caseExpression))); if (psiClass.isEnum()) { enumValues = new HashSet<>(); for (PsiField f : psiClass.getFields()) { @@ -863,10 +880,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } } } - } else { - addInstruction(new PopInstruction()); } - + addInstruction(new AssignInstruction(null, null)); + addInstruction(new PopInstruction()); } PsiCodeBlock body = switchStmt.getBody(); @@ -894,12 +910,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { if (alwaysTrue) { addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null)); } - else if (caseValue != null && - caseExpression instanceof PsiReferenceExpression && - ((PsiReferenceExpression)caseExpression).getQualifierExpression() == null) { - - addInstruction(new PushInstruction(myFactory.createValue(caseExpression), caseExpression)); - generateBoxingUnboxingInstructionFor(caseExpression, PsiType.INT); + else if (caseValue != null && expressionValue != null) { + addInstruction(new PushInstruction(expressionValue, null)); caseValue.accept(this); addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, PsiType.BOOLEAN)); } @@ -908,7 +920,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } addInstruction(new ConditionalGotoInstruction(offset, false, statement)); - } catch (IncorrectOperationException e) { LOG.error(e); @@ -925,6 +936,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { body.accept(this); } + addInstruction(new FlushVariableInstruction(expressionValue)); finishElement(switchStmt); } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/SwitchEnumConstant.java b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchEnumConstant.java index 546282552095..ac6bde9512ef 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/SwitchEnumConstant.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchEnumConstant.java @@ -25,4 +25,20 @@ class InspectionTest { public static String test(@NotNull Object a) { return a.toString(); } + + enum X {A, B, C} + + void testTernary(@Nullable String foo, X x) { + switch (foo == null ? X.A : x) { + case A: + System.out.println(foo.trim()); + break; + case B: + System.out.println(foo.trim()); + break; + case C: + System.out.println(foo.trim()); + break; + } + } } \ No newline at end of file