2 * Created by IntelliJ IDEA.
6 * To change template for new class use
7 * Code Style | Class Templates options (Tools | IDE Options).
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
{
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();
39 condTrue
= cond
.createNegated();
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()]);
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
) {
87 public String
toString() {
88 return "cond_goto " + myOffset
;
91 public int getOffset() {
95 public void setOffset(int offset
) {