Debugger refactoring: frame accessor extracted.

This commit is contained in:
Dmitry Trofimov
2013-09-08 18:00:24 +02:00
parent 179fd4eb08
commit 9a15c3cb49
13 changed files with 54 additions and 40 deletions
@@ -1,23 +1,17 @@
package com.jetbrains.python.debugger;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.xdebugger.frame.XValueChildrenList;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
/**
* @author yole
*/
public interface IPyDebugProcess extends PyEvaluator {
public interface IPyDebugProcess extends PyFrameAccessor {
PyPositionConverter getPositionConverter();
void threadSuspended(PyThreadInfo thread);
XValueChildrenList loadVariable(PyDebugValue var) throws PyDebuggerException;
void changeVariable(PyDebugValue variable, String expression) throws PyDebuggerException;
boolean isVariable(String name);
void threadResumed(PyThreadInfo thread);
@@ -3,9 +3,10 @@ package com.jetbrains.python.debugger;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.xdebugger.XNamedValue;
import com.intellij.xdebugger.frame.XNamedValue;
import com.intellij.xdebugger.frame.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -20,22 +21,29 @@ public class PyDebugValue extends XNamedValue {
private final String myValue;
private final boolean myContainer;
private final PyDebugValue myParent;
private final IPyDebugProcess myDebugProcess;
private final PyFrameAccessor myFrameAccessor;
private final boolean myErrorOnEval;
public PyDebugValue(final String name, final String type, final String value, final boolean container, boolean errorOnEval) {
public PyDebugValue(@NotNull final String name, final String type, final String value, final boolean container, boolean errorOnEval) {
this(name, type, value, container, errorOnEval, null, null);
}
public PyDebugValue(final String name, final String type, final String value, final boolean container,
boolean errorOnEval, final PyDebugValue parent, final IPyDebugProcess debugProcess) {
public PyDebugValue(@NotNull final String name, final String type, final String value, final boolean container,
boolean errorOnEval, final PyFrameAccessor frameAccessor) {
this(name, type, value, container, errorOnEval, null, frameAccessor);
}
public PyDebugValue(@NotNull final String name, final String type, final String value, final boolean container,
boolean errorOnEval, final PyDebugValue parent, final PyFrameAccessor frameAccessor) {
super(name);
myType = type;
myValue = value;
myContainer = container;
myErrorOnEval = errorOnEval;
myParent = parent;
myDebugProcess = debugProcess;
myFrameAccessor = frameAccessor;
}
public String getTempName() {
@@ -61,6 +69,10 @@ public class PyDebugValue extends XNamedValue {
public boolean isErrorOnEval() {
return myErrorOnEval;
}
public PyDebugValue setParent(@Nullable PyDebugValue parent) {
return new PyDebugValue(myName, myType, myValue, myContainer, myErrorOnEval, parent, myFrameAccessor);
}
public PyDebugValue getParent() {
return myParent;
@@ -116,7 +128,7 @@ public class PyDebugValue extends XNamedValue {
String value = PyTypeHandler.format(this);
if (value.length() >= MAX_VALUE) {
node.setFullValueEvaluator(new PyFullValueEvaluator(myDebugProcess, myName));
node.setFullValueEvaluator(new PyFullValueEvaluator(myFrameAccessor, myName));
value = value.substring(0, MAX_VALUE);
}
@@ -129,10 +141,10 @@ public class PyDebugValue extends XNamedValue {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
if (myDebugProcess == null) return;
if (myFrameAccessor == null) return;
try {
final XValueChildrenList values = myDebugProcess.loadVariable(PyDebugValue.this);
final XValueChildrenList values = myFrameAccessor.loadVariable(PyDebugValue.this);
if (!node.isObsolete()) {
node.addChildren(values, true);
}
@@ -149,7 +161,7 @@ public class PyDebugValue extends XNamedValue {
@Override
public XValueModifier getModifier() {
return new PyValueModifier(myDebugProcess, this);
return new PyValueModifier(myFrameAccessor, this);
}
private Icon getValueIcon() {
@@ -163,4 +175,8 @@ public class PyDebugValue extends XNamedValue {
return AllIcons.Debugger.Value;
}
}
public PyDebugValue setName(String newName) {
return new PyDebugValue(newName, myType, myValue, myContainer, myErrorOnEval, myParent, myFrameAccessor);
}
}
@@ -4,11 +4,17 @@ import com.intellij.xdebugger.frame.XValueChildrenList;
import org.jetbrains.annotations.Nullable;
/**
* Facade to access python variables frame
*
* @author traff
*/
public interface PyEvaluator {
public interface PyFrameAccessor {
PyDebugValue evaluate(final String expression, final boolean execute, boolean doTrunc) throws PyDebuggerException;
@Nullable
XValueChildrenList loadFrame() throws PyDebuggerException;
XValueChildrenList loadVariable(PyDebugValue var) throws PyDebuggerException;
void changeVariable(PyDebugValue variable, String expression) throws PyDebuggerException;
}
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
* @author traff
*/
public class PyFullValueEvaluator extends XFullValueEvaluator {
private final IPyDebugProcess myDebugProcess;
private final PyFrameAccessor myDebugProcess;
private final String myExpression;
/**
@@ -15,7 +15,7 @@ public class PyFullValueEvaluator extends XFullValueEvaluator {
* @param debugProcess
* @param expression
*/
protected PyFullValueEvaluator(IPyDebugProcess debugProcess, String expression) {
protected PyFullValueEvaluator(PyFrameAccessor debugProcess, String expression) {
myDebugProcess = debugProcess;
myExpression = expression;
}
@@ -7,10 +7,10 @@ import org.jetbrains.annotations.NotNull;
public class PyValueModifier extends XValueModifier {
private final IPyDebugProcess myDebugProcess;
private final PyFrameAccessor myDebugProcess;
private final PyDebugValue myVariable;
public PyValueModifier(final IPyDebugProcess debugProcess, final PyDebugValue variable) {
public PyValueModifier(final PyFrameAccessor debugProcess, final PyDebugValue variable) {
myDebugProcess = debugProcess;
myVariable = variable;
}
@@ -39,7 +39,7 @@ public abstract class AbstractCommand<T> {
public static final String TAB_CHAR = "@_@TAB_CHAR@_@";
@NotNull private final RemoteDebugger myDebugger;
@NotNull protected final RemoteDebugger myDebugger;
private final int myCommandCode;
private final ResponseProcessor<T> myResponseProcessor;
@@ -34,8 +34,7 @@ public class ChangeVariableCommand extends AbstractFrameCommand {
protected void processResponse(final ProtocolFrame response) throws PyDebuggerException {
super.processResponse(response);
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload());
myNewValue = new PyDebugValue(myVariableName, value.getType(), value.getValue(), value.isContainer(), value.isErrorOnEval(), null, myDebugProcess);
myNewValue = ProtocolParser.parseValue(response.getPayload(), myDebugProcess).setName(myVariableName);
}
public PyDebugValue getNewValue() {
@@ -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());
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload(), myDebugger.getDebugProcess());
return value.getValue();
}
};
@@ -37,9 +37,8 @@ public class EvaluateCommand extends AbstractFrameCommand {
@Override
protected void processResponse(final ProtocolFrame response) throws PyDebuggerException {
super.processResponse(response);
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload());
final String name = (myExecute ? "" : myExpression);
myValue = new PyDebugValue(name, value.getType(), value.getValue(), value.isContainer(), value.isErrorOnEval(), null, myDebugProcess);
final PyDebugValue value = ProtocolParser.parseValue(response.getPayload(), myDebugProcess);
myValue = value.setName((myExecute ? "" : myExpression));
}
public PyDebugValue getValue() {
@@ -36,7 +36,7 @@ public class GetFrameCommand extends AbstractFrameCommand {
@Override
protected void processResponse(final ProtocolFrame response) throws PyDebuggerException {
super.processResponse(response);
final List<PyDebugValue> values = ProtocolParser.parseValues(response.getPayload());
final List<PyDebugValue> values = ProtocolParser.parseValues(response.getPayload(), myDebugProcess);
myFrameVariables = new XValueChildrenList(values.size());
for (PyDebugValue value : values) {
if (!value.getName().startsWith(RemoteDebugger.TEMP_VAR_PREFIX)) {
@@ -115,27 +115,27 @@ public class ProtocolParser {
}
@NotNull
public static PyDebugValue parseValue(final String text) throws PyDebuggerException {
public static PyDebugValue parseValue(final String text, final PyFrameAccessor frameAccessor) throws PyDebuggerException {
final XppReader reader = openReader(text, true);
reader.moveDown();
return parseValue(reader);
return parseValue(reader, frameAccessor);
}
@NotNull
public static List<PyDebugValue> parseValues(final String text) throws PyDebuggerException {
public static List<PyDebugValue> parseValues(final String text, final PyFrameAccessor frameAccessor) throws PyDebuggerException {
final List<PyDebugValue> values = new LinkedList<PyDebugValue>();
final XppReader reader = openReader(text, false);
while (reader.hasMoreChildren()) {
reader.moveDown();
values.add(parseValue(reader));
values.add(parseValue(reader, frameAccessor));
reader.moveUp();
}
return values;
}
private static PyDebugValue parseValue(final XppReader reader) throws PyDebuggerException {
private static PyDebugValue parseValue(final XppReader reader, PyFrameAccessor frameAccessor) throws PyDebuggerException {
if (!"var".equals(reader.getNodeName())) {
throw new PyDebuggerException("Expected <var>, found " + reader.getNodeName());
}
@@ -150,7 +150,7 @@ public class ProtocolParser {
value = value.substring(type.length() + 2);
}
return new PyDebugValue(name, type, value, "True".equals(isContainer), "True".equals(isErrorOnEval));
return new PyDebugValue(name, type, value, "True".equals(isContainer), "True".equals(isErrorOnEval), frameAccessor);
}
private static XppReader openReader(final String text, final boolean checkForContent) throws PyDebuggerException {
@@ -15,9 +15,9 @@ public class PyDebuggerEvaluator extends XDebuggerEvaluator {
private static final PyDebugValue NONE = new PyDebugValue("", "NoneType", "None", false, false, null, null);
private Project myProject;
private final PyEvaluator myDebugProcess;
private final PyFrameAccessor myDebugProcess;
public PyDebuggerEvaluator(@NotNull Project project, @NotNull final PyEvaluator debugProcess) {
public PyDebuggerEvaluator(@NotNull Project project, @NotNull final PyFrameAccessor debugProcess) {
myProject = project;
myDebugProcess = debugProcess;
}
@@ -25,12 +25,12 @@ public class PyStackFrame extends XStackFrame {
private static final Object STACK_FRAME_EQUALITY_OBJECT = new Object();
private Project myProject;
private final PyEvaluator myDebugProcess;
private final PyFrameAccessor myDebugProcess;
private final PyStackFrameInfo myFrameInfo;
private final XSourcePosition myPosition;
public PyStackFrame(@NotNull Project project,
@NotNull final PyEvaluator debugProcess,
@NotNull final PyFrameAccessor debugProcess,
@NotNull final PyStackFrameInfo frameInfo, XSourcePosition position) {
myProject = project;
myDebugProcess = debugProcess;