Permalink
Browse files

Added debug.reflect and fixed metadata of intercepted functions.

* debug.reflect/show prints all fields, methods and constructors of a given class.
* Metadata on function symbols of intercepted functions is now added to the metadata of the created function, correctly.
* superfluous *enable-trace* in `trace-expr` removed.
* clj-gui 0.2.1.
  • Loading branch information...
1 parent f0c6b8c commit 1f4611e7d3d57dbeeeda1edb8f2e774c3b85756c @guv committed Jul 14, 2012
Showing with 115 additions and 25 deletions.
  1. +6 −1 .classpath
  2. +2 −2 README.md
  3. +2 −2 project.clj
  4. +4 −1 src/debug/inspect.clj
  5. +5 −3 src/debug/intercept.clj
  6. +78 −0 src/debug/reflect.clj
  7. +11 −14 src/debug/trace.clj
  8. +7 −2 test/debug/trace_test.clj
View
7 .classpath
@@ -6,8 +6,13 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="classes"/>
<classpathentry kind="lib" path="lib/clojure-1.2.1.jar"/>
- <classpathentry kind="lib" path="lib/swingx-core-1.6.2-2.jar"/>
<classpathentry kind="lib" path="lib/core.incubator-0.1.0.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-action-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-autocomplete-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-common-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-core-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-painters-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-plaf-1.6.3.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/clj-gui"/>
<classpathentry kind="output" path="bin"/>
</classpath>
View
4 README.md
@@ -8,8 +8,8 @@ Library for debugging Clojure programms with support for tracing, timing and ins
Add one of the following to your ```project.clj``` to let Leiningen install ```clj-debug``` for you:
```clj
-:dependencies [[clj-debug "0.6.2"]]
-:dev-dependencies [[clj-debug "0.6.2"]]
+:dependencies [[clj-debug "0.6.4"]]
+:dev-dependencies [[clj-debug "0.6.4"]]
```
View
4 project.clj
@@ -1,10 +1,10 @@
-(defproject clj-debug "0.6.2"
+(defproject clj-debug "0.6.4"
:description "Library for debugging Clojure programms with support for tracing, timing and inspection."
:url "https://github.com/guv/clj-debug"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies
[[org.clojure/clojure "1.2.1"]
[org.clojure/core.incubator "0.1.0"]
- [clj-gui "0.2.0"]]
+ [clj-gui "0.2.1"]]
:aot [debug.inspect.inspectable])
View
5 src/debug/inspect.clj
@@ -53,7 +53,10 @@
(inspect result)
result)
-
+(defn e
+ "Invokes `inspect` on the last exception in the repl bound to *e."
+ []
+ (inspect *e))
(defn- create-attribute-map [fields]
(interleave (map (fn [s] `(quote ~s)) fields) (map #(vary-meta % (constantly nil)) fields)))
View
8 src/debug/intercept.clj
@@ -46,7 +46,7 @@
(defn process-defn-decl
- [func-decl]
+ [func-symb, func-decl]
(let [; extract doc string (if present) and create metadata map
meta-map (if (string? (first func-decl))
{:doc (first func-decl)}
@@ -75,6 +75,8 @@
func-decl (if (map? (last func-decl))
(butlast func-decl)
func-decl)
+ ; merge metadata of the function name symbol with the collected metadata
+ meta-map (merge (meta func-symb) meta-map)
]
{:meta-map meta-map, :func-body-list func-decl}))
@@ -99,7 +101,7 @@
(defn intercept-func-def
[defn-command, intercept-func, func-symb, func-decl]
- (let [{:keys [meta-map, func-body-list]} (process-defn-decl func-decl),
+ (let [{:keys [meta-map, func-body-list]} (process-defn-decl func-symb, func-decl),
modified-func-bodies (map (partial intercept-func *ns* func-symb) func-body-list)]
`(~defn-command ~func-symb ~meta-map ~@modified-func-bodies)))
@@ -115,7 +117,7 @@
`(~defn-command ~func-symb ~@func-decl)
; ... else apply interception function on function body before definition.
`(do
- (print-function-interception-info ~info-prefix, (str *ns* "/" '~func-symb), '~(list* (map first (:func-body-list (process-defn-decl func-decl)))) )
+ (print-function-interception-info ~info-prefix, (str *ns* "/" '~func-symb), '~(list* (map first (:func-body-list (process-defn-decl func-symb, func-decl)))) )
~(intercept-func-def defn-command intercept-fn func-symb func-decl)))))
View
78 src/debug/reflect.clj
@@ -0,0 +1,78 @@
+; Copyright (c) Gunnar Völkel. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v1.0.txt at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+(ns debug.reflect
+ "Implementation to show the constructors, field and methods of a given object or class.
+ Inspired by the `show` function from `clojure.contrib.repl-utils`."
+ (:require
+ [clojure.string :as string])
+ (:import
+ (java.lang.reflect Modifier Method Constructor)))
+
+
+(defn param-str [m]
+ (->> m .getParameterTypes (map #(.getSimpleName %)) (string/join ",") (format "(%s)")))
+
+(defn static?
+ [member]
+ (-> member .getModifiers Modifier/isStatic))
+
+(defn method?
+ [member]
+ (instance? Method member))
+
+(defn constructor?
+ [member]
+ (instance? Constructor member))
+
+(defn result-type
+ [member]
+ (if (method? member) (.getReturnType member) (.getType member)))
+
+(defn member-details [m]
+ (let [static? (static? m)
+ method? (method? m)
+ constructor? (constructor? m)
+ text (if constructor?
+ (str "<init>" (param-str m))
+ (str
+ (when static? "static ")
+ (.getName m)
+ " : "
+ (-> m result-type .getSimpleName)
+ " "
+ (when method? (param-str m))))]
+ (assoc (bean m)
+ :static? static?
+ :method? method?
+ :constructor? constructor?
+ :text text
+ :member m)))
+
+(defn- create-pred-fn
+ [x]
+ (cond
+ (string? x) (fn [^String s] (-> s .toLowerCase (.contains x)))
+ (instance? java.util.regex.Pattern x) (fn [^String s] (re-matches x s))
+ (ifn? x) x
+ :else (constantly true)))
+
+(defn show
+ "Prints all static and instance members of x or (class x).
+ Examples: (show Integer) (show []) (show String 23) (show String \"case\") (show String #\".*Case\")"
+ ([x] (show x (constantly true)))
+ ([x, pred]
+ (let [pred-fn (create-pred-fn pred)
+ c (if (class? x) x (class x))
+ members (->> (concat (.getFields c) (.getMethods c) (.getConstructors c))
+ (map member-details)
+ (sort-by (juxt (comp not :static?) :method? :text)))
+ filtered-members (filter (comp pred-fn :name) members)]
+ (println "=== " (Modifier/toString (.getModifiers c)) c " ===")
+ (doseq [m filtered-members]
+ (println (:text m)))
+ (println (format "=== %d of %d members ===" (count filtered-members) (count members))))))
View
25 src/debug/trace.clj
@@ -177,20 +177,17 @@
; trace-expr is a macro to avoid the recursion pitfall
(defmacro trace-expr
[expr]
- `(if *enable-trace*
- ~(if (seq? expr)
- (if (or (special-symbol? (first expr)) (macro-expr? expr))
- (trace-macro expr)
- `(binding [*parent-call-node* (trace-begin-expr-call '~(resolve-first expr) '~expr)]
- (execute ~trace-end-expr-call
- (~(first expr) ~@(trace-all-exprs (rest expr))))))
- (if (symbol? expr)
- `(binding [*parent-call-node* (trace-begin-symbol-call '~(resolve-first expr))]
- (execute ~trace-end-symbol-call ~expr))
- ; else
- expr))
- ; ... else just return expression unchanged.
- ~expr))
+ (if (seq? expr)
+ (if (or (special-symbol? (first expr)) (macro-expr? expr))
+ (trace-macro expr)
+ `(binding [*parent-call-node* (trace-begin-expr-call '~(resolve-first expr) '~expr)]
+ (execute ~trace-end-expr-call
+ (~(first expr) ~@(trace-all-exprs (rest expr))))))
+ (if (symbol? expr)
+ `(binding [*parent-call-node* (trace-begin-symbol-call '~(resolve-first expr))]
+ (execute ~trace-end-symbol-call ~expr))
+ ; else
+ expr)))
(defmethod trace-macro :default
View
9 test/debug/trace_test.clj
@@ -10,7 +10,7 @@
{:author "Gunnar Völkel"}
(:use debug.trace debug.inspect))
-(trace-setup c d f g h Blubb/toString)
+(trace-setup c d f g h Blubb/toString multi)
(inspection-setup Blubb)
@@ -39,4 +39,9 @@
`(try ~@body (catch Throwable t# nil)))
(with-trace (g 5) (.toString (Blubb. 10)) (silence (h 0)))
-(with-trace (inspect (Blubb. 42)))
+(with-trace (inspect (Blubb. 42)))
+
+
+;(defn multi
+; [x y & args]
+; (apply + x y args))

0 comments on commit 1f4611e

Please sign in to comment.