diff --git a/project.clj b/project.clj index 9b9b274..275eaf2 100644 --- a/project.clj +++ b/project.clj @@ -1,15 +1,16 @@ (defproject riddley "0.2.1-SNAPSHOT" :description "code-walking without caveats" :license {:name "MIT License" - :url "http://opensource.org/licenses/MIT"} + :url "http://opensource.org/licenses/MIT"} :dependencies [] :plugins [[lein-codox "0.9.4"]] - :codox {:src-dir-uri "https://github.com/ztellman/riddley/tree/master/" + :codox {:src-dir-uri "https://github.com/ztellman/riddley/tree/master/" :src-linenum-anchor-prefix "L" - :defaults {:doc/format :markdown} - :include [riddley.walk riddley.compiler] - :output-dir "doc"} - :profiles {:dev {:dependencies [[org.clojure/clojure "1.10.1"] + :defaults {:doc/format :markdown} + :include [riddley.walk riddley.compiler] + :output-dir "doc"} + :profiles {:provided {:dependencies [[org.clojure/clojure "1.8.0"]]} + :dev {:dependencies [[org.clojure/clojure "1.10.1"] [pjstadig/humane-test-output "0.10.0"]] :injections [(require 'pjstadig.humane-test-output) (pjstadig.humane-test-output/activate!)]}} diff --git a/src/riddley/walk.clj b/src/riddley/walk.clj index b561c3e..02cb49e 100644 --- a/src/riddley/walk.clj +++ b/src/riddley/walk.clj @@ -31,8 +31,7 @@ (inline-fn '(+ 1 2)) ; -> #function[clojure.core/nary-inline/fn--5541] (inline-fn '(+ 1 2)) ; -> nil" [form] - (when (and (seq? form) - (not (::transformed (meta form)))) + (when (seq? form) (let [[fn-symbol & args] form] (when (symbol? fn-symbol) ;; a function is inlineable if it has an `:inline` function in its metadata, and, if it has an @@ -50,16 +49,9 @@ ([form special-form?] (let [inline-fn (or (inline-fn form) - (throw (ex-info "Form is not an inlineable function call." {:form form}))) - expanded (with-meta (apply inline-fn (rest form)) (meta form))] + (throw (ex-info "Form is not an inlineable function call." {:form form})))] (macroexpand - ;; unfortunately, static function calls can look a lot like what we just - ;; expanded, so prevent infinite expansion - (if (head= expanded '.) - (with-meta - (concat (butlast expanded) [(merge-meta (last expanded) {::transformed true})]) - (meta expanded)) - expanded) + (with-meta (apply inline-fn (rest form)) (meta form)) special-form?)))) (defn- expand-list-like diff --git a/test/riddley/walk_test.clj b/test/riddley/walk_test.clj index 6c9173c..ebb9980 100644 --- a/test/riddley/walk_test.clj +++ b/test/riddley/walk_test.clj @@ -50,10 +50,7 @@ `(int 1) true `(n 1) nil `+ nil - `n nil} - ;; any form with `::transformed` in its metadata should always come back as nil - [form expected] [[form expected] - [(with-meta form {:riddley.walk/transformed true}) nil]]] + `n nil}] (testing (binding [*print-meta* true] (pr-str (list 'inline-fn? form))) (if expected (is (fn? (r/inline-fn form))) @@ -70,12 +67,12 @@ (deftest expand-inline-fn-test (is (= '(. clojure.lang.Numbers (and 2 1)) - (r/expand-inline-fn '(bit-and 2 1) nil))) + (r/expand-inline-fn '(bit-and 2 1)))) (testing "Should throw an Exception if the form is not inlineable" (is (thrown-with-msg? clojure.lang.ExceptionInfo #"Form is not an inlineable function call" - (r/expand-inline-fn '(+ 1) nil))))) + (r/expand-inline-fn '(+ 1)))))) (deftest test-walk-exprs ;; the first and third numbers get incremented, but not the second @@ -223,3 +220,22 @@ (deftest meta-data-on-inline-function-macro-expasion (is (= {:foo :bar} (meta (r/macroexpand (with-meta '(+ 1 1) {:foo :bar})))))) + +(deftest expand-nested-inline-fn-calls-test + (testing "Nested inlined function calls should get expanded correctly (#33)" + (is (= '(. + clojure.lang.Util + clojure.core/equiv + (. clojure.lang.RT (clojure.core/count [1 2])) + (. clojure.lang.RT (clojure.core/count [3 4]))) + (r/macroexpand-all `(= (count [1 2]) (count [3 4])))))) + (testing "Make sure inline functions that are expanded to Java methods with the same name don't cause infinite recursive expansion" + (testing "(inc 1) expands to (. clojure.lang.Numbers (inc 1)) -- make sure the resultant `(inc 1)` isn't expanded again" + (is (= '(. clojure.lang.Numbers (inc 1)) + (r/macroexpand-all `(inc 1))))) + (testing "(. clojure.lang.Numbers (inc 1)) on its own shouldn't get expanded" + (is (= '(. clojure.lang.Numbers (inc 1)) + (r/macroexpand-all '(. clojure.lang.Numbers (inc 1)))))) + (testing "(inc (inc 1)) *should* have get its nested inc call expanded" + (is (= '(. clojure.lang.Numbers (inc (. clojure.lang.Numbers (inc 1)))) + (r/macroexpand-all `(inc (inc 1))))))))