Get referrers refactored a bit.

This commit is contained in:
Dmitry Trofimov
2014-09-02 17:17:21 +02:00
parent 73936c8cec
commit 4dd3e720d9
5 changed files with 67 additions and 68 deletions
@@ -42,7 +42,7 @@ public abstract class AbstractCommand<T> {
public static final String TAB_CHAR = "@_@TAB_CHAR@_@";
@NotNull protected final RemoteDebugger myDebugger;
@NotNull private final RemoteDebugger myDebugger;
private final int myCommandCode;
private final ResponseProcessor<T> myResponseProcessor;
@@ -187,6 +187,11 @@ public abstract class AbstractCommand<T> {
return command == ERROR;
}
@NotNull
public RemoteDebugger getDebugger() {
return myDebugger;
}
protected static class Payload {
private final StringBuilder myBuilder = new StringBuilder();
private static final char SEPARATOR = '\t';
@@ -28,7 +28,7 @@ public class ConsoleExecCommand extends AbstractFrameCommand<String> {
return new ResponseProcessor<String>() {
@Override
protected String parseResponse(ProtocolFrame response) throws PyDebuggerException {
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload(), myDebugger.getDebugProcess());
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload(), getDebugger().getDebugProcess());
return value.getValue();
}
};
@@ -0,0 +1,50 @@
package com.jetbrains.python.debugger.pydev;
import com.jetbrains.python.debugger.PyDebugValue;
import com.jetbrains.python.debugger.PyDebuggerException;
import com.jetbrains.python.debugger.PyReferringObjectsValue;
import java.util.List;
/**
* @author traff
*/
public class GetReferrersCommand extends RunCustomOperationCommand<List<PyDebugValue>> {
public GetReferrersCommand(RemoteDebugger target, String threadId, String frameId, PyReferringObjectsValue value) {
super(target, createVariableLocator(threadId, frameId, value), "from pydevd_referrers import get_referrer_info",
"get_referrer_info");
}
@Override
protected ResponseProcessor<List<PyDebugValue>> createResponseProcessor() {
return new ResponseProcessor<List<PyDebugValue>>() {
@Override
protected List<PyDebugValue> parseResponse(ProtocolFrame response) throws PyDebuggerException {
return ProtocolParser.parseReferrers(decode(response.getPayload()), getDebugger().getDebugProcess());
}
};
}
private static PyVariableLocator createVariableLocator(final String threadId, final String frameId, final PyReferringObjectsValue var) {
return new PyVariableLocator() {
@Override
public String getThreadId() {
return threadId;
}
@Override
public String getPyDBLocation() {
if (var.getId() == null) {
return threadId + "\t" + frameId + "\tFRAME\t" + var.getName();
}
//Ok, this only happens when we're dealing with references with no proper scope given and we need to get
//things by id (which is usually not ideal). In this case we keep the proper thread id and set the frame id
//as the id of the object to be searched later on based on the list of all alive objects.
return getThreadId() + "\t" + var.getId() + "\tBY_ID";
}
};
}
}
@@ -160,20 +160,8 @@ public class RemoteDebugger implements ProcessDebugger {
final String frameId,
final PyReferringObjectsValue var,
final PyDebugCallback<XValueChildrenList> callback) {
RunCustomOperationCommand cmd = new RunCustomOperationCommand<List<PyDebugValue>>(this, createVariableLocator(threadId, frameId, var),
"from pydevd_referrers import get_referrer_info",
"get_referrer_info") {
RunCustomOperationCommand cmd = new GetReferrersCommand(this, threadId, frameId, var);
@Override
protected ResponseProcessor<List<PyDebugValue>> createResponseProcessor() {
return new ResponseProcessor<List<PyDebugValue>>() {
@Override
protected List<PyDebugValue> parseResponse(ProtocolFrame response) throws PyDebuggerException {
return ProtocolParser.parseReferrers(decode(response.getPayload()), RemoteDebugger.this.getDebugProcess());
}
};
}
};
cmd.execute(new PyDebugCallback<List<PyDebugValue>>() {
@Override
public void ok(List<PyDebugValue> value) {
@@ -191,28 +179,6 @@ public class RemoteDebugger implements ProcessDebugger {
});
}
private PyVariableLocator createVariableLocator(final String threadId, final String frameId, final PyReferringObjectsValue var) {
return new PyVariableLocator() {
@Override
public String getThreadId() {
return threadId;
}
@Override
public String getPyDBLocation() {
if (var.getId() == null) {
return threadId + "\t" + frameId + "\tFRAME\t" + var.getName();
}
//Ok, this only happens when we're dealing with references with no proper scope given and we need to get
//things by id (which is usually not ideal). In this case we keep the proper thread id and set the frame id
//as the id of the object to be searched later on based on the list of all alive objects.
return getThreadId() + "\t" + var.getId() + "\tBY_ID";
}
};
}
@Override
public PyDebugValue changeVariable(final String threadId, final String frameId, final PyDebugValue var, final String value)
throws PyDebuggerException {
@@ -25,20 +25,19 @@ import java.net.URLEncoder;
public class RunCustomOperationCommand<T> extends AbstractCommand<T> {
private static final Logger LOG = Logger.getInstance(RunCustomOperationCommand.class);
private String encodedCodeOrFile;
private String operationFnName;
private PyVariableLocator locator;
private String style;
private String responsePayload;
private String myEncodedCodeOrFile;
private String myOperationFnName;
private PyVariableLocator myLocator;
private String myStyle;
private RunCustomOperationCommand(RemoteDebugger target, PyVariableLocator locator,
String style, String codeOrFile, String operationFnName) {
super(target, CMD_RUN_CUSTOM_OPERATION);
this.locator = locator;
this.style = style;
this.encodedCodeOrFile = encode(codeOrFile);
this.operationFnName = operationFnName;
this.myLocator = locator;
this.myStyle = style;
this.myEncodedCodeOrFile = encode(codeOrFile);
this.myOperationFnName = operationFnName;
}
/**
@@ -54,23 +53,10 @@ public class RunCustomOperationCommand<T> extends AbstractCommand<T> {
this(target, locator, "EXEC", operationSource, operationFnName);
}
/**
* Create a new command to run with the function defined in a file.
*
* @param target Debug Target to run on
* @param locator Location of variable or expression.
* @param operationPyFile Definition of the function to be run (this file is "execfile"d by the target)
* @param operationFnName Function to call, must be defined by operationSource
*/
public RunCustomOperationCommand(RemoteDebugger target, PyVariableLocator locator,
File operationPyFile, String operationFnName) {
this(target, locator, "EXECFILE", operationPyFile.toString(), operationFnName);
}
@Override
protected void buildPayload(Payload payload) {
payload.add(locator.getPyDBLocation() + "||" + style).add(encodedCodeOrFile).add(operationFnName);
payload.add(myLocator.getPyDBLocation() + "||" + myStyle).add(myEncodedCodeOrFile).add(myOperationFnName);
}
@Override
@@ -78,14 +64,6 @@ public class RunCustomOperationCommand<T> extends AbstractCommand<T> {
return true;
}
/**
* Return the response received from the custom command
* @return the response or <code>null</code> if an error or no response has been received.
*/
public String getResponsePayload() {
return responsePayload;
}
private static String encode(String in) {
try {
return URLEncoder.encode(in, "UTF-8");