update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / dataFlow / InstructionVisitor.java
blobe6978a4cfa58b07d8049d8513034513c97cf4e38
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeInspection.dataFlow;
18 import com.intellij.codeInspection.dataFlow.instructions.*;
19 import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue;
20 import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
21 import com.intellij.codeInspection.dataFlow.value.DfaValue;
22 import com.intellij.psi.PsiExpression;
24 import java.util.ArrayList;
26 /**
27 * @author peter
29 public abstract class InstructionVisitor {
31 public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
32 memState.pop();
33 memState.push(memState.pop());
34 return nextInstruction(instruction, runner, memState);
37 protected static DfaInstructionState[] nextInstruction(Instruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
38 return new DfaInstructionState[]{new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), memState)};
41 public DfaInstructionState[] visitInstanceof(InstanceofInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
42 return visitBinop(instruction, runner, memState);
45 public DfaInstructionState[] visitBinop(BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
46 memState.pop();
47 memState.pop();
48 memState.push(DfaUnknownValue.getInstance());
49 return nextInstruction(instruction, runner, memState);
52 public DfaInstructionState[] visitCheckReturnValue(CheckReturnValueInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
53 memState.pop();
54 return nextInstruction(instruction, runner, memState);
57 public DfaInstructionState[] visitConditionalGoto(ConditionalGotoInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
58 DfaValue cond = memState.pop();
60 DfaValue condTrue;
61 DfaValue condFalse;
63 if (instruction.isNegated()) {
64 condFalse = cond;
65 condTrue = cond.createNegated();
66 } else {
67 condTrue = cond;
68 condFalse = cond.createNegated();
71 if (condTrue == runner.getFactory().getConstFactory().getTrue()) {
72 markBranchReachable(instruction, true);
73 return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(instruction.getOffset()), memState)};
76 if (condFalse == runner.getFactory().getConstFactory().getTrue()) {
77 markBranchReachable(instruction, false);
78 return nextInstruction(instruction, runner, memState);
81 ArrayList<DfaInstructionState> result = new ArrayList<DfaInstructionState>();
83 DfaMemoryState thenState = memState.createCopy();
84 DfaMemoryState elseState = memState.createCopy();
86 if (thenState.applyCondition(condTrue)) {
87 result.add(new DfaInstructionState(runner.getInstruction(instruction.getOffset()), thenState));
88 markBranchReachable(instruction, true);
91 if (elseState.applyCondition(condFalse)) {
92 result.add(new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), elseState));
93 markBranchReachable(instruction, false);
96 return result.toArray(new DfaInstructionState[result.size()]);
99 private static void markBranchReachable(ConditionalGotoInstruction instruction, boolean isTrueBranch) {
100 if (isTrueBranch ^ instruction.isNegated()) {
101 instruction.setTrueReachable();
103 else {
104 instruction.setFalseReachable();
109 public DfaInstructionState[] visitEmptyStack(EmptyStackInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
110 memState.emptyStack();
111 return nextInstruction(instruction, runner, memState);
114 public DfaInstructionState[] visitFieldReference(FieldReferenceInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
115 memState.pop();
116 return nextInstruction(instruction, runner, memState);
119 public DfaInstructionState[] visitFlushVariable(FlushVariableInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
120 final DfaVariableValue variable = instruction.getVariable();
121 if (variable != null) {
122 memState.flushVariable(variable);
123 } else {
124 memState.flushFields(runner);
126 return nextInstruction(instruction, runner, memState);
129 public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
130 //noinspection UnusedDeclaration
131 for (PsiExpression arg : instruction.getArgs()) {
132 memState.pop();
135 memState.pop(); //qualifier
136 memState.push(DfaUnknownValue.getInstance());
137 return nextInstruction(instruction, runner, memState);
140 public DfaInstructionState[] visitCast(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
141 return visitMethodCall(instruction, runner, memState);
144 public DfaInstructionState[] visitNot(NotInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
145 DfaValue dfaValue = memState.pop();
147 dfaValue = dfaValue.createNegated();
148 memState.push(dfaValue);
149 return nextInstruction(instruction, runner, memState);
152 public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
153 memState.push(instruction.getValue());
154 return nextInstruction(instruction, runner, memState);
157 public DfaInstructionState[] visitTypeCast(TypeCastInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
158 return nextInstruction(instruction, runner, memState);