diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ClientModeMultiProcessDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ClientModeMultiProcessDebugger.java index a1fd0a18e30e..f8162b35d0b4 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ClientModeMultiProcessDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ClientModeMultiProcessDebugger.java @@ -327,10 +327,10 @@ public class ClientModeMultiProcessDebugger implements ProcessDebugger { } @Override - public void setNextStatement(String threadId, - XSourcePosition sourcePosition, - String functionName, - PyDebugCallback> callback) { + public void setNextStatement(@NotNull String threadId, + @NotNull XSourcePosition sourcePosition, + @Nullable String functionName, + @NotNull PyDebugCallback> callback) { debugger(threadId).setNextStatement(threadId, sourcePosition, functionName, callback); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java index bce29ba6c3ec..79e17ee5983b 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java @@ -362,10 +362,10 @@ public class MultiProcessDebugger implements ProcessDebugger { } @Override - public void setNextStatement(String threadId, - XSourcePosition sourcePosition, - String functionName, - PyDebugCallback> callback) { + public void setNextStatement(@NotNull String threadId, + @NotNull XSourcePosition sourcePosition, + @Nullable String functionName, + @NotNull PyDebugCallback> callback) { debugger(threadId).setNextStatement(threadId, sourcePosition, functionName, callback); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java index 510d899dbdc3..f21f99c9b667 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java @@ -81,10 +81,10 @@ public interface ProcessDebugger { void resumeOrStep(String threadId, ResumeOrStepCommand.Mode mode); - void setNextStatement(String threadId, - XSourcePosition sourcePosition, - String functionName, - PyDebugCallback> callback); + void setNextStatement(@NotNull String threadId, + @NotNull XSourcePosition sourcePosition, + @Nullable String functionName, + @NotNull PyDebugCallback> callback); void setTempBreakpoint(@NotNull String type, @NotNull String file, int line); diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java index 78044dcdc4b2..3ccf5c4bf848 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java @@ -140,9 +140,9 @@ public class ProtocolParser { String[] values = payload.split("\t"); if (values.length > 0) { boolean success = values[0].equals("True"); - String errorMessage = "Error: "; + String errorMessage = "Error"; if (values.length > 1) { - errorMessage += values[1]; + errorMessage = errorMessage + ": " + values[1]; } return new Pair<>(success, errorMessage); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index 3f23ce2ff4ab..36ca95d1a6c0 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -402,10 +402,10 @@ public class RemoteDebugger implements ProcessDebugger { } @Override - public void setNextStatement(String threadId, - XSourcePosition sourcePosition, - String functionName, - PyDebugCallback> callback) { + public void setNextStatement(@NotNull String threadId, + @NotNull XSourcePosition sourcePosition, + @Nullable String functionName, + @NotNull PyDebugCallback> callback) { final SetNextStatementCommand command = new SetNextStatementCommand(this, threadId, sourcePosition, functionName, callback); execute(command); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/SetNextStatementCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/SetNextStatementCommand.java index 87efa4ec177e..82d59cba8f24 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/SetNextStatementCommand.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/SetNextStatementCommand.java @@ -3,17 +3,19 @@ package com.jetbrains.python.debugger.pydev; import com.intellij.openapi.util.Pair; import com.intellij.xdebugger.XSourcePosition; import com.jetbrains.python.debugger.PyDebuggerException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SetNextStatementCommand extends AbstractThreadCommand { private int myLine; - private String myFunctionName; - private final PyDebugCallback> myCallback; + @NotNull private final PyDebugCallback> myCallback; + @Nullable private String myFunctionName; - protected SetNextStatementCommand(RemoteDebugger debugger, - String threadId, - XSourcePosition sourcePosition, - String functionName, - PyDebugCallback> callback) { + protected SetNextStatementCommand(@NotNull RemoteDebugger debugger, + @NotNull String threadId, + @NotNull XSourcePosition sourcePosition, + @Nullable String functionName, + @NotNull PyDebugCallback> callback) { super(debugger, SET_NEXT_STATEMENT, threadId); myLine = sourcePosition.getLine(); myFunctionName = functionName; diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 2bc0079118da..79210a7ee233 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -545,14 +545,14 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } public void startSetNextStatement(@Nullable XSuspendContext context, - XSourcePosition sourcePosition, - PyDebugCallback> callback) { + @NotNull XSourcePosition sourcePosition, + @NotNull PyDebugCallback> callback) { if (!checkCanPerformCommands()) return; dropFrameCaches(); if (isConnected()) { String threadId = threadIdBeforeResumeOrStep(context); for (PyThreadInfo suspendedThread : mySuspendedThreads) { - if (threadId == null || threadId.equals(suspendedThread.getId())) { + if (threadId != null && threadId.equals(suspendedThread.getId())) { myDebugger.setNextStatement(threadId, sourcePosition, getFunctionName(sourcePosition), callback); break; } diff --git a/python/src/com/jetbrains/python/debugger/PySetNextStatementAction.kt b/python/src/com/jetbrains/python/debugger/PySetNextStatementAction.kt index bb18b7d28b38..f62b56c9f596 100644 --- a/python/src/com/jetbrains/python/debugger/PySetNextStatementAction.kt +++ b/python/src/com/jetbrains/python/debugger/PySetNextStatementAction.kt @@ -19,46 +19,47 @@ import com.intellij.codeInsight.hint.HintManager import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.ModalityState import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project import com.intellij.openapi.util.Pair -import com.intellij.util.ui.UIUtil import com.intellij.xdebugger.XDebugSession import com.intellij.xdebugger.impl.DebuggerSupport import com.intellij.xdebugger.impl.XDebuggerUtilImpl -import com.intellij.xdebugger.impl.actions.DebuggerActionHandler import com.intellij.xdebugger.impl.actions.XDebuggerActionBase import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler import com.jetbrains.python.debugger.pydev.PyDebugCallback class PySetNextStatementAction : XDebuggerActionBase(true) { - private val LOG = Logger.getInstance("#com.jetbrains.python.debugger.PySetNextStatementAction") - private val mySetNextStatementActionHandler: XDebuggerSuspendedActionHandler + private val setNextStatementActionHandler: XDebuggerSuspendedActionHandler init { - mySetNextStatementActionHandler = object : XDebuggerSuspendedActionHandler() { + setNextStatementActionHandler = object : XDebuggerSuspendedActionHandler() { override fun perform(session: XDebugSession, dataContext: DataContext) { - val debugProcess = session.debugProcess - if (debugProcess is PyDebugProcess) { - val position = XDebuggerUtilImpl.getCaretPosition(session.project, dataContext) ?: return - val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: FileEditorManager.getInstance(session.project).selectedTextEditor - debugProcess - .startSetNextStatement(debugProcess.getSession().suspendContext, position, object : PyDebugCallback> { - override fun ok(response: Pair) { - if (!response.first && editor != null) { - UIUtil.invokeLaterIfNeeded { + val debugProcess = session.debugProcess as? PyDebugProcess ?: return + val position = XDebuggerUtilImpl.getCaretPosition(session.project, dataContext) ?: return + val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: FileEditorManager.getInstance(session.project).selectedTextEditor + val suspendContext = debugProcess.session.suspendContext + ApplicationManager.getApplication().executeOnPooledThread(Runnable { + debugProcess.startSetNextStatement(suspendContext, position, object : PyDebugCallback> { + override fun ok(response: Pair) { + if (!response.first && editor != null) { + ApplicationManager.getApplication().invokeLater(Runnable { + if (!editor.isDisposed) { editor.caretModel.moveToOffset(position.offset) HintManager.getInstance().showErrorHint(editor, response.second) } - } + }, ModalityState.defaultModalityState()) } + } - override fun error(e: PyDebuggerException) { - LOG.error(e) - } - }) - } + override fun error(e: PyDebuggerException) { + LOG.error(e) + } + }) + }) } override fun isEnabled(project: Project, event: AnActionEvent): Boolean { @@ -67,11 +68,13 @@ class PySetNextStatementAction : XDebuggerActionBase(true) { } } - override fun getHandler(debuggerSupport: DebuggerSupport): DebuggerActionHandler { - return mySetNextStatementActionHandler - } + override fun getHandler(debuggerSupport: DebuggerSupport) = setNextStatementActionHandler override fun isHidden(event: AnActionEvent): Boolean { return !PyDebugSupportUtils.isPythonConfigurationSelected(event.getData(CommonDataKeys.PROJECT)) } + + companion object { + private val LOG = Logger.getInstance("#com.jetbrains.python.debugger.PySetNextStatementAction") + } }