Skip to content

Commit 180902a

Browse files
authored
support evaluation of quoted regex (#766)
Closes #741.
1 parent c27943d commit 180902a

File tree

7 files changed

+34
-17
lines changed

7 files changed

+34
-17
lines changed

.clj-kondo/config.edn

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@
3636
clojure.set
3737
clojure.walk]}}}
3838
clojure.test/deftest {:linters {:inline-def {:level :off}}}
39-
shadow.cljs.modern/defclass {:linters {:redefined-var {:level :off}}}}}
39+
shadow.cljs.modern/defclass {:linters {:redefined-var {:level :off}}}
40+
nextjournal.clerk.utils/if-bb {:linters {:condition-always-true {:level :off}}}}}

deps.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{:paths ["src" "resources" "bb"]
22
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
33
org.clojure/java.classpath {:mvn/version "1.0.0"}
4-
babashka/fs {:mvn/version "0.5.22"}
4+
babashka/fs {:mvn/version "0.5.27"}
55
org.babashka/http-client {:mvn/version "0.4.23"}
66
borkdude/edamame {:mvn/version "1.4.28"}
77
weavejester/dependency {:mvn/version "0.2.1"}

src/nextjournal/clerk/analyzer.clj

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@
534534
analyze-doc-deps
535535
set-no-cache-on-redefs
536536
make-deps-inherit-no-cache
537-
(dissoc :analyzed-file-set :counter))))))
537+
(dissoc :analyzed-file-set :counter))))))
538538

539539
(comment
540540
(reset! !file->analysis-cache {})
@@ -572,8 +572,7 @@
572572

573573

574574
(defn ^:private canonicalize-form
575-
"Undoes the non-deterministic transformations done by the splicing
576-
reader macro."
575+
"Undoes the non-deterministic transformations done by the splicing reader macro."
577576
[form]
578577
(walk/postwalk (fn [f]
579578
(if-let [orig-name (and (simple-symbol? f)
@@ -589,7 +588,7 @@
589588

590589
(defn hash-codeblock [->hash {:keys [ns graph record-missing-hash-fn]} {:as codeblock :keys [hash form id vars graph-node]}]
591590
(let [deps (when id (dep/immediate-dependencies graph id))
592-
hashed-deps (into #{} (keep ->hash) deps)]
591+
hashed-deps (into (sorted-set) (keep ->hash) deps)]
593592
;; NOTE: missing hashes on deps might occur e.g. when some dependencies are interned at runtime
594593
(when record-missing-hash-fn
595594
(when-some [dep-with-missing-hash
@@ -600,9 +599,14 @@
600599
(record-missing-hash-fn (assoc codeblock
601600
:dep-with-missing-hash dep-with-missing-hash
602601
:graph-node graph-node :ns ns))))
603-
(sha1-base58 (binding [*print-length* nil]
604-
(pr-str (set/union (conj hashed-deps (if form (-> form remove-type-meta canonicalize-form) hash))
605-
vars))))))
602+
(binding [*print-length* nil]
603+
(let [form-with-deps-sorted
604+
(-> hashed-deps
605+
(conj (if form
606+
(-> form remove-type-meta canonicalize-form pr-str)
607+
hash))
608+
(into (map str) vars))]
609+
(sha1-base58 (pr-str form-with-deps-sorted))))))
606610

607611
#_(hash-codeblock {} {:graph (dep/graph)} {})
608612
#_(hash-codeblock {} {:graph (dep/graph)} {:hash "foo"})

src/nextjournal/clerk/parser.cljc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
(defn read-string [s]
3535
(edamame/parse-string s {:all true
3636
:read-cond :allow
37-
:regex #(list `re-pattern %)
3837
:features #?(:bb #{:bb :clj}
3938
:default #{:clj})
4039
:end-location false

test/nextjournal/clerk/analyzer_test.clj

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,25 @@
302302
(is (not (:no-cache? (get ->analysis-info 'nextjournal.clerk.analyzer-test.redefs/a#2))))))
303303

304304

305-
(testing "hashing is determistics for splicing reader macros"
305+
(testing "hashing is deterministic for auto-gensym-ed symbols in syntax-quote"
306306
(let [hash-single-form (fn [form]
307307
(ana/hash-codeblock {} {:graph (dep/graph)} (ana/analyze form)))]
308308
(is (= (hash-single-form `(let [a# 1]
309309
(inc a#)))
310310
(hash-single-form `(let [a# 1]
311-
(inc a#))))))))
311+
(inc a#)))))))
312+
313+
(testing "hashing is deterministic for regexes"
314+
(let [regex-graph #(->
315+
(parser/parse-clojure-string "
316+
(def id identity)
317+
318+
[+ - id #\"my\"]")
319+
(ana/analyze-doc)
320+
(ana/build-graph)
321+
(ana/hash)
322+
:->hash)]
323+
(apply = (repeatedly 100 regex-graph)))))
312324

313325
(deftest analyze-doc
314326
(utils/when-not-bb
@@ -428,7 +440,7 @@ my-uuid")]
428440
(is (:dep-with-missing-hash missing-hash-report)))))
429441

430442
(deftest ->hash
431-
(testing "notices change in depedency namespace"
443+
(testing "notices change in dependency namespace"
432444
(let [test-var 'nextjournal.clerk.fixtures.generated.my-test-ns/hello
433445
test-string "(ns test (:require [nextjournal.clerk.fixtures.generated.my-test-ns :as my-test-ns])) (str my-test-ns/hello)"
434446
spit-with-value #(spit (format "test%s%s.clj" fs/file-separator (str/replace (namespace-munge (namespace test-var)) "." fs/file-separator ))

test/nextjournal/clerk/eval_test.clj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,8 @@
286286
(testing "show with ns arg"
287287
(clerk/show! 'nextjournal.clerk.fixtures.hello)
288288
(is (fs/exists? (:file (meta (resolve 'nextjournal.clerk.fixtures.hello/answer)))))))
289+
290+
(deftest issue-741-can-eval-quoted-regex-test
291+
(is (match? {:blocks [{:type :code,
292+
:result {:nextjournal/value "foo"}}]}
293+
(eval/eval-string "(re-find '#\"foo\" \"foobar\")"))))

test/nextjournal/clerk/parser_test.clj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,6 @@ par two"))))
167167
"^{:un :balanced :map} (do nothing)"))))
168168

169169
(deftest read-string-tests
170-
(testing "read-string should read regex's such that value equalility is preserved"
171-
(is (= '(fn [x] (clojure.string/split x (clojure.core/re-pattern "/")))
172-
(parser/read-string "(fn [x] (clojure.string/split x #\"/\"))"))))
173-
174170
(testing "read-string can handle syntax quote"
175171
(is (match? '['nextjournal.clerk.parser-test/foo 'nextjournal.clerk.view/foo 'nextjournal.clerk/foo]
176172
(binding [*ns* (find-ns 'nextjournal.clerk.parser-test)]

0 commit comments

Comments
 (0)