Skip to content

Commit 7ddab96

Browse files
frenchy64lread
andauthored
Close #305: Qualify @ ~ ~@ sexpr's under clojure.core (#306)
* Qualify @ ~ ~@ sexpr's under clojure.core z/sexpr should return the same value as clojure.core/read-string as per the documentation. The tests were moved from clojure.tools.reader.edn/read-string to clojure.tools.reader/read-string because the latter implements Clojure's reader. After this commit, the only special forms that return different values are ` and #=. * test & ci: bump sci-test for new tools.reader vars * lib test: patch zprint to disable new failing test See kkinnear/zprint#333 --------- Co-authored-by: lread <[email protected]>
1 parent 29e39a2 commit 7ddab96

File tree

7 files changed

+67
-36
lines changed

7 files changed

+67
-36
lines changed

deps.edn

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137

138138
:sci-test {:extra-paths ["target/generated/sci-test/src"]
139139
:extra-deps {lread/sci-test {:git/url "https://github.com/lread/sci-test.git"
140-
:sha "5adc46b18efa8661c9c86bb79c0876265cf6612a"}}}
140+
:sha "27318786f077d491c9cbc0c9d99e5781d9a9ef83"}}}
141141

142142
:native-test {:extra-paths ["target/generated/graal"]}
143143

doc/01-user-guide.adoc

+9-3
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ a|<unsupported operation>
10621062

10631063
2+a|*Deref* `:deref`
10641064
a|`@form`
1065-
a|`(deref form)`
1065+
a|`(clojure.core/deref form)`
10661066

10671067
2+a|*Metadata* `:meta`
10681068
a|`^{:a 1 :b 2} [1 2 3]`
@@ -1098,7 +1098,11 @@ a|`(quote symbol)`
10981098

10991099
2+a|*Syntax unquote* `:unquote`
11001100
a|`~symbol`
1101-
a|`(unquote symbol)`
1101+
a|`(clojure.core/unquote symbol)`
1102+
1103+
2+a|*Unquote splicing* `:unquote-spliciing`
1104+
a|`~@symbol`
1105+
a|`(clojure.core/unquote-splicing symbol)`
11021106

11031107
2+a|*Tagged literal* `:reader-macro`
11041108
a|`#foo/bar [1 2 3]`
@@ -1181,7 +1185,7 @@ a|`'#::my-ns-alias{my-symbol 1}`
11811185

11821186
==== Rewrite-clj Default Auto-Resolve Handling
11831187

1184-
When calling `sepxr` on an auto-resolved keyword or symbol node, rewrite-clj will resolve:
1188+
When calling `sexpr` on an auto-resolved keyword or symbol node, rewrite-clj will resolve:
11851189

11861190
* the current namespace to `?\_current-ns_?`
11871191
* namespaced alias `x` to `??\_x_??`
@@ -1202,6 +1206,8 @@ To illustrate:
12021206
;; => #:??_my-alias_??{s1 3, :b 2, :a 1}
12031207
----
12041208

