From 8699b0e4ae2f3df44c4ab60573cd49070634c012 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 2 Mar 2016 14:25:57 +0100 Subject: [PATCH] =?UTF-8?q?XDebugProcess=20=E2=80=94=20pass=20suspend=20co?= =?UTF-8?q?ntext=20to=20resume=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debugger-ui/src/DebugProcessImpl.kt | 22 ++++---- .../com/intellij/xdebugger/XDebugProcess.java | 48 ++++++++++++++--- .../stepping/XSmartStepIntoHandler.java | 12 ++++- .../xdebugger/impl/XDebugSessionImpl.java | 27 +++++----- .../python/debugger/PyDebugProcess.java | 52 +++++++------------ .../python/debugger/PyExecutionStack.java | 6 ++- .../debugger/PyStepIntoMyCodeAction.java | 4 +- .../python/debugger/PySuspendContext.java | 5 +- .../env/python/debug/PyBaseDebuggerTask.java | 8 +-- 9 files changed, 112 insertions(+), 72 deletions(-) diff --git a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt index fbcaa9935980..090b5b301951 100644 --- a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt +++ b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt @@ -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>(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>(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) { diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index e1aa69cc08cc..0bd309f8b87c 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -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 diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java index 56b098de99f0..f0643b776c3f 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java @@ -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 XSmartStepIntoHandlervariant 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 diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 0500a4400f83..33fd6d1ddb37 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -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 diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index c43465ba6ef7..c91c0194096e 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -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); } } diff --git a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java index bc47b720471e..573ae7a2c5b5 100644 --- a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java +++ b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java @@ -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(); + } } diff --git a/python/src/com/jetbrains/python/debugger/PyStepIntoMyCodeAction.java b/python/src/com/jetbrains/python/debugger/PyStepIntoMyCodeAction.java index 3366225d4384..36e3a6ce42ed 100644 --- a/python/src/com/jetbrains/python/debugger/PyStepIntoMyCodeAction.java +++ b/python/src/com/jetbrains/python/debugger/PyStepIntoMyCodeAction.java @@ -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()); } }; } diff --git a/python/src/com/jetbrains/python/debugger/PySuspendContext.java b/python/src/com/jetbrains/python/debugger/PySuspendContext.java index 637171016633..a3bcfa77b870 100644 --- a/python/src/com/jetbrains/python/debugger/PySuspendContext.java +++ b/python/src/com/jetbrains/python/debugger/PySuspendContext.java @@ -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; } diff --git a/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java b/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java index 6c6f05240de3..43240606aece 100644 --- a/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java +++ b/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java @@ -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);