Skip to content

Commit

Permalink
[#603] Partial support for reifying multiple classes
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude committed Oct 18, 2020
1 parent 5eb4890 commit e86891f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 62 deletions.
2 changes: 1 addition & 1 deletion sci
Submodule sci updated from ea5a87 to 323a25
94 changes: 34 additions & 60 deletions src/babashka/impl/reify.clj
Original file line number Diff line number Diff line change
@@ -1,66 +1,40 @@
(ns babashka.impl.reify
{:no-doc true}
#_(:require [clojure.math.combinatorics :as combo]))
(:require [clojure.math.combinatorics :as combo]))

;; (defmacro gen-reify-combos [classes]
;; (let [subsets (rest (combo/subsets classes))]
;; (reduce (fn [opts classes]
;; (assoc opts (set (map (fn [[class _]]
;; (list 'quote class))
;; classes))
;; ;; TODO: methods per class
;; `(fn [{:keys [:methods]}]
;; (reify
;; ~@(mapcat
;; (fn [[clazz methods]]
;; (cons clazz
;; (map (fn [[meth args]]
;; (list meth args
;; (list* (list 'get-in 'methods [(list 'quote clazz) (list 'quote meth)])
;; args)))
;; methods)))
;; classes)))))
;; {}
;; subsets)))
(set! *warn-on-reflection* false)

;; (def combos (gen-reify-combos [[clojure.lang.IPending [[isRealized [this]]]]
;; [clojure.lang.IDeref [[deref [this]]]]]))

;; (def pending-and-deref
;; (let [factory-fn (get combos '#{clojure.lang.IPending clojure.lang.IDeref})]
;; (factory-fn {:methods {'clojure.lang.IPending {'isRealized (fn [_] false)}
;; 'clojure.lang.IDeref {'deref (fn [_] :deref)}}})))

;; (prn @pending-and-deref)
;; (prn (realized? pending-and-deref))
;; (prn (instance? clojure.lang.IDeref pending-and-deref))
;; (prn (instance? clojure.lang.IPending pending-and-deref))

;; (def only-deref
;; (let [factory-fn (get combos '#{clojure.lang.IDeref})]
;; (factory-fn {:methods {'clojure.lang.IDeref {'deref (fn [_] :deref)}}})))

;; (prn @only-deref)
;; (prn (instance? clojure.lang.IDeref only-deref))
;; (prn (instance? clojure.lang.IPending only-deref))
(defmacro gen-reify-combos
"Generates pre-compiled reify combinations"
[methods]
(let [subsets (rest (combo/subsets (seq methods)))]
(reduce (fn [opts classes]
(assoc opts
(set (map (fn [[class _]]
(list 'quote class))
classes))
(list 'fn ['methods]
(list* 'reify
(mapcat
(fn [[clazz methods]]
(cons clazz
(map
(fn [[meth args]]
(list meth args
(list*
(list 'get-in 'methods
[(list 'quote clazz) (list 'quote meth)])
args)))
methods)))
classes)))))
{}
subsets)))

#_:clj-kondo/ignore
(def reify-opts
{'java.nio.file.FileVisitor
(fn [{:keys [:methods]}]
{:obj (reify java.nio.file.FileVisitor
(preVisitDirectory [this p attrs]
((get methods 'preVisitDirectory) this p attrs))
(postVisitDirectory [this p attrs]
((get methods 'postVisitDirectory) this p attrs))
(visitFile [this p attrs]
((get methods 'visitFile) this p attrs)))})
'java.io.FileFilter
(fn [{:keys [:methods]}]
{:obj (reify java.io.FileFilter
(accept [this f]
((get methods 'accept) this f)))})
'java.io.FilenameFilter
(fn [{:keys [:methods]}]
{:obj (reify java.io.FilenameFilter
(accept [this f s]
((get methods 'accept) this f s)))})})
(gen-reify-combos
{java.nio.file.FileVisitor {preVisitDirectory [this p attrs]
postVisitDirectory [this p attrs]
visitFile [this p attrs]}
java.io.FileFilter {accept [this f]}
java.io.FilenameFilter {accept [this f s]}}))
11 changes: 10 additions & 1 deletion test/babashka/main_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,16 @@
(is (.exists f2))
(let [v (bb nil "-f" (.getPath (io/file "test-resources" "babashka" "glob.clj")))]
(is (vector? v))
(is (.exists (io/file (first v)))))))
(is (.exists (io/file (first v))))))
(testing "reify can handle multiple classes at once"
(is (true? (bb nil "
(def filter-obj (reify java.io.FileFilter
(accept [this f] (prn (.getPath f)) true)
java.io.FilenameFilter
(accept [this f name] (prn name) true)))
(def s1 (with-out-str (.listFiles (clojure.java.io/file \".\") filter-obj)))
(def s2 (with-out-str (.list (clojure.java.io/file \".\") filter-obj)))
(and (pos? (count s1)) (pos? (count s2)))")))))

(deftest future-print-test
(testing "the root binding of sci/*out*"
Expand Down

0 comments on commit e86891f

Please sign in to comment.