Skip to content
Browse files

Options map as explicit arg (vs. kwargs), use own reflection lib.

Should work at this point.
  • Loading branch information...
1 parent 3d841ee commit 0a103fad9bdfa5053653e68f3f64499afcd0cca8 @timmc committed May 2, 2012
Showing with 65 additions and 54 deletions.
  1. +50 −54 src/org/timmc/handy/repl.clj
  2. +15 −0 test/org/timmc/handy/test/repl.clj
View
104 src/org/timmc/handy/repl.clj
@@ -1,80 +1,76 @@
(ns org.timmc.handy.repl
- (:use [clojure.reflect :only (reflect)])
- (:require [clojure.string :as str])
- (:import (clojure.reflect Field Method Constructor)))
-
-(def ^:private vis-levels {:public 3 :protected 2 :package 1 :private 0})
-
-(defn- vis>=
- [to-check threshold]
- (apply >= (map vis-levels [to-check threshold])))
-
-(defn- vis
- [m]
- (or (some #{:public :private :protected} (:flags m)) :package))
+ (:require [clojure.string :as str]
+ [org.timmc.handy.reflect :as rf]))
(defn- vis-str
- [m]
- (.substring (name (vis m)) 0 3))
+ [kw]
+ (.substring (name kw) 0 3))
(defn- static-str
[m]
- (if (:static (:flags m)) "st" " "))
+ (if (:static? m) "st" " "))
-(def ^:private ^:dynamic *fq* false)
+(def ^:dynamic *fq* false)
-(defn- format-classname
+(defn ^:internal format-classname
[cls]
- (cond (= cls 'void) "void"
- (class? cls) (if *fq* (.getName cls) (.getSimpleName cls))
- (symbol? cls) (format-classname (resolve cls))
- (var? cls) (.sym cls) ;; cast fn, such as #'clojure.core/long
- :else cls))
+ (if *fq*
+ (if (.isPrimitive cls)
+ (.getSimpleName cls)
+ (if (.isArray cls)
+ (str (format-classname (.getComponentType cls)) "[]")
+ (.getName cls)))
+ (.getSimpleName cls)))
-(defmulti write-member type)
-(defmethod write-member Field [f]
+(defmulti write-member :type)
+(defmethod write-member :field [f]
(format " %s %s %s : %s"
- (vis-str f)
+ (vis-str (:visibility f))
(static-str f)
(:name f)
- (format-classname (:type f))))
-(defmethod write-member Constructor [c]
+ (format-classname (:return f))))
+(defmethod write-member :constructor [c]
(format " %s : %s"
- (vis-str c)
- (str/join ", " (map format-classname (:parameter-types c)))))
-(defmethod write-member Method [m]
+ (vis-str (:visibility c))
+ (str/join ", " (map format-classname (:params c)))))
+(defmethod write-member :method [m]
(format " %s %s %s : %s : %s"
- (vis-str m)
+ (vis-str (:visibility m))
(static-str m)
(:name m)
- (format-classname (:return-type m))
- (str/join ", " (map format-classname (:parameter-types m)))))
+ (format-classname (:return m))
+ (str/join ", " (map format-classname (:params m)))))
(defn- sort-members
[ms]
- (sort-by (comp not :static :flags) (sort-by :name ms)))
+ (sort-by (comp not :static?) (sort-by :name ms)))
+
+;;(defmulti filter-return type)
(defn show
"Print the methods, constructors, and fields of the class of the provided
-value (or the class itself, if a Class subclass is provided.) Specs are
-keyword arguments, with allowed values:
+value (or the class itself, if a Class subclass is provided.) Options are
+entered in an optional map, with allowed values:
* :level <lvl> - Minimum visibility of members to show. lvl may be :public
(the default), :protected, :package, or :private.
* :fq <bool> - If true, show fully-qualified classnames. Default false."
- [v & {:as specs
- :keys [level fq]
- :or {level :public, fq false}}]
- {:pre [(contains? #{:public :protected :package :private} level)]}
- (let [cl (if (class? v) v (class v))
- data (reflect v)
- members (group-by type (:members data))]
- (binding [*fq* fq]
- (println (format-classname cl))
- (println "Bases:" (map format-classname (:bases data)))
- (doseq [t [Field Constructor Method]]
- (when-let [ms (filter #(vis>= (vis %) level) (members t))]
- (println (str (.getSimpleName t) "s:"))
- (doseq [m (sort-members ms)]
- (println (write-member m))))))
- (symbol "") ;; stupid hack to not show a nil after the printout
- ))
+ ([v {:as specs
+ :keys [level fq]
+ :or {level :public, fq false}}]
+ {:pre [(contains? #{:public :protected :package :private} level)]}
+ (let [cl (if (class? v) v (class v))
+ members {:Fields (rf/fields cl)
+ :Constructors (rf/constructors cl)
+ :Methods (rf/methods cl)}]
+ (binding [*fq* fq]
+ (println (format-classname cl))
+ (println "Bases:" (map format-classname (bases cl)))
+ (doseq [t [:Fields :Constructors :Methods]]
+ (when-let [ms (filter #(rf/vis>= (:visibility %) level)
+ (get members t :DONE_BROKE))]
+ (println (str (name t) ":"))
+ (doseq [m (sort-members ms)]
+ (println (write-member m))))))
+ (symbol "") ;; stupid hack to not show a nil after the printout
+ ))
+ ([v] (show v {})))
View
15 test/org/timmc/handy/test/repl.clj
@@ -0,0 +1,15 @@
+(ns org.timmc.handy.test.repl
+ (:use clojure.test
+ org.timmc.handy.repl))
+
+(deftest formatting
+ (are [c fq? s] (binding [*fq* fq?]
+ (= (format-classname c) s))
+ String false "String"
+ String true "java.lang.String"
+ Integer/TYPE false "int"
+ Integer/TYPE true "int"
+ (class (int-array [])) false "int[]"
+ (class (int-array [])) true "int[]"
+ (class (into-array [(into-array Void [])])) false "Void[][]"
+ (class (into-array [(into-array Void [])])) true "java.lang.Void[][]"))

0 comments on commit 0a103fa

Please sign in to comment.
Something went wrong with that request. Please try again.