InstructionVisitor in dfa
[fedora-idea.git] / inspections / impl / com / intellij / codeInspection / dataFlow / instructions / ConditionalGotoInstruction.java
blob63f80e768552e5b7ba495326a39fa27c119935f3
1 /*
2 * Created by IntelliJ IDEA.
3 * User: max
4 * Date: Jan 26, 2002
5 * Time: 10:48:29 PM
6 * To change template for new class use
7 * Code Style | Class Templates options (Tools | IDE Options).
8 */
9 package com.intellij.codeInspection.dataFlow.instructions;
12 import com.intellij.codeInspection.dataFlow.DataFlowRunner;
13 import com.intellij.codeInspection.dataFlow.DfaInstructionState;
14 import com.intellij.codeInspection.dataFlow.DfaMemoryState;
15 import com.intellij.codeInspection.dataFlow.InstructionVisitor;
16 import com.intellij.codeInspection.dataFlow.value.DfaValue;
17 import com.intellij.psi.PsiElement;
19 import java.util.ArrayList;
21 public class ConditionalGotoInstruction extends BranchingInstruction {
22 private int myOffset;
23 private final boolean myIsNegated;
25 public ConditionalGotoInstruction(int myOffset, boolean isNegated, PsiElement psiAnchor) {
26 this.myOffset = myOffset;
27 myIsNegated = isNegated;
28 setPsiAnchor(psiAnchor);
31 public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) {
32 DfaValue cond = memState.pop();
34 DfaValue condTrue;
35 DfaValue condFalse;
37 if (myIsNegated) {
38 condFalse = cond;
39 condTrue = cond.createNegated();
40 } else {
41 condTrue = cond;
42 condFalse = cond.createNegated();
45 if (condTrue == runner.getFactory().getConstFactory().getTrue()) {
46 markBranchReachable(true);
47 return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getOffset()), memState)};
50 if (condFalse == runner.getFactory().getConstFactory().getTrue()) {
51 markBranchReachable(false);
52 return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)};
55 ArrayList<DfaInstructionState> result = new ArrayList<DfaInstructionState>();
57 DfaMemoryState thenState = memState.createCopy();
58 DfaMemoryState elseState = memState.createCopy();
60 if (thenState.applyCondition(condTrue)) {
61 result.add(new DfaInstructionState(runner.getInstruction(getOffset()), thenState));
62 markBranchReachable(true);
65 if (elseState.applyCondition(condFalse)) {
66 result.add(new DfaInstructionState(runner.getInstruction(getIndex() + 1), elseState));
67 markBranchReachable(false);
70 return result.toArray(new DfaInstructionState[result.size()]);
73 @Override
74 public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
75 return visitor.visitConditionalGoto(this, runner, stateBefore);
78 private void markBranchReachable(boolean isTrueBranch) {
79 if (isTrueBranch ^ myIsNegated) {
80 setTrueReachable();
82 else {
83 setFalseReachable();
87 public String toString() {
88 return "cond_goto " + myOffset;
91 public int getOffset() {
92 return myOffset;
95 public void setOffset(int offset) {
96 myOffset = offset;