Skip to content
Open
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
## Unreleased

- Fix [#815](https://github.com/squint-cljs/squint/issues/815): `str` wrapping known-numeric infix expressions in `??''`, which esbuild flagged as `suspicious-nullish-coalescing`.
- Populate `:macro-aliases` from `:require :as` so downstream macro
resolvers (e.g. cherry's sci ctx) can find built-in macros under
the alias.
- `:cherry` target of `resolve-ns` now honors the `:resolve-ns` env
hook for non-builtin symbol libnames, matching the existing
`:squint` target behavior.
- Filter `:refer`'d macros via env-supplied `:built-in-macro-nss`
map (`{libname-sym #{macro-syms}}`), so hosts (e.g. cherry) can
register additional macro namespaces beyond the hardcoded
`cljs.test`/`clojure.test`/etc set without patching squint.

## 0.11.189

Expand Down
15 changes: 13 additions & 2 deletions src/squint/compiler_common.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,12 @@
(cljs.set clojure.set) "cherry-cljs/lib/clojure.set.js"
(cljs.pprint clojure.pprint) "cherry-cljs/lib/cljs.pprint.js"
(cljs.test clojure.test) "cherry-cljs/lib/clojure.test.js"
alias)
(if (symbol? alias)
(if-let [resolve-ns (:resolve-ns env)]
(or (resolve-ns alias)
alias)
alias)
(resolve-import-map import-maps alias)))
alias)))

(defmethod emit #?(:clj clojure.lang.Symbol :cljs Symbol) [expr env]
Expand Down Expand Up @@ -763,7 +768,10 @@
(get rename refer refer)) refer)
(repeat (if (symbol? original-libname)
original-libname libname)))))))))
(let [runtime-refer (remove #(builtin-refer-is-macro? original-libname %) refer)]
(let [runtime-refer (remove (fn [refer-sym]
(or (builtin-refer-is-macro? original-libname refer-sym)
(contains? (get (:built-in-macro-nss env) original-libname) refer-sym)))
refer)]
(str
(when (seq runtime-refer)
(let [referred+renamed (str/join ", "
Expand Down Expand Up @@ -818,6 +826,9 @@
as
(update-in [current :aliases] (fn [aliases]
((fnil assoc {}) aliases as libname)))
(and as (symbol? original-libname))
(update-in [current :macro-aliases]
(fn [aliases] (merge {as original-libname} aliases)))
(symbol? original-libname)
(update-in [current :aliases] (fn [aliases]
((fnil assoc {}) aliases
Expand Down
50 changes: 50 additions & 0 deletions test/squint/compiler_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
[squint.math-test]
[squint.multi-test]
[squint.string-test]
[squint.compiler-common :as cc]
[squint.test-utils :refer [eq js! jss! jsv!]]))

(deftest return-test
Expand Down Expand Up @@ -2889,6 +2890,55 @@ new Foo();")
_ (with-meta f {:name "foo"})]
(meta f)))))))

(deftest resolve-ns-hook-target-symmetry-test
(let [env {:resolve-ns (fn [alias] (str "./resolved/" alias ".mjs"))}]
(testing "the :resolve-ns env hook must be honored equally by both
:target :squint and :target :cherry for non-builtin symbol
libnames"
(binding [cc/*target* :squint]
(is (= "./resolved/some.lib.mjs" (cc/resolve-ns env 'some.lib))
":target :squint must honor :resolve-ns hook"))
(binding [cc/*target* :cherry]
(is (= "./resolved/some.lib.mjs" (cc/resolve-ns env 'some.lib))
":target :cherry must honor :resolve-ns hook")))
(testing ":cherry built-in libname mappings must still take precedence
over the :resolve-ns hook"
(binding [cc/*target* :cherry]
(is (= "cherry-cljs/lib/clojure.test.js" (cc/resolve-ns env 'cljs.test))
"cljs.test must resolve to its hardcoded cherry mapping")))))

(deftest built-in-macro-nss-filters-refers-test
(testing "symbols listed in (:built-in-macro-nss env) for a libname must
be filtered out of the runtime JS import; non-listed symbols
must still appear"
(let [src "(ns my.app (:require [some.lib :refer [my-macro my-fn]]))"
opts {:built-in-macro-nss {'some.lib #{'my-macro}}
:elide-imports false}
s (jss! src opts)]
(is (not (re-find #"\bmy_macro\b" s))
(str "my-macro listed in :built-in-macro-nss must NOT appear in JS import\n"
"compiled output:\n" s))
(is (re-find #"\bmy_fn\b" s)
(str "my-fn (not listed) must still appear in JS import\n"
"compiled output:\n" s)))))

(deftest require-as-populates-macro-aliases-test
(testing ":require :as must populate :macro-aliases (read by cherry's
sci ctx to expand alias-prefixed macros). Squint emits no
visible behavior change for this field; the contract is the
state mutation itself."
(let [state (atom {})]
(jss! "(ns my.app (:require [some.lib :as lib]))"
{:ns-state state})
(let [s @state
current (:current s)]
(is (= 'some.lib (get-in s [current :macro-aliases 'lib]))
(str ":macro-aliases must map alias->libname for :require :as\n"
"ns-state:\n" (pr-str s)))
(is (= "some.lib" (get-in s [current :aliases 'lib]))
(str ":aliases must map alias->libname-string for :require :as\n"
"ns-state:\n" (pr-str s)))))))

(defn init []
(t/run-tests 'squint.compiler-test
'squint.jsx-test
Expand Down
Loading