void (@NotNull PsiElement statement, @Nullable PsiExpression conditionExpression, final PsiElement thenBranch, final PsiElement elseBranch) { if (thenBranch == null) { myStartStatementStack.pushStatement(statement, false); } else { myStartStatementStack.pushStatement(thenBranch, true); } if (elseBranch == null) { myEndStatementStack.pushStatement(statement, false); } else { myEndStatementStack.pushStatement(elseBranch, true); } myEndJumpRoles.push(elseBranch == null ? BranchingInstruction.Role.END : BranchingInstruction.Role.ELSE); myStartJumpRoles.push(thenBranch == null ? BranchingInstruction.Role.END : BranchingInstruction.Role.THEN); if (conditionExpression != null) { conditionExpression.accept(this); } boolean thenReachable = true; boolean generateConditionalJump = true; /* * if() statement generated instructions outline: * 'if (C) { A } [ else { B } ]' : * generate (C) * cond_goto else * generate (A) * [ goto end ] * :else * [ generate (B) ] * :end */ if (myOptions.shouldEvaluateConstantIfCondition()) { final Object value = myConstantEvaluationHelper.computeConstantExpression(conditionExpression); if (value instanceof Boolean) { thenReachable = ((Boolean)value).booleanValue(); generateConditionalJump = false; myCurrentFlow.setConstantConditionOccurred(true); } } if (generateConditionalJump || !thenReachable) { BranchingInstruction.Role role = elseBranch == null ? BranchingInstruction.Role.END : BranchingInstruction.Role.ELSE; Instruction instruction = generateConditionalJump ? new ConditionalGoToInstruction(0, role, conditionExpression) : new GoToInstruction(0, role); myCurrentFlow.addInstruction(instruction); if (elseBranch == null) { addElementOffsetLater(statement, false); } else { addElementOffsetLater(elseBranch, true); } } myStartJumpRoles.pop(); myEndJumpRoles.pop(); myStartStatementStack.popStatement(); myEndStatementStack.popStatement(); if (thenBranch != null) { thenBranch.accept(this); } if (elseBranch != null) { Instruction instruction = new GoToInstruction(0); myCurrentFlow.addInstruction(instruction); addElementOffsetLater(statement, false); elseBranch.accept(this); } }