[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