(defn macroexpand-1*
[env form]
(let [op (first form)]
(if (contains? specials op)
form
;else
(if-some [mac-var (when (symbol? op) (get-expander op env))]
(#?@(:clj [binding [*ns* (create-ns *cljs-ns*)]]
:cljs [do])
(let [mchk #?(:clj (some-> (find-ns 'clojure.spec.alpha)
(ns-resolve 'macroexpand-check))
:cljs (get-macroexpand-check-var))
_ (when (some? mchk)
(mchk mac-var (next form)))
form' (try
(apply @mac-var form env (rest form))
#?(:clj (catch ArityException e
(throw (ArityException. (- (.actual e) 2) (.name e))))))]
(if #?(:clj (seq? form') :cljs (cljs-seq? form'))
(let [sym' (first form')
sym (first form)]
(if #?(:clj (= sym' 'js*)
:cljs (symbol-identical? sym' JS_STAR_SYM))
(let [sym (if (some? (namespace sym))
sym
(symbol "cljs.core" (str sym)))
js-op {:js-op sym}
numeric #?(:clj (-> mac-var meta ::numeric)
:cljs (let [mac-var-ns (symbol (namespace (.-sym mac-var)))
mac-var-name (symbol (name (.-sym mac-var)))]
(get-in @env/*compiler*
[::namespaces mac-var-ns :defs mac-var-name :meta ::numeric])))
js-op (if (true? numeric)
(assoc js-op :numeric true)
js-op)]
(vary-meta form' merge js-op))
form'))
form')))
(if (symbol? op)
(let [opname (str op)]
(cond
(identical? \.
#?(:clj (first opname)
:cljs (.charAt opname 0)))
(let [[target & args] (next form)]
(with-meta (list* #?(:clj '. :cljs DOT_SYM) target (symbol (subs opname 1)) args)
(meta form)))
(identical? \.
#?(:clj (last opname)
:cljs (.charAt opname (dec (. opname -length)))))
(with-meta
(list* #?(:clj 'new :cljs NEW_SYM) (symbol (subs opname 0 (dec (count opname)))) (next form))
(meta form))
:else form))
form)))))