blob: beadb422e9de8780f44ee2e675e654d2e85b1239 [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.
*/
/*
* Interface DebuggerContextImpl
* @author Jeka
*/
package com.intellij.debugger.impl;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.Nullable;
public final class DebuggerContextImpl implements DebuggerContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextImpl");
public static final DebuggerContextImpl EMPTY_CONTEXT = createDebuggerContext((DebuggerSession)null, null, null, null);
private boolean myInitialized;
@Nullable
private final DebuggerSession myDebuggerSession;
private final DebugProcessImpl myDebugProcess;
private final SuspendContextImpl mySuspendContext;
private final ThreadReferenceProxyImpl myThreadProxy;
private StackFrameProxyImpl myFrameProxy;
private SourcePosition mySourcePosition;
private PsiElement myContextElement;
private DebuggerContextImpl(@Nullable DebuggerSession session,
@Nullable DebugProcessImpl debugProcess,
@Nullable SuspendContextImpl context,
ThreadReferenceProxyImpl threadProxy,
StackFrameProxyImpl frameProxy,
SourcePosition position,
PsiElement contextElement,
boolean initialized) {
LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy());
LOG.assertTrue(debugProcess != null || frameProxy == null && threadProxy == null);
myDebuggerSession = session;
myThreadProxy = threadProxy;
myFrameProxy = frameProxy;
myDebugProcess = debugProcess;
mySourcePosition = position;
mySuspendContext = context;
myContextElement = contextElement;
myInitialized = initialized;
}
@Nullable
public DebuggerSession getDebuggerSession() {
return myDebuggerSession;
}
@Nullable
@Override
public DebugProcessImpl getDebugProcess() {
return myDebugProcess;
}
public ThreadReferenceProxyImpl getThreadProxy() {
return myThreadProxy;
}
@Override
public SuspendContextImpl getSuspendContext() {
return mySuspendContext;
}
@Override
public Project getProject() {
return myDebugProcess != null ? myDebugProcess.getProject() : null;
}
@Override
@Nullable
public StackFrameProxyImpl getFrameProxy() {
LOG.assertTrue(myInitialized);
return myFrameProxy;
}
public SourcePosition getSourcePosition() {
LOG.assertTrue(myInitialized);
return mySourcePosition;
}
public PsiElement getContextElement() {
LOG.assertTrue(myInitialized);
PsiElement contextElement = myContextElement;
if(contextElement != null && !contextElement.isValid()) {
myContextElement = ContextUtil.getContextElement(mySourcePosition);
}
return myContextElement;
}
public EvaluationContextImpl createEvaluationContext(Value thisObject) {
DebuggerManagerThreadImpl.assertIsManagerThread();
return new EvaluationContextImpl(getSuspendContext(), getFrameProxy(), thisObject);
}
@Nullable
public EvaluationContextImpl createEvaluationContext() {
DebuggerManagerThreadImpl.assertIsManagerThread();
StackFrameProxyImpl frameProxy = getFrameProxy();
ObjectReference objectReference;
try {
objectReference = frameProxy != null ? frameProxy.thisObject() : null;
}
catch (EvaluateException e) {
LOG.info(e);
objectReference = null;
}
SuspendContextImpl context = getSuspendContext();
return context != null ? new EvaluationContextImpl(context, frameProxy, objectReference) : null;
}
public static DebuggerContextImpl createDebuggerContext(@Nullable DebuggerSession session,
@Nullable SuspendContextImpl context,
ThreadReferenceProxyImpl threadProxy,
StackFrameProxyImpl frameProxy) {
LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy());
LOG.assertTrue(session == null || session.getProcess() != null);
return new DebuggerContextImpl(session, session != null ? session.getProcess() : null, context, threadProxy, frameProxy, null, null, context == null);
}
public void initCaches() {
if(myInitialized) return;
myInitialized = true;
if(myFrameProxy == null) {
if(myThreadProxy != null) {
try {
myFrameProxy = myThreadProxy.frameCount() > 0 ? myThreadProxy.frame(0) : null;
}
catch (EvaluateException ignored) {
}
}
}
if (myFrameProxy != null) {
PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() {
@Override
public void run() {
if (mySourcePosition == null) {
mySourcePosition = ContextUtil.getSourcePosition(DebuggerContextImpl.this);
}
myContextElement = ContextUtil.getContextElement(mySourcePosition);
}
});
}
}
public void setPositionCache(SourcePosition position) {
//LOG.assertTrue(!myInitialized, "Debugger context is initialized. Cannot change caches");
mySourcePosition = position;
}
public boolean isInitialised() {
return myInitialized;
}
public boolean isEvaluationPossible() {
final DebugProcessImpl debugProcess = getDebugProcess();
return debugProcess != null && debugProcess.getSuspendManager().getPausedContext() != null;
}
}