[Git][clojure-team/riddley-clojure][upstream] New upstream version 0.2.0

Louis-Philippe Véronneau gitlab at salsa.debian.org
Thu Dec 3 17:50:59 GMT 2020



Louis-Philippe Véronneau pushed to branch upstream at Debian Clojure Maintainers / riddley-clojure


Commits:
e27fc436 by Louis-Philippe Véronneau at 2020-12-02T13:51:19-05:00
New upstream version 0.2.0
- - - - -


5 changed files:

- .travis.yml
- README.md
- project.clj
- src/riddley/walk.clj
- test/riddley/walk_test.clj


Changes:

=====================================
.travis.yml
=====================================
@@ -1,7 +1,4 @@
 language: clojure
-lein: lein2
-script: lein2 do clean, test
+script: lein do clean, test
 jdk:
-  - openjdk7
-  - oraclejdk7
-  - openjdk6
\ No newline at end of file
+  - openjdk8
\ No newline at end of file


=====================================
README.md
=====================================
@@ -16,14 +16,14 @@ Code may be data, but only some of that data is executable.  If we want to perfo
 * `clojure.walk/macroexpand-all` will pass in a nil `&env` to all macros
 * macroexpansion doesn't expand inlined functions
 
-This means that transforms that we intend to apply to expressions may have unintended consequences on a `fn`, `let`, or `case` form.  It also means that any macro which relies on `&env` will not compose with our transformation.  Finally, if inlined functions aren't expanded, this can break certain transformations.
+This means that transforms that we intend to apply to expressions may have unintended consequences on a `fn`, `let`, or `case` form.  It also means that any macro which relies on `&env` will not compose with our transformation.  Finally, if inlined functions aren't expanded, certain transformations will break.
 
 ### usage
 
 [![Build Status](https://travis-ci.org/ztellman/riddley.png?branch=master)](https://travis-ci.org/ztellman/riddley)
 
 ```clj
-[riddley "0.1.12"]
+[riddley "0.2.0"]
 ```
 
 Riddley provides a correct `riddley.walk/macroexpand-all`, which preserves the binding information in `&env` and expands inlined functions, and `riddley.walk/walk-exprs`, which is a general mechanism for code walking and transformation.
@@ -39,7 +39,7 @@ Notice that `walk-exprs` implicitly macroexpands the form, including the inline
 
 Access to `&env` is available via `(riddley.compiler/locals)` if you need it as part of your transformation.
 
-Full documentation can be found [here](http://ideolalia.com/riddley/).
+Full documentation can be found [here](http://aleph.io/codox/riddley/).
 
 ### license
 


=====================================
project.clj
=====================================
@@ -1,4 +1,4 @@
-(defproject riddley "0.1.14"
+(defproject riddley "0.2.0"
   :description "code-walking without caveats"
   :license {:name "MIT License"
             :url "http://opensource.org/licenses/MIT"}


=====================================
src/riddley/walk.clj
=====================================
@@ -55,6 +55,12 @@
 
 ;;;
 
+(def ^:private special-forms
+  (into #{} (keys (. clojure.lang.Compiler specials))))
+
+(defn- special-meta [[op & body]]
+  (list* (vary-meta op assoc ::special true) body))
+
 (defn- do-handler [f [_ & body]]
   (list* 'do
     (doall
@@ -93,15 +99,17 @@
       (cmp/register-local n '())
       (list* 'def (f n) (doall (map f r))))))
 
-(defn- let-bindings [f x]
-  (->> x
-    (partition-all 2)
-    (mapcat
-      (fn [[k v]]
-        (let [[k v] [k (f v)]]
-          (cmp/register-local k v)
-          [k v])))
-    vec))
+(defn- let-bindings [f x recursive?]
+  (let [pairs (partition-all 2 x)]
+    (when recursive?
+      (doall (map (fn [[k v]] (cmp/register-local k nil)) pairs)))
+    (->> pairs
+         (mapcat
+           (fn [[k v]]
+             (let [[k v] [k (f v)]]
+               (cmp/register-local k v)
+               [k v])))
+         vec)))
 
 (defn- reify-handler [f x]
   (let [[_ classes & fns] x]
@@ -130,13 +138,19 @@
                 (list* nm args (doall (map f body)))))
             fns))))))
 
-(defn- let-handler [f x]
-  (cmp/with-lexical-scoping
-    (doall
-      (list*
-        (first x)
-        (let-bindings f (second x))
-        (map f (drop 2 x))))))
+(defn- let-handler
+  ([f x]
+   (let-handler f x nil))
+  ([f x recursive?]
+   (cmp/with-lexical-scoping
+     (doall
+       (list*
+         (first x)
+         (let-bindings f (second x) recursive?)
+         (map f (drop 2 x)))))))
+
+(defn- letfn-handler [f x]
+  (let-handler f x true))
 
 (defn- case-handler [f [_ ge shift mask default imap switch-type check-type skip-check]]
   (let [prefix  ['case* ge shift mask]
@@ -162,6 +176,10 @@
       (list* 'catch type var
         (doall (map f body))))))
 
+(defn- try-handler [f x]
+  (let [[_ & body] x]
+    (list* 'try (doall (map #(f % :try-clause? true) body)))))
+
 (defn- dot-handler [f x]
   (let [[_ hostexpr mem-or-meth & remainder] x]
     (list* '.
@@ -183,10 +201,13 @@
 
    Macroexpansion can be halted by defining a set of `special-form?` which will be left alone.
    Including `fn`, `let`, or other binding forms can break local variable analysis, so use
-   with caution."
+   with caution.
+
+   The :try-clause? option indicates that a `try` clause is being walked. The special forms
+   `catch` and `finally` are only special in `try` clauses."
   ([predicate handler x]
      (walk-exprs predicate handler nil x))
-  ([predicate handler special-form? x]
+  ([predicate handler special-form? x & {:keys [try-clause?]}]
      (cmp/with-base-env
        (let [x (try
                  (macroexpand x special-form?)
@@ -205,20 +226,25 @@
                   (handler x)
 
                   (seq? x)
-                  ((condp = (first x)
-                     'do     do-handler
-                     'def    def-handler
-                     'fn*    fn-handler
-                     'let*   let-handler
-                     'loop*  let-handler
-                     'letfn* let-handler
-                     'case*  case-handler
-                     'catch  catch-handler
-                     'reify* reify-handler
-                     'deftype* deftype-handler
-                     '.      dot-handler
-                     #(doall (map %1 %2)))
-                   walk-exprs' x)
+                  (if (or (and (not try-clause?)
+                               (#{'catch 'finally} (first x)))
+                          (not (contains? special-forms (first x))))
+                    (doall (map walk-exprs' x))
+                    ((condp = (first x)
+                       'do        do-handler
+                       'def       def-handler
+                       'fn*       fn-handler
+                       'let*      let-handler
+                       'loop*     let-handler
+                       'letfn*    letfn-handler
+                       'case*     case-handler
+                       'try       try-handler
+                       'catch     catch-handler
+                       'reify*    reify-handler
+                       'deftype*  deftype-handler
+                       '.         dot-handler
+                       #(doall (map %1 %2)))
+                     walk-exprs' (special-meta x)))
 
                   (instance? java.util.Map$Entry x)
                   (clojure.lang.MapEntry.
@@ -252,3 +278,8 @@
   "Recursively macroexpands all forms, preserving the &env special variables."
   [x]
   (walk-exprs (constantly false) nil x))
+
+(defn special-form?
+  "Given sym, a symbol produced by walk-exprs, returns true if sym is a special form."
+  [x]
+  (when (symbol? x) (::special (meta x))))


=====================================
test/riddley/walk_test.clj
=====================================
@@ -1,6 +1,7 @@
 (ns riddley.walk-test
   (:require
     [clojure.test :refer :all]
+    [riddley.compiler :as c]
     [riddley.walk :as r]))
 
 (defmacro inc-numbers [& body]
@@ -9,6 +10,24 @@
     inc
     `(do ~@body)))
 
+(defmacro external-references [expr]
+  (let [log (atom #{})]
+    (r/walk-exprs
+      symbol?
+      (fn [x]
+        (when (or (contains? &env x)
+                  (not (contains? (c/locals) x)))
+          (swap! log conj x))
+        x)
+      expr)
+    (list 'quote @log)))
+
+(defmacro identify-special-forms [expr]
+  (list 'quote (r/walk-exprs
+                 symbol?
+                 (comp boolean r/special-form?)
+                 expr)))
+
 (defrecord Test [x])
 
 (defprotocol TestP
@@ -77,6 +96,44 @@
             '#'riddley.walk-test/foo)
            @acc))))
 
+(deftest try-catch-finally-locals
+  (is (= '(let* [catch inc, finally dec, throw +]
+            (try (throw (catch 100) (finally 200))
+                 (catch Exception e)
+                 (finally nil)))
+
+         (r/walk-exprs (constantly false) identity
+           '(let [catch inc, finally dec, throw +]
+             (try (throw (catch 100) (finally 200))
+                  (catch Exception e)
+                  (finally nil)))))))
+
+(deftest try-catch-finally-locals-in-env
+  (let [catch inc, finally dec, throw +]
+    (is (= nil ((external-references
+                  (try (throw (catch 100) (finally 200))
+                       (catch Exception e)
+                       (finally nil)))
+                'e)))))
+
+(deftest letfn-binds-locals-recursively
+  (is (= nil ((external-references
+                (letfn [(f1 [x] (inc (f2 x)))
+                        (f2 [x] (* x 100))]
+                  (f1 (f2 100))))
+              'f2))))
+
+(deftest special-forms-identified
+  (is (= (identify-special-forms
+           (let* [catch inc, finally dec, throw +]
+             (try (throw (catch 100) (finally 200))
+                  (catch Exception e)
+                  (finally nil))))
+         '(let* [catch false, finally false, throw false]
+            (try (true (false 100) (false 200))
+                 (catch Exception e)
+                 (true nil))))))
+
 (deftest catch-old-fn*-syntax
   (is (= (r/walk-exprs (constantly false) identity
                        '(fn* tst [x seq]))



View it on GitLab: https://salsa.debian.org/clojure-team/riddley-clojure/-/commit/e27fc436a333c916a6ed90b715a40210e82eccd2

-- 
View it on GitLab: https://salsa.debian.org/clojure-team/riddley-clojure/-/commit/e27fc436a333c916a6ed90b715a40210e82eccd2
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20201203/2f2d1d66/attachment.html>


More information about the pkg-java-commits mailing list