-
-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Partial support for multiple reified classes
- Loading branch information
Showing
2 changed files
with
32 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,32 @@ | ||
(ns sci.impl.reify | ||
(:refer-clojure :exclude [reify]) | ||
(:require [sci.impl.types :as t])) | ||
(:require [sci.impl.types :as t] | ||
[sci.impl.utils :refer [split-when]])) | ||
|
||
(defn reify [_ _ _ctx interface & meths] | ||
(let [meths (into {} (map (fn [meth] | ||
`['~(first meth) (fn ~(second meth) ~@(nnext meth))]) | ||
meths))] | ||
`(clojure.core/reify* ~interface ~meths))) | ||
(defn reify [_ _ _ctx & args] | ||
(let [classes->methods (split-when symbol? args) | ||
classes->methods (into {} (map (fn [[class & methods]] | ||
[class (into {} | ||
(map (fn [meth] | ||
`['~(first meth) (fn ~(second meth) ~@(nnext meth))]) | ||
methods))]) | ||
classes->methods))] | ||
`(clojure.core/reify* ~classes->methods))) | ||
|
||
(defn reify* [#?(:clj ctx | ||
:cljs _ctx) interface meths] | ||
#?(:clj (if (class? interface) | ||
(let [class-name (symbol (.getName ^Class interface))] | ||
(if-let [factory (get-in ctx [:reify class-name])] | ||
(:obj (factory {:class interface :methods meths})) | ||
(throw (ex-info (str "No reify factory for: " class-name) | ||
{:class class})))) | ||
(t/->Reified interface meths)) | ||
:cljs (t/->Reified interface meths))) | ||
:cljs _ctx) classes->methods] | ||
#?(:clj (let [ks (keys classes->methods)] | ||
;; NOTE: if the first thing in reify is a class, we assume all | ||
;; classes and no protocols. This should be addressed in a future version. | ||
(if (class? (first ks)) | ||
(let [class-names (set (map #(symbol (.getName ^Class %)) ks))] | ||
(if-let [factory (get-in ctx [:reify class-names])] | ||
(factory (zipmap class-names (vals classes->methods))) | ||
(throw (ex-info (str "No reify factory for: " class-names) | ||
{:class class})))) | ||
;; So far we only supported reify-ing one protocol at a time. This | ||
;; should be addressed in a future version | ||
(let [[interface methods] (first classes->methods)] | ||
(t/->Reified interface methods)))) | ||
:cljs (let [[interface methods] (first classes->methods)] | ||
(t/->Reified interface methods)))) |