1209+
Currently, symbols under syntax quote are never resolved.
1210+
12051211
[#custom-auto-resolve]
12061212
==== Custom Auto-Resolve Handling
12071213

doc/design/namespaced-elements.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ The following rewrite-clj nodes throw an exception for `sexpr` which is sensible
102102
- whitespace
103103
- uneval, which is rewrite-clj's term for `#_`
104104

105+
The following nodes have different `sexpr` representations than if you called `read-string`:
106+
107+
- read eval
108+
- syntax quote
109+
105110
=== Sexpr support for namespaced elements in rewrite-clj v0 and rewrite-cljs
106111
_Auto-resolved_ keywords have been around https://groups.google.com/g/clojure/c/i770QaIFiF0/m/v63cZgrlBwAJ[since at least Clojure 1.0, which was released in May 2009].
107112
https://github.com/clojure/clojure/blob/master/changes.md#12-support-for-working-with-maps-with-qualified-keys[Namespaced maps were introduced in Clojure 1.9, released in December 2017].

script/test_libs.clj

+11-2
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,16 @@
245245
(string/replace #"\[lein-zprint \"1.2.4\"\]"
246246
"[lein-zprint \"1.2.4.1\"]")
247247
(->> (spit p))))
248-
(show-patch-diff lib))
248+
;; zprint 1.2.9 has a single failing test for https://github.com/clj-commons/rewrite-clj/pull/306
249+
;; Have raised this with over at zprint https://github.com/kkinnear/zprint/issues/333
250+
;; and have agreement that it is a zprint issue.
251+
;; Disable the failing test which starts on line 2538
252+
(status/line :detail "Patching for failing test in v1.2.9")
253+
(let [p (str (fs/file home-dir "test/zprint/guide_test.cljc"))
254+
lines (-> p slurp string/split-lines)
255+
new-lines (update lines 2537 #(str "#_" %))]
256+
(->> (string/join "\n" new-lines)
257+
(spit p))))
249258

250259
(defn- zprint-prep [{:keys [home-dir]}]
251260
(status/line :detail "=> Building uberjar for uberjar tests")
@@ -449,7 +458,7 @@
449458
:test-cmds ["lein test"]}
450459
{:name "zprint"
451460
:version "1.2.9"
452-
:note "1) planck cljs tests disabled for now: https://github.com/planck-repl/planck/issues/1088"
461+
:note "1) planck cljs tests disabled for now: https://github.com/planck-repl/planck/issues/1088 2) failing v1.2.9 test disabled"
453462
:platforms [:clj :cljs]
454463
:github-release {:repo "kkinnear/zprint"}
455464
:patch-fn zprint-patch

src/rewrite_clj/node/quote.cljc

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
[children]
111111
(if (sequential? children)
112112
(->node
113-
:unquote "~" 'unquote
113+
:unquote "~" 'clojure.core/unquote
114114
children)
115115
(recur [children])))
116116

@@ -135,6 +135,6 @@
135135
[children]
136136
(if (sequential? children)
137137
(->node
138-
:unquote-splicing "~@" 'unquote-splicing
138+
:unquote-splicing "~@" 'clojure.core/unquote-splicing
139139
children)
140140
(recur [children])))

