Commits

Anonymous committed 70e5b49

Added inspecting variables in frame.

Comments (0)

Files changed (5)

src/org/lispdev/swank/ISwank.java

   @Deprecated
   void addListener(SwankEvent writeString, SwankRunnable displayRunnable);
 
+  public LispNode getInspectFrameLocal(String threadNum,
+      String frameNum, String varNum, long timeout);
+
 }

src/org/lispdev/swank/LispImplementation.java

 
 import java.io.IOException;
 
+import org.eclipse.debug.core.DebugException;
 import org.lispdev.log.Log;
 import org.lispdev.swank.debug.LispDebugTarget;
+import org.lispdev.swank.debug.LispValue;
 import org.lispdev.swank.debug.LispVariable;
+import org.lispdev.swank.debug.LispVariable.IInspectCmd;
+import org.lispdev.swank.debug.LispVariable.InspectInfo;
 import org.lispdev.swank.runnables.SwankCompileStringRunnable.CompileMessage;
 import org.lispdev.swank.runnables.SwankCompileStringRunnable.CompileStringInfo;
 import org.lispdev.swank.runnables.SwankDebugActivateRunnable.DebugActivateInfo;
    * Converts {@link LispNode} n, which is result of call to sendGetFrameLocals
    * to array of LispVariables.
    */
-  public LispVariable[] getLispVariables(LispDebugTarget target, LispNode n)
+  public LispVariable[] getLispVariables(final LispDebugTarget target,
+      final String thread, final String frame, final LispNode n)
   {
     if( n == null )
     {
       return new LispVariable[0];
     }
     LispVariable[] res = new LispVariable[n.getParamsCount()];
+    final ISwank swank = target.getSwank();
     for( int i = 0; i < res.length; ++i )
     {
       LispNode ni = n.get(i);
-      res[i] = new LispVariable(target,
-          ni.getf(":name").value,ni.getf(":value").value);
+      final int ii = i;
+      final IInspectCmd cmd = new IInspectCmd()
+      {
+        @Override
+        public InspectInfo inspect(final LispVariable parent)
+        {
+          LispNode r = swank.getInspectFrameLocal(thread, frame,
+              String.valueOf(ii), 500);
+          InspectInfo res = new InspectInfo(r.getf(":title").value,
+              r.getf(":title").value);
+          LispNode c = r.getf(":content").get(0);
+          for(int j = 1; j < c.getParamsCount(); ++j )
+          {
+            if( c.get(j).value.startsWith(":") )
+            {
+              try
+              {
+                res.content.add(new LispVariable(target,
+                    (LispValue)parent.getValue(),c.get(j-1).value,
+                    c.get(j+1).getf(":value").value,null));
+              }
+              catch(DebugException e)
+              {
+                e.printStackTrace();
+              }
+            }
+          }
+          return res;
+        }
+      };
+      res[i] = new LispVariable(target, null, ni.getf(":name").value,
+          ni.getf(":value").value, cmd);
     }
     return res;
   }

src/org/lispdev/swank/SwankInterface.java

     swank.sendEvalRawWithThread(msg, "nil", threadNum, callBack);
   }
 
