Skip to content

Commit 4b44c3e

Browse files
mfikesdnolen
authored andcommitted
CLJS-1542: Self-host: cljs/compile-str not handling errors properly
If you use cljs.js/compile-str on a form that cannot be analyzed, then the analysis error is wrapped, but inadvertently passed on to compilation as an AST structure. This results in the compiler derailing because it tries to process a nil :op. The fix is to employ the same pattern used in cljs.js/eval-str, namely: Wrap successful analysis in a {:value ast} map, and then additionally check for an :error key in the result and cb early, otherwise extract the :value and continue on to compilation.
1 parent 170cece commit 4b44c3e

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

src/main/cljs/cljs/js.cljs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -621,20 +621,23 @@
621621
(let [aenv (cond-> (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
622622
(:context opts) (assoc :context (:context opts))
623623
(:def-emits-var opts) (assoc :def-emits-var true))
624-
ast (try
625-
(ana/analyze aenv form nil opts)
624+
res (try
625+
{:value (ana/analyze aenv form nil opts)}
626626
(catch :default cause
627627
(wrap-error
628628
(ana/error aenv
629629
(str "Could not compile " name) cause))))]
630-
(.append sb (with-out-str (comp/emit ast)))
631-
(if (= :ns (:op ast))
632-
(ns-side-effects bound-vars aenv ast opts
633-
(fn [res]
634-
(if (:error res)
635-
(cb res)
636-
(compile-loop (:name ast)))))
637-
(recur ns)))
630+
(if (:error res)
631+
(cb res)
632+
(let [ast (:value res)]
633+
(.append sb (with-out-str (comp/emit ast)))
634+
(if (= :ns (:op ast))
635+
(ns-side-effects bound-vars aenv ast opts
636+
(fn [res]
637+
(if (:error res)
638+
(cb res)
639+
(compile-loop (:name ast)))))
640+
(recur ns)))))
638641
(do
639642
(when (:source-map opts)
640643
(append-source-map env/*compiler*

src/test/self/self_host/test.cljs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
(deftest test-analyze-str
5454
(async done
55-
(let [l (latch 2 done)]
55+
(let [l (latch 3 done)]
5656
(cljs/analyze-str st "(+ 1 1)" nil
5757
{:context :expr}
5858
(fn [{:keys [error value]}]
@@ -63,11 +63,17 @@
6363
{:context :expr}
6464
(fn [{:keys [error value]}]
6565
(is (nil? error))
66+
(inc! l)))
67+
(cljs/analyze-str st "(fn [] (let [x 7 y] (prn y)))" nil
68+
{:context :expr}
69+
(fn [{:keys [error value]}]
70+
(is (nil? value))
71+
(is (= "Could not analyze " (ex-message error)))
6672
(inc! l))))))
6773

6874
(deftest test-compile-str
6975
(async done
70-
(let [l (latch 6 done)]
76+
(let [l (latch 7 done)]
7177
(cljs/compile-str st "(+ 1 1)"
7278
(fn [{:keys [error value]}]
7379
(is (nil? error))
@@ -103,6 +109,12 @@
103109
(fn [{:keys [error value]}]
104110
(is (nil? error))
105111
(is (string/index-of value "cljs.user.foo((1),(2))"))
112+
(inc! l)))
113+
(cljs/compile-str st "(fn [] (let [x 7 y] (prn y)))" nil
114+
{:context :expr}
115+
(fn [{:keys [error value]}]
116+
(is (nil? value))
117+
(is (= "Could not compile " (ex-message error)))
106118
(inc! l))))))
107119

108120
(deftest test-eval-str

0 commit comments

Comments
 (0)