src/rewrite_clj/node/reader_macro.cljc

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
(node-type [_node] :deref)
6969
(printable-only?[_node] false)
7070
(sexpr* [_node opts]
71-
(list* 'deref (node/sexprs children opts)))
71+
(list* 'clojure.core/deref (node/sexprs children opts)))
7272
(length [_node]
7373
(inc (node/sum-lengths children)))
7474
(string [_node]

test/rewrite_clj/parser_test.cljc

+38-27
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
(ns ^{:doc "Tests for EDN parser."
22
:author "Yannick Scherer"}
33
rewrite-clj.parser-test
4-
(:refer-clojure :exclude [read-string])
54
(:require [clojure.string :as string]
6-
[clojure.test :refer [deftest is]]
7-
[clojure.tools.reader.edn :refer [read-string]]
5+
[clojure.test :refer [deftest is testing]]
6+
[clojure.tools.reader :as rdr]
87
[rewrite-clj.node :as node]
98
[rewrite-clj.parser :as p])
109
#?(:clj (:import [clojure.lang ExceptionInfo]
@@ -130,29 +129,40 @@
130129
:default (is (Double/isNaN e)))))
131130

132131
(deftest t-parsing-reader-prefixed-data
133-
(doseq [[s t ws sexpr]
134-
[["@sym" :deref [] '(deref sym)]
135-
["@ sym" :deref [:whitespace] '(deref sym)]
136-
["'sym" :quote [] '(quote sym)]
137-
["' sym" :quote [:whitespace] '(quote sym)]
138-
["`sym" :syntax-quote [] '(quote sym)]
139-
["` sym" :syntax-quote [:whitespace] '(quote sym)]
140-
["~sym" :unquote [] '(unquote sym)]
141-
["~ sym" :unquote [:whitespace] '(unquote sym)]
142-
["~@sym" :unquote-splicing [] '(unquote-splicing sym)]
143-
["~@ sym" :unquote-splicing [:whitespace] '(unquote-splicing sym)]
144-
["#=sym" :eval [] '(eval 'sym)]
145-
["#= sym" :eval [:whitespace] '(eval 'sym)]
146-
["#'sym" :var [] '(var sym)]
147-
["#'\nsym" :var [:newline] '(var sym)]]]
148-
(let [n (p/parse-string s)
149-
children (node/children n)
150-
c (map node/tag children)]
151-
(is (= t (node/tag n)))
152-
(is (= :token (last c)))
153-
(is (= sexpr (node/sexpr n)))
154-
(is (= 'sym (node/sexpr (last children))))
155-
(is (= ws (vec (butlast c)))))))
132+
(doseq [[ s t ws sexpr ltag lcld]
133+
[["@sym" :deref [] '@sym :token 'sym]
134+
["@ sym" :deref [:whitespace] '@sym :token 'sym]
135+
["'sym" :quote [] ''sym :token 'sym]
136+
["' sym" :quote [:whitespace] ''sym :token 'sym]
137+
["`sym" :syntax-quote [] ''sym :token 'sym]
138+
["` sym" :syntax-quote [:whitespace] ''sym :token 'sym]
139+
["~sym" :unquote [] '~sym :token 'sym]
140+
["~ sym" :unquote [:whitespace] '~sym :token 'sym]
141+
["~@sym" :unquote-splicing [] '~@sym :token 'sym]
142+
["~@ sym" :unquote-splicing [:whitespace] '~@sym :token 'sym]
143+
["~ @sym" :unquote [:whitespace] '~ @sym :deref '@sym]
144+
["#=sym" :eval [] '(eval 'sym) :token 'sym]
145+
["#= sym" :eval [:whitespace] '(eval 'sym) :token 'sym]
146+
["#'sym" :var [] '#'sym :token 'sym]
147+
["#'\nsym" :var [:newline] '#'sym :token 'sym]]]
148+
(testing (pr-str s)
149+
(let [n (p/parse-string s)
150+
children (node/children n)
151+
c (map node/tag children)]
152+
(is (= t (node/tag n)) "tag")
153+
(is (= ltag (last c)) "ltag")
154+
(is (= sexpr (node/sexpr n)) "sexpr")
155+
(is (= s (node/string n)) "string")
156+
;; ` and #= return different sexpr's than via clojure.core/read-string
157+
(when-not (#{:syntax-quote :eval} t)
158+
(is (= sexpr
159+
#?(:cljs (rdr/read-string s)
160+
:default (binding [rdr/*read-eval* false] (rdr/read-string s)))
161+
#?@(:cljs []
162+
:default [(binding [*read-eval* false] (read-string s))]))
163+
"read-string"))
164+
(is (= lcld (node/sexpr (last children))) "lcld")
165+
(is (= ws (vec (butlast c))) "ws")))))
156166

157167
(deftest t-eval
158168
(let [n (p/parse-string "#=(+ 1 2)")]
@@ -223,7 +233,8 @@
223233
fq (frequencies (map node/tag children))]
224234
(is (= t (node/tag n)))
225235
(is (= (string/trim s) (node/string n)))
226-
(is (= (node/sexpr n) (read-string s)))
236+
(is (= (node/sexpr n) #?(:cljs (rdr/read-string s)
237+
:default (binding [rdr/*read-eval* false] (rdr/read-string s)))))
227238
(is (= w (:whitespace fq 0)))
228239
(is (= c (:token fq 0))))))
229240

0 commit comments

Comments
 (0)