package jetbrains.mps.debugger.java.api.state.proxy;
/*Generated by MPS */
import jetbrains.mps.debug.api.programState.IStackFrame;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.debug.api.programState.IWatchable;
import java.util.List;
import jetbrains.mps.debugger.java.api.state.watchables.JavaLocalVariable;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import com.sun.jdi.AbsentInformationException;
import jetbrains.mps.util.Pair;
import com.sun.jdi.StackFrame;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.ide.ThreadUtils;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.ObjectReference;
import jetbrains.mps.debugger.java.api.state.watchables.JavaThisObject;
import jetbrains.mps.debugger.java.api.state.watchables.JavaStaticContext;
import jetbrains.mps.debug.api.programState.IValue;
import jetbrains.mps.debugger.java.api.state.customViewers.CustomViewersManager;
public class JavaStackFrame extends ProxyForJava implements IStackFrame {
private static final Logger LOG = LogManager.getLogger(JavaStackFrame.class);
private final int myIndex;
private final JavaLocation myLocation;
private final JavaThread myThread;
private IWatchable myContextWatchable;
private final List<JavaLocalVariable> myVariables = ListSequence.fromList(new ArrayList<JavaLocalVariable>());
private boolean myInitialized;
public JavaStackFrame(JavaThread threadReference, int i) throws AbsentInformationException {
super(new Pair<JavaThread, Integer>(threadReference, i));
myIndex = i;
myThread = threadReference;
StackFrame stackFrame = getStackFrame();
if (stackFrame != null) {
myLocation = new JavaLocation(stackFrame.location());
} else {
myLocation = null;
}
}
@Override
@Nullable
public JavaLocation getLocation() {
return myLocation;
}
@Override
public JavaThread getThread() {
return myThread;
}
@Nullable
public StackFrame getStackFrame() {
assert !(ThreadUtils.isInEDT());
try {
return getFrame();
} catch (Throwable t) {
LOG.error(null, t);
return null;
}
}
@Override
public synchronized List<IWatchable> getVisibleWatchables() {
List<IWatchable> watchables = ListSequence.fromList(new ArrayList<IWatchable>());
ListSequence.fromList(watchables).addSequence(ListSequence.fromList(myVariables));
if (myContextWatchable != null) {
ListSequence.fromList(watchables).addElement(myContextWatchable);
}
return watchables;
}
public synchronized List<JavaLocalVariable> getVisibleVariables() {
return myVariables;
}
public synchronized IWatchable getContextWatchable() {
return myContextWatchable;
}
public synchronized void initializeWatchables() {
if (myInitialized) {
return;
}
myInitialized = true;
try {
ListSequence.fromList(myVariables).addSequence(ListSequence.fromList(fetchVisibleVariables()));
myContextWatchable = fetchContextWatchable();
} catch (IncompatibleThreadStateException ignore) {
} catch (AbsentInformationException ignore) {
}
}
private List<JavaLocalVariable> fetchVisibleVariables() throws IncompatibleThreadStateException, AbsentInformationException {
assert !(ThreadUtils.isInEDT());
StackFrame stackFrame = getFrame();
List<JavaLocalVariable> result = new ArrayList<JavaLocalVariable>();
if (stackFrame != null) {
for (LocalVariable variable : stackFrame.visibleVariables()) {
ListSequence.fromList(result).addElement(new JavaLocalVariable(variable, this, myThread.getThread()));
}
}
return result;
}
private IWatchable fetchContextWatchable() throws IncompatibleThreadStateException {
assert !(ThreadUtils.isInEDT());
StackFrame stackFrame = getFrame();
if (stackFrame != null) {
ObjectReference thisObject = stackFrame.thisObject();
if (thisObject != null) {
return new JavaThisObject(thisObject, this, myThread.getThread());
} else {
return new JavaStaticContext(stackFrame.location().declaringType(), myThread.getThread());
}
}
return null;
}
private StackFrame getFrame() throws IncompatibleThreadStateException {
return myThread.getThread().frame(myIndex);
}
@Override
public IValue getValue(IWatchable watchable) {
assert !(ThreadUtils.isInEDT());
try {
if (watchable instanceof JavaLocalVariable) {
JavaLocalVariable localVariable = (JavaLocalVariable) watchable;
return CustomViewersManager.getInstance().fromJdi(getFrame().getValue(localVariable.getLocalVariable()), myThread.getThread());
}
} catch (IncompatibleThreadStateException e) {
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
JavaStackFrame that = (JavaStackFrame) o;
if (myIndex != that.myIndex) {
return false;
}
if ((myLocation != null ? !(myLocation.equals(that.myLocation)) : that.myLocation != null)) {
return false;
}
if ((myThread != null ? !(myThread.equals(that.myThread)) : that.myThread != null)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = 0;
result = 31 * result + myIndex;
result = 31 * result + ((myLocation != null ? (myLocation).hashCode() : 0));
result = 31 * result + ((myThread != null ? (myThread).hashCode() : 0));
return result;
}
}