mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
XDebugProcess — pass suspend context to resume methods
This commit is contained in:
@@ -30,6 +30,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointType
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
|
||||
import com.intellij.xdebugger.frame.XSuspendContext
|
||||
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.debugger.connection.VmConnection
|
||||
@@ -118,25 +119,28 @@ abstract class DebugProcessImpl<C : VmConnection<*>>(session: XDebugSession,
|
||||
|
||||
override final fun isValuesCustomSorted() = true
|
||||
|
||||
override final fun startStepOver() {
|
||||
val vm = activeOrMainVm!!
|
||||
override final fun startStepOver(context: XSuspendContext?) {
|
||||
val vm = context.vm
|
||||
updateLastCallFrame(vm)
|
||||
continueVm(vm, StepAction.OVER)
|
||||
}
|
||||
|
||||
val XSuspendContext?.vm: Vm
|
||||
get() = (this as? SuspendContextView)?.activeExecutionStack?.suspendContext?.vm ?: mainVm!!
|
||||
|
||||
override final fun startForceStepInto() {
|
||||
isForceStep = true
|
||||
startStepInto()
|
||||
}
|
||||
|
||||
override final fun startStepInto() {
|
||||
val vm = activeOrMainVm!!
|
||||
override final fun startStepInto(context: XSuspendContext?) {
|
||||
val vm = context.vm
|
||||
updateLastCallFrame(vm)
|
||||
continueVm(vm, if (vm.captureAsyncStackTraces) StepAction.IN_ASYNC else StepAction.IN)
|
||||
}
|
||||
|
||||
override final fun startStepOut() {
|
||||
val vm = activeOrMainVm!!
|
||||
override final fun startStepOut(context: XSuspendContext?) {
|
||||
val vm = context.vm
|
||||
if (isVmStepOutCorrect()) {
|
||||
lastCallFrame = null
|
||||
}
|
||||
@@ -149,10 +153,8 @@ abstract class DebugProcessImpl<C : VmConnection<*>>(session: XDebugSession,
|
||||
// some VM (firefox for example) doesn't implement step out correctly, so, we need to fix it
|
||||
protected open fun isVmStepOutCorrect() = true
|
||||
|
||||
@Deprecated("Pass vm explicitly", ReplaceWith("resume(vm!!)"))
|
||||
override fun resume() {
|
||||
@Suppress("DEPRECATION")
|
||||
continueVm(activeOrMainVm!!, StepAction.CONTINUE)
|
||||
override fun resume(context: XSuspendContext?) {
|
||||
continueVm(context.vm, StepAction.CONTINUE)
|
||||
}
|
||||
|
||||
open fun resume(vm: Vm) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
|
||||
import com.intellij.xdebugger.frame.XStackFrame;
|
||||
import com.intellij.xdebugger.frame.XSuspendContext;
|
||||
import com.intellij.xdebugger.frame.XValueMarkerProvider;
|
||||
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
|
||||
import com.intellij.xdebugger.ui.XDebugTabLayouter;
|
||||
@@ -92,7 +93,13 @@ public abstract class XDebugProcess {
|
||||
* when next line in current method/function is reached.
|
||||
* Do not call this method directly. Use {@link XDebugSession#stepOver} instead
|
||||
*/
|
||||
public abstract void startStepOver();
|
||||
public void startStepOver() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void startStepOver(@Nullable XSuspendContext context) {
|
||||
startStepOver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Steps into suppressed call
|
||||
@@ -104,19 +111,36 @@ public abstract class XDebugProcess {
|
||||
public void startForceStepInto(){
|
||||
startStepInto();
|
||||
}
|
||||
|
||||
public void startForceStepInto(@Nullable XSuspendContext context) {
|
||||
startForceStepInto();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume execution and call {@link XDebugSession#positionReached}
|
||||
* when next line is reached.
|
||||
* Do not call this method directly. Use {@link XDebugSession#stepInto} instead
|
||||
*/
|
||||
public abstract void startStepInto();
|
||||
public void startStepInto() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void startStepInto(@Nullable XSuspendContext context) {
|
||||
startStepInto();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume execution and call {@link XDebugSession#positionReached}
|
||||
* after returning from current method/function.
|
||||
* Do not call this method directly. Use {@link XDebugSession#stepOut} instead
|
||||
*/
|
||||
public abstract void startStepOut();
|
||||
public void startStepOut() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void startStepOut(@Nullable XSuspendContext context) {
|
||||
startStepOut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement {@link com.intellij.xdebugger.stepping.XSmartStepIntoHandler} and return its instance from this method to enable Smart Step Into action
|
||||
@@ -145,7 +169,13 @@ public abstract class XDebugProcess {
|
||||
* Resume execution.
|
||||
* Do not call this method directly. Use {@link XDebugSession#resume} instead
|
||||
*/
|
||||
public abstract void resume();
|
||||
public void resume() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void resume(@Nullable XSuspendContext context) {
|
||||
resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume execution and call {@link XDebugSession#positionReached(com.intellij.xdebugger.frame.XSuspendContext)}
|
||||
@@ -153,7 +183,13 @@ public abstract class XDebugProcess {
|
||||
* Do not call this method directly. Use {@link XDebugSession#runToPosition} instead
|
||||
* @param position position in source code
|
||||
*/
|
||||
public abstract void runToPosition(@NotNull XSourcePosition position);
|
||||
public void runToPosition(@NotNull XSourcePosition position) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) {
|
||||
runToPosition(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is it is possible to perform commands such as resume, step etc. And notify user if necessary
|
||||
|
||||
+10
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -16,7 +16,9 @@
|
||||
package com.intellij.xdebugger.stepping;
|
||||
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.intellij.xdebugger.frame.XSuspendContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,7 +42,13 @@ public abstract class XSmartStepIntoHandler<Variant extends XSmartStepIntoVarian
|
||||
* when <code>variant</code> function/method is reached
|
||||
* @param variant selected variant
|
||||
*/
|
||||
public abstract void startStepInto(@NotNull Variant variant);
|
||||
public void startStepInto(@NotNull Variant variant) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public void startStepInto(@NotNull Variant variant, @Nullable XSuspendContext context) {
|
||||
startStepInto(variant);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return title for popup which will be shown to select method/function
|
||||
|
||||
@@ -476,24 +476,21 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
if (ignoreBreakpoints) {
|
||||
disableBreakpoints();
|
||||
}
|
||||
doResume();
|
||||
myDebugProcess.startStepOver();
|
||||
myDebugProcess.startStepOver(doResume());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stepInto() {
|
||||
if (!myDebugProcess.checkCanPerformCommands()) return;
|
||||
|
||||
doResume();
|
||||
myDebugProcess.startStepInto();
|
||||
myDebugProcess.startStepInto(doResume());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stepOut() {
|
||||
if (!myDebugProcess.checkCanPerformCommands()) return;
|
||||
|
||||
doResume();
|
||||
myDebugProcess.startStepOut();
|
||||
myDebugProcess.startStepOut(doResume());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -508,8 +505,7 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
public void forceStepInto() {
|
||||
if (!myDebugProcess.checkCanPerformCommands()) return;
|
||||
|
||||
doResume();
|
||||
myDebugProcess.startForceStepInto();
|
||||
myDebugProcess.startForceStepInto(doResume());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -519,8 +515,7 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
if (ignoreBreakpoints) {
|
||||
disableBreakpoints();
|
||||
}
|
||||
doResume();
|
||||
myDebugProcess.runToPosition(position);
|
||||
myDebugProcess.runToPosition(position, doResume());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -545,14 +540,17 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
public void resume() {
|
||||
if (!myDebugProcess.checkCanPerformCommands()) return;
|
||||
|
||||
doResume();
|
||||
myDebugProcess.resume();
|
||||
myDebugProcess.resume(doResume());
|
||||
}
|
||||
|
||||
public void doResume() {
|
||||
if (!myPaused.getAndSet(false)) return;
|
||||
@Nullable
|
||||
private XSuspendContext doResume() {
|
||||
if (!myPaused.getAndSet(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
myDispatcher.getMulticaster().beforeSessionResume();
|
||||
XSuspendContext context = mySuspendContext;
|
||||
mySuspendContext = null;
|
||||
myCurrentExecutionStack = null;
|
||||
myCurrentStackFrame = null;
|
||||
@@ -565,6 +563,7 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
}
|
||||
});
|
||||
myDispatcher.getMulticaster().sessionResumed();
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -52,6 +52,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointType;
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
|
||||
import com.intellij.xdebugger.frame.XSuspendContext;
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList;
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
||||
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
|
||||
@@ -104,7 +105,6 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
private PyPositionConverter myPositionConverter;
|
||||
private final XSmartStepIntoHandler<?> mySmartStepIntoHandler;
|
||||
private boolean myWaitingForConnection = false;
|
||||
private PyStackFrame myStackFrameBeforeResume;
|
||||
private PyStackFrame myConsoleContextFrame = null;
|
||||
private PyReferrersLoader myReferrersProvider;
|
||||
|
||||
@@ -158,18 +158,6 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
detachDebuggedProcess();
|
||||
}
|
||||
});
|
||||
|
||||
session.addSessionListener(new XDebugSessionAdapter() {
|
||||
@Override
|
||||
public void beforeSessionResume() {
|
||||
if (session.getCurrentStackFrame() instanceof PyStackFrame) {
|
||||
myStackFrameBeforeResume = (PyStackFrame)session.getCurrentStackFrame();
|
||||
}
|
||||
else {
|
||||
myStackFrameBeforeResume = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MultiProcessDebugger createMultiprocessDebugger(ServerSocket serverSocket) {
|
||||
@@ -384,24 +372,24 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startStepOver() {
|
||||
passToCurrentThread(ResumeOrStepCommand.Mode.STEP_OVER);
|
||||
public void startStepOver(@Nullable XSuspendContext context) {
|
||||
passToCurrentThread(context, ResumeOrStepCommand.Mode.STEP_OVER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startStepInto() {
|
||||
passToCurrentThread(ResumeOrStepCommand.Mode.STEP_INTO);
|
||||
public void startStepInto(@Nullable XSuspendContext context) {
|
||||
passToCurrentThread(context, ResumeOrStepCommand.Mode.STEP_INTO);
|
||||
}
|
||||
|
||||
public void startStepIntoMyCode() {
|
||||
public void startStepIntoMyCode(@Nullable XSuspendContext context) {
|
||||
if (!checkCanPerformCommands()) return;
|
||||
getSession().sessionResumed();
|
||||
passToCurrentThread(ResumeOrStepCommand.Mode.STEP_INTO_MY_CODE);
|
||||
passToCurrentThread(context, ResumeOrStepCommand.Mode.STEP_INTO_MY_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startStepOut() {
|
||||
passToCurrentThread(ResumeOrStepCommand.Mode.STEP_OUT);
|
||||
public void startStepOut(@Nullable XSuspendContext context) {
|
||||
passToCurrentThread(context, ResumeOrStepCommand.Mode.STEP_OUT);
|
||||
}
|
||||
|
||||
public void startSmartStepInto(String functionName) {
|
||||
@@ -439,10 +427,10 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
}
|
||||
|
||||
private void passToCurrentThread(final ResumeOrStepCommand.Mode mode) {
|
||||
private void passToCurrentThread(@Nullable XSuspendContext context, final ResumeOrStepCommand.Mode mode) {
|
||||
dropFrameCaches();
|
||||
if (isConnected()) {
|
||||
String threadId = threadIdBeforeResumeOrStep();
|
||||
String threadId = threadIdBeforeResumeOrStep(context);
|
||||
|
||||
for (PyThreadInfo suspendedThread : mySuspendedThreads) {
|
||||
if (threadId == null || threadId.equals(suspendedThread.getId())) {
|
||||
@@ -454,13 +442,13 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String threadIdBeforeResumeOrStep() {
|
||||
String threadId = null;
|
||||
if (myStackFrameBeforeResume != null) {
|
||||
threadId = myStackFrameBeforeResume.getThreadId();
|
||||
private static String threadIdBeforeResumeOrStep(@Nullable XSuspendContext context) {
|
||||
if (context instanceof PySuspendContext) {
|
||||
return ((PySuspendContext)context).getActiveExecutionStack().getThreadId();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return threadId;
|
||||
}
|
||||
|
||||
protected boolean isConnected() {
|
||||
@@ -486,7 +474,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runToPosition(@NotNull final XSourcePosition position) {
|
||||
public void runToPosition(@NotNull final XSourcePosition position, @Nullable XSuspendContext context) {
|
||||
dropFrameCaches();
|
||||
if (isConnected() && !mySuspendedThreads.isEmpty()) {
|
||||
final PySourcePosition pyPosition = myPositionConverter.convertToPython(position);
|
||||
@@ -509,7 +497,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
myDebugger.setTempBreakpoint(type, pyPosition.getFile(), pyPosition.getLine());
|
||||
|
||||
passToCurrentThread(ResumeOrStepCommand.Mode.RESUME);
|
||||
passToCurrentThread(context, ResumeOrStepCommand.Mode.RESUME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -87,4 +87,8 @@ public class PyExecutionStack extends XExecutionStack {
|
||||
public int hashCode() {
|
||||
return myThreadInfo != null ? myThreadInfo.hashCode() : 0;
|
||||
}
|
||||
|
||||
public String getThreadId() {
|
||||
return myThreadInfo.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -40,7 +40,7 @@ public class PyStepIntoMyCodeAction extends XDebuggerActionBase {
|
||||
@Override
|
||||
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
|
||||
PyDebugProcess debugProcess = (PyDebugProcess)session.getDebugProcess();
|
||||
debugProcess.startStepIntoMyCode();
|
||||
debugProcess.startStepIntoMyCode(debugProcess.getSession().getSuspendContext());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.Collection;
|
||||
|
||||
public class PySuspendContext extends XSuspendContext {
|
||||
|
||||
private final XExecutionStack myActiveStack;
|
||||
private final PyExecutionStack myActiveStack;
|
||||
private PyDebugProcess myDebugProcess;
|
||||
|
||||
public PySuspendContext(@NotNull final PyDebugProcess debugProcess, @NotNull final PyThreadInfo threadInfo) {
|
||||
@@ -33,7 +33,8 @@ public class PySuspendContext extends XSuspendContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public XExecutionStack getActiveExecutionStack() {
|
||||
@NotNull
|
||||
public PyExecutionStack getActiveExecutionStack() {
|
||||
return myActiveStack;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -36,6 +36,7 @@ import com.jetbrains.python.debugger.PyDebugValue;
|
||||
import com.jetbrains.python.debugger.PyDebuggerException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -106,6 +107,7 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask {
|
||||
currentSession.stepInto();
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
protected void stepIntoMyCode() {
|
||||
XDebugSession currentSession = XDebuggerManager.getInstance(getProject()).getCurrentSession();
|
||||
|
||||
@@ -113,7 +115,7 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask {
|
||||
Assert.assertEquals(0, myPausedSemaphore.availablePermits());
|
||||
|
||||
PyDebugProcess debugProcess = (PyDebugProcess)currentSession.getDebugProcess();
|
||||
debugProcess.startStepIntoMyCode();
|
||||
debugProcess.startStepIntoMyCode(currentSession.getSuspendContext());
|
||||
}
|
||||
|
||||
protected void smartStepInto(String funcName) {
|
||||
@@ -317,7 +319,7 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask {
|
||||
}
|
||||
finally {
|
||||
doFinally();
|
||||
|
||||
|
||||
clearAllBreakpoints();
|
||||
|
||||
setProcessCanTerminate(true);
|
||||
|
||||
Reference in New Issue
Block a user