added handling of absent remote files in python remote debug

This commit is contained in:
Dmitry Trofimov
2010-12-10 00:04:50 +03:00
parent c209b5ca66
commit 4f4c14736a
14 changed files with 108 additions and 60 deletions

View File

@@ -25,6 +25,7 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
CMD_CONSOLE_EXEC, \
CMD_ADD_EXCEPTION_BREAK, \
CMD_REMOVE_EXCEPTION_BREAK, \
CMD_LOAD_SOURCE, \
GetGlobalDebugger, \
InternalChangeVariable, \
InternalGetCompletions, \
@@ -633,6 +634,17 @@ class PyDB:
always_exception_set.remove(exc_type)
update_exception_hook()
elif cmd_id == CMD_LOAD_SOURCE:
path = text
try:
print path
f = open(path, 'r')
source = f.read()
print source
self.cmdFactory.makeLoadSourceMessage(seq, source, self)
except:
return self.cmdFactory.makeErrorMessage(seq, GetExceptionTracebackStr())
else:
#I have no idea what this is all about
cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(cmd_id))

View File

@@ -103,7 +103,8 @@ CMD_RELOAD_CODE = 119
CMD_GET_COMPLETIONS = 120
CMD_CONSOLE_EXEC = 121
CMD_ADD_EXCEPTION_BREAK = 122
CMD_REMOVE_EXCEPTION_BREAK = 122
CMD_REMOVE_EXCEPTION_BREAK = 123
CMD_LOAD_SOURCE = 124
CMD_VERSION = 501
CMD_RETURN = 502
CMD_ERROR = 901
@@ -545,6 +546,14 @@ class NetCommandFactory:
except Exception:
return self.makeErrorMessage(seq, GetExceptionTracebackStr())
def makeLoadSourceMessage(self, seq, source, dbg=None):
try:
net = NetCommand(str(CMD_LOAD_SOURCE), seq, '%s' % source)
if dbg:
dbg.writer.addCommand(net)
except:
return self.makeErrorMessage(0, GetExceptionTracebackStr())
INTERNAL_TERMINATE_THREAD = 1
INTERNAL_SUSPEND_THREAD = 2

View File

