From ba129824ca94838e3fd90ffec6d922b0b2700efa Mon Sep 17 00:00:00 2001 From: Brandon Bloom Date: Fri, 27 Apr 2012 21:48:30 -0700 Subject: [PATCH] Support apply on objects which satisfy IFn. --- src/clj/cljs/core.clj | 49 +++++++++++++++++++--------------------- test/cljs/cljs/core_test.cljs | 5 ++++ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/clj/cljs/core.clj b/src/clj/cljs/core.clj index ddf8260..d296e94 100644 --- a/src/clj/cljs/core.clj +++ b/src/clj/cljs/core.clj @@ -19,7 +19,7 @@ aget aset + - * / < <= > >= == zero? pos? neg? inc dec max min mod - bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set + bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-test bit-shift-left bit-shift-right bit-xor])) (alias 'core 'clojure.core) @@ -277,31 +277,28 @@ sigs)) (cons `(set! ~(symbol (str prototype-prefix pprefix)) true) (mapcat (fn [[f & meths]] - (let [ifn? (= psym 'cljs.core.IFn) - pf (if ifn? - (str prototype-prefix 'call) - (str prototype-prefix pprefix f)) - adapt-params (fn [[[targ & args :as sig] & body]] - (let [tsym (gensym "tsym")] - `(~(with-meta (vec (cons tsym args)) (meta sig)) - (this-as ~tsym - (let [~targ ~tsym] - ~@body))))) - meths (if ifn? - (map adapt-params meths) - meths)] - (cond - ifn? - [`(set! ~(symbol pf) (fn ~@meths))] - - (vector? (first meths)) - [`(set! ~(symbol (str pf "$arity$" (count (first meths)))) (fn ~@meths))] - - :else - (map (fn [[sig & body :as meth]] - `(set! ~(symbol (str pf "$arity$" (count sig))) - (fn ~meth))) - meths)))) + (if (= psym 'cljs.core.IFn) + (let [adapt-params (fn [[[targ & args :as sig] & body]] + (let [tsym (gensym "tsym")] + `(~(with-meta (vec (cons tsym args)) (meta sig)) + (this-as ~tsym + (let [~targ ~tsym] + ~@body))))) + meths (map adapt-params meths) + tsym (gensym "tsym") + argsym (gensym "args")] + [`(set! ~(symbol (str prototype-prefix 'call)) (fn ~@meths)) + `(set! ~(symbol (str prototype-prefix 'apply)) + (fn ~(with-meta [tsym argsym] (meta (first meths))) + (.apply (.-call ~tsym) ~tsym + (.concat (array ~tsym) (aclone ~argsym)))))]) + (let [pf (str prototype-prefix pprefix f)] + (if (vector? (first meths)) + [`(set! ~(symbol (str pf "$arity$" (count (first meths)))) (fn ~@meths))] + (map (fn [[sig & body :as meth]] + `(set! ~(symbol (str pf "$arity$" (count sig))) + (fn ~meth))) + meths))))) sigs)))))] `(do ~@(mapcat assign-impls impl-map)))))) diff --git a/test/cljs/cljs/core_test.cljs b/test/cljs/cljs/core_test.cljs index 5539463..0b2c387 100644 --- a/test/cljs/cljs/core_test.cljs +++ b/test/cljs/cljs/core_test.cljs @@ -175,6 +175,11 @@ (assert (= 2 ({1 1 2 2} 2))) (assert (= 2 (#{1 2 3} 2))) + (assert (= 1 (apply :a '[{:a 1 a 2}]))) + (assert (= 1 (apply 'a '[{a 1 :b 2}]))) + (assert (= 1 (apply {:a 1} [:a]))) + (assert (= 2 (apply {:a 1} [:b 2]))) + (assert (= "baz" (name 'foo/bar/baz))) (assert (= "foo/bar" (namespace 'foo/bar/baz))) (assert (= "baz" (name :foo/bar/baz))) -- 1.7.9.1