 (defn load-core-noop [])
 
 (defmacro shadow-redefs [& body]
-  `(locking REDEF-LOCK
-     (with-redefs [ana/parse shadow-parse
-                   ana/load-core load-core-noop
-                   ana/analyze-form shadow-analyze-form]
-       ~@body)))
+  ;; FIXME: can't redef without the lock
+  ;; but the lock prevents multiple builds from running in parallel
+  #_(locking REDEF-LOCK
+      (with-redefs [ana/parse shadow-parse
+                    ana/load-core load-core-noop
+                    ana/analyze-form shadow-analyze-form]
+        ~@body))
+
+  `(do ~@body))
 
 (defn do-compile-sources
   "compiles with just the main thread, can do partial compiles assuming deps are compiled"

(defn get-closure-compiler [state]
  (::cc state))

(defonce stdout-lock (Object.))

(def stdout-log
  (reify log/BuildLog
    (log* [_ state evt]

      (rewrite-ns-aliases compiler-state)
      (assoc :env env :form form :op :ns)))

;; FIXME: this hijacks unconditionally which may break other CLJS tools
;; with-redefs is probably safer
(defmethod ana/parse 'ns
  [op env form name opts]
  (hijacked-parse-ns env form name opts))

(comment
  ;; FIXME: these rely on with-redefs which isn't threadsafe

  (def default-parse ana/parse)

  (defn shadow-parse [op env form name opts]
    (condp = op
      ;; the default ana/parse 'ns has way too many side effects we don't need or want
      ;; don't want analyze-deps -> never needed
      ;; don't want require or macro ns -> post-analyze
      ;; don't want check-uses -> doesn't recognize macros
      ;; don't want check-use-macros -> doesnt handle (:require [some-ns :refer (a-macro)])
      ;; don't want swap into compiler env -> post-analyze
      'ns (hijacked-parse-ns env form name opts)
      (default-parse op env form name opts)))

  (def default-analyze-form ana/analyze-form)

  ;; FIXME: doing this so I can access the form that caused a warning
  ;; some warnings do not include it, should really provide patches to add them
  ;; but this is simpler and an experiment anyways
  (defn shadow-analyze-form
    [env form name opts]
    (let [warnings-before
          @*cljs-warnings-ref*

          result
          (default-analyze-form env form name opts)

          warnings-after
          @*cljs-warnings-ref*]

      (when-not (identical? warnings-before warnings-after)
        (swap! *cljs-warnings-ref*
          (fn [warnings]
            (->> warnings
                 (map (fn [x]
                        (if (contains? x :form)
                          x
                          (assoc x :form form))))
                 (into [])
                 ))))
      result
      )))

(defn analyze
  ([state compile-state form]
