blob: 96f2ed9350f9f8d63b162ad289fc83776bbedc3f [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.controlFlow;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
public class ReturnInstruction extends GoToInstruction {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ReturnInstruction");
private final ControlFlowStack myStack;
private CallInstruction myCallInstruction;
private boolean myRethrowFromFinally = false;
public ReturnInstruction(int offset, @NotNull ControlFlowStack stack, CallInstruction callInstruction) {
super(offset, Role.END, false);
myStack = stack;
myCallInstruction = callInstruction;
}
public String toString() {
return "RETURN FROM " + getProcBegin() + (offset == 0 ? "" : " TO "+offset);
}
public int execute(boolean pushBack) {
synchronized (myStack) {
int jumpTo = -1;
if (myStack.size() != 0) {
jumpTo = myStack.pop(pushBack);
}
if (offset != 0) {
jumpTo = offset;
}
return jumpTo;
}
}
public int[] getPossibleReturnOffsets() {
return offset == 0 ?
new int[]{
getProcBegin() - 5, // call normal
getProcBegin() - 3, // call return
getProcBegin() - 1, // call throw
}
:
new int[]{
offset, // exit from middle of the finally
};
}
public int getProcBegin() {
return myCallInstruction.procBegin;
}
public int getProcEnd() {
return myCallInstruction.procEnd;
}
public void setCallInstruction(CallInstruction callInstruction) {
myCallInstruction = callInstruction;
}
@Override
public int nNext() { return offset == 0 ? 3 : 1; }
@Override
public int getNext(int index, int no) {
if (offset == 0)
switch (no) {
case 0: return getProcBegin() - 5; // call normal
case 1: return getProcBegin() - 3; // call return
case 2: return getProcBegin() - 1; // call throw
default:
LOG.assertTrue (false);
return -1;
}
else
switch (no) {
case 0: return offset; // call normal
default:
LOG.assertTrue (false);
return -1;
}
}
@Override
public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) {
visitor.visitReturnInstruction(this, offset, nextOffset);
}
public ControlFlowStack getStack() {
return myStack;
}
public void setRethrowFromFinally() {
myRethrowFromFinally = true;
}
public boolean isRethrowFromFinally() {
return myRethrowFromFinally;
}
}