Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

evaluate expressions in debug session

  • Loading branch information...
commit a79b60f89e0b8d59ee12c26d97b63092fa48caef 1 parent f79dd99
@JPMoresmau authored
View
2  net.sf.eclipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/util/GHCiSyntax.java
@@ -23,6 +23,7 @@
public static final String QUIT_COMMAND=":q"; //$NON-NLS-1$
public static final String DELETE_ALL_BREAKPOINTS_COMMAND=":delete *"; //$NON-NLS-1$
public static final String SHOW_BINDINGS_COMMAND=":show bindings"; //$NON-NLS-1$
+ public static final String TYPE_LAST_RESULT_COMMAND=":t it"; //$NON-NLS-1$
public static final String STEP_COMMAND=":step"; //$NON-NLS-1$
public static final String SET_PRINT_WITH_SHOW_COMMAND=":set -fprint-evld-with-show"; //$NON-NLS-1$
@@ -33,6 +34,7 @@
public static final String PROMPT_END="> "; //$NON-NLS-1$
public static final String TYPEOF="::"; //$NON-NLS-1$
+ public static final String UNIT="()"; //$NON-NLS-1$
public static String setBreakpointCommand(final String module, final int lineNumber){
return ":break " +module+" "+ lineNumber; //$NON-NLS-1$//$NON-NLS-2$
View
32 ....debug.core/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellDebugTarget.java
@@ -327,7 +327,7 @@ public synchronized void streamAppended( final String text, final IStreamMonitor
}
- public IVariable[] getVariables( final HaskellStrackFrame frame ) throws DebugException {
+ public synchronized IVariable[] getVariables( final HaskellStrackFrame frame ) throws DebugException {
sendRequest( GHCiSyntax.SHOW_BINDINGS_COMMAND, true );
String s=response.toString();
BufferedReader br=new BufferedReader(new StringReader( s ));
@@ -366,4 +366,34 @@ public void forceVariable(final HaskellVariable var)throws DebugException{
}*/
}
+ /**
+ * evaluate an arbitrary expression
+ * @param expression the expression
+ * @return the value and its type
+ * @throws DebugException
+ */
+ public synchronized HaskellValue evaluate(final String expression)throws DebugException{
+ // get rid of any previous "it" in case of evaluation error
+ sendRequest(GHCiSyntax.UNIT,true);
+ sendRequest(expression,true);
+ String val=getResultWithoutPrompt();
+ sendRequest(GHCiSyntax.TYPE_LAST_RESULT_COMMAND,true);
+ String type=getResultWithoutPrompt();
+ int ix=type.indexOf( GHCiSyntax.TYPEOF );
+ if (ix>-1){
+ type=type.substring( ix+GHCiSyntax.TYPEOF.length() ).trim();
+ } else {
+ type=""; //$NON-NLS-1$
+ }
+ return new HaskellValue(this,type,val);
+ }
+
+ private String getResultWithoutPrompt(){
+ String s=response.toString();
+ int ix=s.lastIndexOf( ResourceUtil.NL );
+ if(ix>-1){
+ s=s.substring(0,ix).trim();
+ }
+ return s;
+ }
}
View
11 ...askell.debug.core/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellValue.java
@@ -11,17 +11,22 @@
*/
public class HaskellValue extends HaskellDebugElement implements IValue {
private final String val;
- private final HaskellVariable var;
+ private final String type;
public HaskellValue(final HaskellVariable var,final String val){
super( var.getDebugTarget() );
- this.var=var;
+ this.type=var.getReferenceTypeName();
this.val=val;
+ }
+ public HaskellValue(final HaskellDebugTarget target,final String type,final String val){
+ super( target );
+ this.type=type;
+ this.val=val;
}
public String getReferenceTypeName() {
- return var.getReferenceTypeName();
+ return type;
}
public String getValueString() {
View
85 ...i/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/ui/internal/debug/HaskellWatchExpressionDelegate.java
@@ -0,0 +1,85 @@
+package net.sf.eclipsefp.haskell.debug.ui.internal.debug;
+
+import net.sf.eclipsefp.haskell.debug.core.internal.debug.HaskellDebugElement;
+import net.sf.eclipsefp.haskell.debug.core.internal.debug.HaskellValue;
+import net.sf.eclipsefp.haskell.debug.ui.internal.util.UITexts;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.ISuspendResume;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IWatchExpressionDelegate;
+import org.eclipse.debug.core.model.IWatchExpressionListener;
+import org.eclipse.debug.core.model.IWatchExpressionResult;
+
+/**
+ * Delegate to evaluate haskell expression in GHCi debugging session
+ * @author JP Moresmau
+ *
+ */
+public class HaskellWatchExpressionDelegate implements IWatchExpressionDelegate {
+
+ public void evaluateExpression( final String expression, final IDebugElement context,
+ final IWatchExpressionListener listener ) {
+ HaskellDebugElement hde=(HaskellDebugElement)context;
+ if ((hde instanceof ISuspendResume && ((ISuspendResume)hde).isSuspended()) || hde.getDebugTarget().isSuspended()){
+ try {
+ HaskellValue val=hde.getDebugTarget().evaluate( expression );
+ listener.watchEvaluationFinished( new WatchExpressionResult( expression, val, null ));
+
+ } catch (DebugException de){
+ listener.watchEvaluationFinished( new WatchExpressionResult( expression, null, de ));
+
+ }
+ } else {
+ listener.watchEvaluationFinished( new WatchExpressionResult(expression,null,null) );
+ }
+
+ }
+
+ /**
+ * Wraps either:
+ * - a HaskellValue if we could evaluate the expression
+ * - A DebugException if there was an error
+ * - Nothing if we couldn't evaluate at all because we weren't suspended
+ * @author jean-philippem
+ *
+ */
+ private class WatchExpressionResult implements IWatchExpressionResult{
+ private final HaskellValue val;
+ private final DebugException exception;
+ private final String expression;
+
+
+
+ public WatchExpressionResult( final String expression, final HaskellValue val,
+ final DebugException exception ) {
+ this.expression = expression;
+ this.val = val;
+ this.exception = exception;
+ }
+
+ public boolean hasErrors() {
+ return exception!=null;
+ }
+
+ public IValue getValue() {
+ return val;
+ }
+
+ public String getExpressionText() {
+ return expression;
+ }
+
+ public DebugException getException() {
+ return exception;
+ }
+
+ public String[] getErrorMessages() {
+ if (val==null && exception==null){
+ return new String[]{UITexts.evaluate_need_suspend};
+ }
+ return new String[0];
+ }
+ }
+
+}
View
40 ....ui/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/ui/internal/debug/HaskellWatchExpressionResult.java
@@ -0,0 +1,40 @@
+package net.sf.eclipsefp.haskell.debug.ui.internal.debug;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IWatchExpressionResult;
+
+/**
+ *
+ * @author JP Moresmau
+ *
+ */
+public class HaskellWatchExpressionResult implements IWatchExpressionResult {
+
+ public String[] getErrorMessages() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public DebugException getException() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getExpressionText() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IValue getValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean hasErrors() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+
+}
View
2  ...clipsefp.haskell.debug.ui/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/UITexts.java
@@ -45,6 +45,8 @@
public static String breakpoint_toggle;
public static String breakpoint_toggle_description;
+ public static String evaluate_need_suspend;
+
private static final String BUNDLE_NAME
= UITexts.class.getPackage().getName() + ".uitexts"; //$NON-NLS-1$
View
4 ...fp.haskell.debug.ui/INTERNAL/java/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/uitexts.properties
@@ -34,4 +34,6 @@ debug_editor_title=Force variable evaluation
debug_editor_text=Haskell variables cannot have values assigned to them. But by clicking OK you can force evaluation of the variable. Be aware that forcing evaluation of a variable instead of leaving Haskell lazy evaluation system decide when to do it can change the behavior of your code.
breakpoint_toggle=Toggle breakpoint
-breakpoint_toggle_description=Toggle line breakpoint
+breakpoint_toggle_description=Toggle line breakpoint
+
+evaluate_need_suspend=Execution must be suspended to perform evaluation of expressions
View
5 net.sf.eclipsefp.haskell.debug.ui/plugin.xml
@@ -163,5 +163,10 @@
</editorContribution>
</extension>
+ <extension point="org.eclipse.debug.core.watchExpressionDelegates">
+ <watchExpressionDelegate
+ debugModel="net.sf.eclipsefp.haskell.debug"
+ delegateClass="net.sf.eclipsefp.haskell.debug.ui.internal.debug.HaskellWatchExpressionDelegate"/>
+ </extension>
</plugin>
Please sign in to comment.
Something went wrong with that request. Please try again.