@@ -2,7 +2,6 @@ package com.jetbrains.python.debugger.pydev;
import com.jetbrains.python.debugger.PyDebuggerException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class AbstractCommand {
@@ -27,6 +26,7 @@ public abstract class AbstractCommand {
public static final int CONSOLE_EXEC = 121;
public static final int ADD_EXCEPTION_BREAKPOINT = 122;
public static final int REMOVE_EXCEPTION_BREAKPOINT = 123;
public static final int LOAD_SOURCE = 124;
public static final int VERSION = 501;
public static final String NEW_LINE_CHAR = "@_@NEW_LINE_CHAR@_@";
public static final String TAB_CHAR = "@_@TAB_CHAR@_@";
@@ -39,7 +39,7 @@ public abstract class AbstractCommand {
myCommandCode = commandCode;
}
@Nullable
@NotNull
public final String getPayload() {
Payload payload = new Payload();
buildPayload(payload);
@@ -52,7 +52,6 @@ public abstract class AbstractCommand {
return false;
}
// todo: pass debugger to constructor(?)
public void execute() throws PyDebuggerException {
int sequence = myDebugger.getNextSequence();
if (isResponseExpected()) {

View File

@@ -0,0 +1,39 @@
package com.jetbrains.python.debugger.pydev;
import com.jetbrains.python.debugger.PyDebuggerException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author traff
*/
public class LoadSourceCommand extends AbstractCommand {
private final String myPath;
private String myContent = null;
protected LoadSourceCommand(@NotNull final RemoteDebugger debugger, String path) {
super(debugger, LOAD_SOURCE);
myPath = path;
}
public boolean isResponseExpected() {
return true;
}
@Override
protected void processResponse(final ProtocolFrame response) throws PyDebuggerException {
super.processResponse(response);
myContent = ProtocolParser.parseSourceContent(response.getPayload());
}
@Override
protected void buildPayload(Payload payload) {
payload.add(myPath);
}
@Nullable
public String getContent() {
return myContent;
}
}

View File

@@ -17,6 +17,10 @@ public class ProtocolParser {
private ProtocolParser() {
}
public static String parseSourceContent(String payload) throws PyDebuggerException {
return payload;
}
public static String decode(final String value) throws PyDebuggerException {
try {
return URLDecoder.decode(value, "UTF-8");

View File

@@ -150,6 +150,18 @@ public class RemoteDebugger {
return command.getNewValue();
}
@Nullable
public String loadSource(String path) {
LoadSourceCommand command = new LoadSourceCommand(this, path);
try {
command.execute();
return command.getContent();
}
catch (PyDebuggerException e) {
return "print 1";
}
}
private static String composeName(final PyDebugValue var) {
final StringBuilder sb = new StringBuilder(var.getTempName());
PyDebugValue p = var;
@@ -472,7 +484,7 @@ public class RemoteDebugger {
}
private void fireCloseEvent() {
for (RemoteDebuggerCloseListener listener: myCloseListeners) {
for (RemoteDebuggerCloseListener listener : myCloseListeners) {
listener.closed();
}
}

View File

@@ -88,6 +88,7 @@
<highlightUsagesHandlerFactory implementation="com.jetbrains.python.codeInsight.highlighting.PyHighlightExitPointsHandlerFactory"/>
<configurationType implementation="com.jetbrains.python.run.remote.PyRemoteDebugConfigurationType"/>
<fileEditorProvider implementation="com.jetbrains.python.debugger.remote.PyRemoteDebugEditorProvider"/>
<intentionAction>
<className>com.jetbrains.python.codeInsight.intentions.ImportToImportFromIntention</className>

View File

@@ -519,7 +519,7 @@ run.configuration.type.description=Starts server for remote debug
remote.debug.info=Info
remote.debug.server.hint=Run this remote debug configuration to start debug server.
remote.debug.server.hint2=Then copy \\helpers\\pydev package from your PyCharm distribution to location of your python script.
remote.debug.server.hint2=Add pycharm-debug.egg from PyCharm distribution to python path of your script.
remote.debug.server.hint3=Use the following command in your script to connect to debug server:
remote.debug.settings=Settings
remote.debug.remote.host=Remote host
@@ -527,3 +527,5 @@ remote.debug.port=Port
remote.debug.remote.root.folder=Remote root folder
remote.debug.local.root.folder=Local root folder
remote.debug.server.hint4=If you want to enable stdout and stderr redirection to PyCharm console, use following command in your script:
remote.debug.local.host=Local host name
remote.debug.redirect.output=Redirect output to console

View File

@@ -41,8 +41,6 @@ import static javax.swing.SwingUtilities.invokeLater;
// todo: pydevd supports module reloading - look for a way to use the feature
// todo: smart step into
public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, ProcessListener {
private final PyPositionConverter myPositionConverter;
private final RemoteDebugger myDebugger;
private final XBreakpointHandler[] myBreakpointHandlers;
private final PyDebuggerEditorsProvider myEditorsProvider;
@@ -58,18 +56,12 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
private boolean myClosing = false;
public PyDebugProcess(@NotNull XDebugSession session,
@NotNull final ServerSocket serverSocket,
@NotNull final ExecutionConsole executionConsole,
@Nullable final ProcessHandler processHandler) {
this(session, serverSocket, executionConsole, processHandler, new PyLocalPositionConverter());
}
private PyPositionConverter myPositionConverter;
public PyDebugProcess(final @NotNull XDebugSession session,
@NotNull final ServerSocket serverSocket,
@NotNull final ExecutionConsole executionConsole,
@Nullable final ProcessHandler processHandler, @NotNull PyPositionConverter positionConverter) {
@Nullable final ProcessHandler processHandler) {
super(session);
session.setPauseActionSupported(true);
myDebugger = new RemoteDebugger(this, serverSocket, 10);
@@ -80,7 +72,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
if (myProcessHandler != null) {
myProcessHandler.addProcessListener(this);
}
myPositionConverter = positionConverter;
myPositionConverter = new PyLocalPositionConverter();
myDebugger.addCloseListener(new RemoteDebuggerCloseListener() {
@Override
public void closed() {
@@ -89,6 +81,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
});
}
public void setPositionConverter(PyPositionConverter positionConverter) {
myPositionConverter = positionConverter;
}
@Override
public PyPositionConverter getPositionConverter() {
return myPositionConverter;
@@ -272,6 +269,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
myNewVariableValue.put(frame.getThreadFrameId(), newValue);
}
@Nullable
public String loadSource(String path) {
return myDebugger.loadSource(path);
}
@Override
public boolean isVariable(String name) {
final Project project = getSession().getProject();
@@ -411,4 +413,8 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
}
public PyStackFrame createStackFrame(PyStackFrameInfo frameInfo) {
return new PyStackFrame(this, frameInfo);
}
}

View File

@@ -53,7 +53,7 @@ public class PyExecutionStack extends XExecutionStack {
}
private static PyStackFrame convert(final PyDebugProcess debugProcess, final PyStackFrameInfo frameInfo) {
return new PyStackFrame(debugProcess, frameInfo);
return debugProcess.createStackFrame(frameInfo);
}
@Override

View File

@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
public class PyLocalPositionConverter implements PyPositionConverter {
protected static class PyLocalSourcePosition extends PySourcePosition {
PyLocalSourcePosition(final String file, final int line) {
public PyLocalSourcePosition(final String file, final int line) {
super(file, line);
}
}

View File

@@ -1,40 +0,0 @@
package com.jetbrains.python.debugger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.xdebugger.XSourcePosition;
import org.jetbrains.annotations.NotNull;
/**
* @author traff
*/
public class PyRemotePositionConverter extends PyLocalPositionConverter {
private final String myLocalRoot;
private final String myRemoteRoot;
public PyRemotePositionConverter(final String localRoot, final String remoteRoot) {
myLocalRoot = FileUtil.toSystemIndependentName(localRoot);
myRemoteRoot = FileUtil.toSystemIndependentName(remoteRoot);
}
@NotNull
@Override
public PySourcePosition convert(@NotNull XSourcePosition position) {
String path = FileUtil.toSystemIndependentName(position.getFile().getPath());
if (myLocalRoot.length() > 0) {
path = path.replace(myLocalRoot, myRemoteRoot);
}
return new PyLocalSourcePosition(path, position.getLine() + 1);
}
@Override
public XSourcePosition convert(@NotNull PySourcePosition position) {
String path = FileUtil.toSystemIndependentName(position.getFile());
if (myRemoteRoot.length() > 0) {
path = path.replace(myRemoteRoot, myLocalRoot);
}
final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
return createXSourcePosition(file, position.getLine());
}
}

View File

@@ -110,4 +110,8 @@ public class PyStackFrame extends XStackFrame {
return myFrameInfo.getThreadId() + ":" + myFrameInfo.getId();
}
protected XSourcePosition getPosition() {
return myPosition;
}
}

View File

@@ -707,7 +707,7 @@ public class PythonSdkType extends SdkType {
}
@Nullable
public static Sdk findPythonSdk(Module module) {
public static Sdk findPythonSdk(@Nullable Module module) {
if (module == null) return null;
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType() instanceof PythonSdkType) return sdk;