void (@NotNull PsiSwitchBlock switchBlock) { PsiExpression selector = PsiUtil.skipParenthesizedExprDown(switchBlock.getExpression()); DfaVariableValue expressionValue = null; boolean syntheticVar = true; PsiType targetType = null; if (selector != null) { targetType = selector.getType(); DfaValue selectorValue = JavaDfaValueFactory.getExpressionDfaValue(myFactory, selector); if (selectorValue instanceof DfaVariableValue dfaVar && !dfaVar.isFlushableByCalls()) { expressionValue = dfaVar; syntheticVar = false; } selector.accept(this); if (syntheticVar) { expressionValue = createTempVariable(targetType); addInstruction(new SimpleAssignmentInstruction(null, expressionValue)); } addInstruction(new PopInstruction()); } PsiCodeBlock body = switchBlock.getBody(); if (body != null) { PsiStatement[] statements = body.getStatements(); PsiElement defaultLabel = null; for (PsiStatement statement : statements) { if (!(statement instanceof PsiSwitchLabelStatementBase psiLabelStatement)) { continue; } if (psiLabelStatement.isDefaultCase()) { defaultLabel = psiLabelStatement; continue; } try { PsiExpression guard = psiLabelStatement.getGuardExpression(); ControlFlowOffset offset = getStartOffset(statement); ControlFlowOffset targetOffset = guard == null ? offset : new DeferredOffset(); PsiCaseLabelElementList labelElementList = psiLabelStatement.getCaseLabelElementList(); if (labelElementList != null) { for (PsiCaseLabelElement labelElement : labelElementList.getElements()) { if (labelElement instanceof PsiDefaultCaseLabelElement) { defaultLabel = labelElement; continue; } if (labelElement instanceof PsiExpression expr) { boolean enumConstant = expr instanceof PsiReferenceExpression ref && ref.resolve() instanceof PsiEnumConstant; if (expressionValue != null && (enumConstant || PsiUtil.isConstantExpression(expr))) { if (PsiPrimitiveType.getUnboxedType(targetType) == null) { addInstruction(new JvmPushInstruction(expressionValue, null)); expr.accept(this); addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr))); addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE)); } else { addInstruction(new JvmPushInstruction(expressionValue, null)); DeferredOffset condGotoOffset = new DeferredOffset(); addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.NULL)); addInstruction(new JvmPushInstruction(expressionValue, null)); generateBoxingUnboxingInstructionFor(selector, PsiPrimitiveType.getUnboxedType(targetType)); expr.accept(this); addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr))); DeferredOffset gotoOffset = new DeferredOffset(); addInstruction(new GotoInstruction(gotoOffset)); PushValueInstruction pushValInstr = new PushValueInstruction(DfTypes.FALSE, new JavaSwitchLabelTakenAnchor(expr)); addInstruction(pushValInstr); condGotoOffset.setOffset(pushValInstr.getIndex()); ConditionalGotoInstruction exitFromSwitchBranchInstr = new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE); addInstruction(exitFromSwitchBranchInstr); gotoOffset.setOffset(exitFromSwitchBranchInstr.getIndex()); } } else if (expressionValue != null && ExpressionUtils.isNullLiteral(expr)) { addInstruction(new JvmPushInstruction(expressionValue, null)); expr.accept(this); addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr))); addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE)); } else { pushUnknown(); addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE)); } } else if (expressionValue != null && targetType != null) { if (labelElement instanceof PsiPattern pattern) { processPatternInSwitch(pattern, expressionValue, targetType); addInstruction(new ResultOfInstruction(new JavaSwitchLabelTakenAnchor(pattern))); addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE)); } } } } if (guard != null) { DeferredOffset endGuardOffset = new DeferredOffset(); addInstruction(new GotoInstruction(endGuardOffset)); ((DeferredOffset)targetOffset).setOffset(getInstructionCount()); guard.accept(this); addInstruction(new ResultOfInstruction(new JavaSwitchLabelTakenAnchor(guard))); addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE)); endGuardOffset.setOffset(getInstructionCount()); } } catch (IncorrectOperationException e) { LOG.error(e); } } if (defaultLabel != null) { addInstruction(new GotoInstruction(getStartOffset(defaultLabel))); } else if (switchBlock instanceof PsiSwitchExpression) { addInstruction(new ThrowInstruction(myTrapTracker.transferValue("java.lang.IncompatibleClassChangeError"), null)); } else { addInstruction(new GotoInstruction(getEndOffset(body))); } body.accept(this); } if (syntheticVar && expressionValue != null) { addInstruction(new FlushVariableInstruction(expressionValue)); } }