+  public LispNode getInspectFrameLocal(String threadNum,
+      String frameNum, String varNum, long timeout)
+  {
+    String msg = "(swank:inspect-frame-var " + frameNum + " " + varNum + ")";
+    return swank.sendEvalAndGrabRawWithThread(msg, "nil", threadNum, timeout);
+  }
+
   // Debug related
 
   public synchronized void sendGetFrameLocals(String frameNum, String threadId,
     LispNode n = swank.sendEvalAndGrabRawWithThread(
         "(swank:frame-locals-for-emacs " + frameNum + ")",
         "nil", threadId, 2000);
-    return implementation.getLispVariables(target, n);
+    return implementation.getLispVariables(target,threadId,String.valueOf(frameNum), n);
   }
 
   public synchronized void sendGetFrameSourceLocation(String frameNum,

src/org/lispdev/swank/debug/LispValue.java

 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IValue;
 import org.eclipse.debug.core.model.IVariable;
+import org.lispdev.swank.debug.LispVariable.IInspectCmd;
+import org.lispdev.swank.debug.LispVariable.InspectInfo;
 
+/*
+-->(:emacs-rex (swank:inspect-frame-var 1 0) nil 1 4)
+  <--(:return (:ok (:title "#<(INTEGER 0 536870911) {C}>" :id 3 :content (("Value: 3 = #x00000003 = #o3 = #b11 = 3.e+0" "
+  " "Code-char" ": " (:value "#\\Etx" 0) "
+  " "Integer-length" ": " (:value "2" 1) "
+  " "Universal-time" ": " (:value "\"1899-12-31T18:00:03-06:00\"" 2) "
+  ") 14 0 14))) 4)
+
+
+  -->(:emacs-rex (swank:listener-eval "\"this\"
+  ") nil :repl-thread 2)
+  <--(:presentation-start 1 :repl-result)
+  <--(:write-string "\"this\"" :repl-result)
+  <--(:presentation-end 1 :repl-result)
+  <--(:write-string "
+  " :repl-result)
+  <--(:return (:ok nil) 2)
+  -->(:emacs-rex (swank:init-inspector "(swank:get-repl-result #10r1)" ) nil :repl-thread 3)
+  <--(:return (:ok (:title "#<(SIMPLE-ARRAY CHARACTER (4)) {B05859F}>" :id 8 :content (("Dimensions" ": " (:value "(4)" 0) "
+  " "Element type" ": " (:value "CHARACTER" 1) "
+  " "Total size" ": " (:value "4" 2) "
+  " "Adjustable" ": " (:value "NIL" 3) "
+  " "Contents:" "
+  " "0" ": " (:value "#\\t" 4) "
+  " "1" ": " (:value "#\\h" 5) "
+  " "2" ": " (:value "#\\i" 6) "
+  " "3" ": " (:value "#\\s" 7) "
+  ") 34 0 34))) 3)
+  -->(:emacs-rex (swank:inspect-nth-part 4) nil :repl-thread 4)
+  <--(:return (:ok (:title "#<STANDARD-CHAR {7442}>" :id 12 :content (("Char code" ": " (:value "116" 9) "
+  " "Lower cased" ": " (:value "#1=#\\t" 10) "
+  " "Upper cased" ": " (:value "#\\T" 11) "
+  ") 12 0 12))) 4)
+  -->(:emacs-rex (swank:inspector-pop) nil :repl-thread 5)
+  <--(:return (:ok (:title "#<(SIMPLE-ARRAY CHARACTER (4)) {B05859F}>" :id 21 :content (("Dimensions" ": " (:value "(4)" 13) "
+  " "Element type" ": " (:value "CHARACTER" 14) "
+  " "Total size" ": " (:value "4" 15) "
+  " "Adjustable" ": " (:value "NIL" 16) "
+  " "Contents:" "
+  " "0" ": " (:value "#1=#\\t" 17) "
+  " "1" ": " (:value "#\\h" 18) "
+  " "2" ": " (:value "#\\i" 19) "
+  " "3" ": " (:value "#\\s" 20) "
+  ") 34 0 34))) 5)
+  -->(:emacs-rex (swank:inspector-next) nil :repl-thread 6)
+  <--(:return (:ok (:title "#<STANDARD-CHAR {7442}>" :id 25 :content (("Char code" ": " (:value "116" 22) "
+  " "Lower cased" ": " (:value "#1=#\\t" 23) "
+  " "Upper cased" ": " (:value "#\\T" 24) "
+  ") 12 0 12))) 6)
+
+ */
 public class LispValue extends LispDebugElement implements IValue
 {
+  private final LispVariable parent;
   private final String value;
+  private final IInspectCmd inspect;
+  private InspectInfo info = null;
 
-  public LispValue(LispDebugTarget target, String value)
+  public LispValue(LispDebugTarget target, LispVariable parent, String value,
+      IInspectCmd inspect)
   {
     super(target);
+    this.parent = parent;
     this.value = value;
+    this.inspect = inspect;
+  }
+
+  private void runInspect()
+  {
+    if( inspect != null )
+    {
+      if( parent != null && parent.getParent() != null )
+      {
+        parent.getParent().runInspect();
+      }
+      info = inspect.inspect(parent);
+    }
   }
 
   @Override
   public String getReferenceTypeName() throws DebugException
   {
-    return "lisp";
+    if( info == null )
+    {
+      runInspect();
+    }
+    return (info == null ? "" : info.type);
   }
 
   @Override
   @Override
   public IVariable[] getVariables() throws DebugException
   {
-    return new IVariable[0];
+    if( info == null )
+    {
+      runInspect();
+    }
+    return (info == null ? new IVariable[0] :
+      info.content.toArray(new IVariable[info.content.size()]));
   }
 
   @Override
   public boolean hasVariables() throws DebugException
   {
-    return false;
+    if( info == null )
+    {
+      runInspect();
+    }
+    return info != null;
   }
 
   @Override
   public String toString()
   {
-    return value;
+    if( info == null )
+    {
+      runInspect();
+    }
+    return (info == null ? value : info.title);
   }
 
 }

src/org/lispdev/swank/debug/LispVariable.java

 package org.lispdev.swank.debug;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IVariable;
 import org.lispdev.swank.SwankPlugin;
 
+
+/*
+-->(:emacs-rex (swank:inspect-frame-var 1 0) nil 1 4)
+  <--(:return (:ok (:title "#<(INTEGER 0 536870911) {C}>" :id 3 :content (("Value: 3 = #x00000003 = #o3 = #b11 = 3.e+0" "
+  " "Code-char" ": " (:value "#\\Etx" 0) "
+  " "Integer-length" ": " (:value "2" 1) "
+  " "Universal-time" ": " (:value "\"1899-12-31T18:00:03-06:00\"" 2) "
+  ") 14 0 14))) 4)
+
+
+  -->(:emacs-rex (swank:listener-eval "\"this\"
+  ") nil :repl-thread 2)
+  <--(:presentation-start 1 :repl-result)
+  <--(:write-string "\"this\"" :repl-result)
+  <--(:presentation-end 1 :repl-result)
+  <--(:write-string "
+  " :repl-result)
+  <--(:return (:ok nil) 2)
+  -->(:emacs-rex (swank:init-inspector "(swank:get-repl-result #10r1)" ) nil :repl-thread 3)
+  <--(:return (:ok (:title "#<(SIMPLE-ARRAY CHARACTER (4)) {B05859F}>" :id 8 :content (("Dimensions" ": " (:value "(4)" 0) "
+  " "Element type" ": " (:value "CHARACTER" 1) "
+  " "Total size" ": " (:value "4" 2) "
+  " "Adjustable" ": " (:value "NIL" 3) "
+  " "Contents:" "
+  " "0" ": " (:value "#\\t" 4) "
+  " "1" ": " (:value "#\\h" 5) "
+  " "2" ": " (:value "#\\i" 6) "
+  " "3" ": " (:value "#\\s" 7) "
+  ") 34 0 34))) 3)
+  -->(:emacs-rex (swank:inspect-nth-part 4) nil :repl-thread 4)
+  <--(:return (:ok (:title "#<STANDARD-CHAR {7442}>" :id 12 :content (("Char code" ": " (:value "116" 9) "
+  " "Lower cased" ": " (:value "#1=#\\t" 10) "
+  " "Upper cased" ": " (:value "#\\T" 11) "
+  ") 12 0 12))) 4)
+  -->(:emacs-rex (swank:inspector-pop) nil :repl-thread 5)
+  <--(:return (:ok (:title "#<(SIMPLE-ARRAY CHARACTER (4)) {B05859F}>" :id 21 :content (("Dimensions" ": " (:value "(4)" 13) "
+  " "Element type" ": " (:value "CHARACTER" 14) "
+  " "Total size" ": " (:value "4" 15) "
+  " "Adjustable" ": " (:value "NIL" 16) "
+  " "Contents:" "
+  " "0" ": " (:value "#1=#\\t" 17) "
+  " "1" ": " (:value "#\\h" 18) "
+  " "2" ": " (:value "#\\i" 19) "
+  " "3" ": " (:value "#\\s" 20) "
+  ") 34 0 34))) 5)
+  -->(:emacs-rex (swank:inspector-next) nil :repl-thread 6)
+  <--(:return (:ok (:title "#<STANDARD-CHAR {7442}>" :id 25 :content (("Char code" ": " (:value "116" 22) "
+  " "Lower cased" ": " (:value "#1=#\\t" 23) "
+  " "Upper cased" ": " (:value "#\\T" 24) "
+  ") 12 0 12))) 6)
+
+ */
 public class LispVariable extends LispDebugElement implements IVariable
 {
   private final String name;
-  private final LispValue value;
+  private final LispValue value; /* :content */
+  private final LispValue parent;
 
-  public LispVariable(LispDebugTarget target, String name, String value)
+  public static class InspectInfo
+  {
+    public final List<LispVariable> content = new ArrayList<LispVariable>();
+    public final String title;
+    public final String type;
+    public InspectInfo(String title, String type)
+    {
+      this.title = title;
+      this.type = type;
+    }
+  }
+
+  public LispValue getParent()
+  {
+    return parent;
+  }
+
+  public static interface IInspectCmd
+  {
+    public InspectInfo inspect(LispVariable parent);
+  }
+
+  public LispVariable(LispDebugTarget target, LispValue parent,
+      String name, String value, IInspectCmd inspect)
   {
     super(target);
     this.name = name;
-    this.value = new LispValue(target, value);
+    this.parent = parent;
+    this.value = new LispValue(target,this,value,inspect);
   }
 
   @Override
   @Override
   public String getReferenceTypeName() throws DebugException
   {
-    return "lisp";
+    return value.getReferenceTypeName();
   }
 
   @Override