         (when-not (= :statement (:context env))
           (comp/emit-wrap env
             (comp/emits (comp/munge info))))))))
-
-(defmethod comp/emit* :var [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :binding [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :js-var [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :local [expr] (shadow-emit-var expr))
 
 ;; noop
 (defn shadow-load-core [])


  (replace-fn! #'cljs.core/exists? shadow-exists?)

  ;; remove these for now, not worth the trouble
  ;; (replace-fn! #'test/deftest @#'shadow-deftest)
  ;; (replace-fn! #'test/use-fixtures @#'shadow-use-fixtures)
  )


(in-ns 'cljs.compiler)

;; FIXME: patch this in CLJS. its the only externs inference call I can't work around
;; cljs will blindly generate (set! (.. Thing -prototype -something) ...) for
;; (deftype Thing []
;;   Object
;;   (something [...] ...))
;; but doesn't keep any kind of meta that something is being defined on Object
;; and that we should generate externs for it
(in-ns 'cljs.core)

;; multimethod in core, although I don't see how this is ever going to go past 2 impls?
;; also added the metadata for easier externs inference
;; switched .. to nested . since .. looses form meta
(defn- extend-prefix [tsym sym]
  (let [prop-sym (to-property sym)]
    (core/case (core/-> tsym meta :extend)
      :instance
      `(. ~tsym ~prop-sym)
      ;; :default
      `(. (. ~tsym ~'-prototype) ~prop-sym))))

(core/defn- add-obj-methods [type type-sym sigs]
  (map (core/fn [[f & meths :as form]]
         (core/let [[f meths] (if (vector? (first meths))
                                [f [(rest form)]]
                                [f meths])]
           `(set! ~(with-meta
                     (extend-prefix type-sym f)
                     {:shadow/object-fn f})
              ~(with-meta `(fn ~@(map #(adapt-obj-params type %) meths)) (meta form)))))
    sigs))


;; CLJS-3003
(core/defn- add-ifn-methods [type type-sym [f & meths :as form]]
  (core/let [this-sym (with-meta 'self__ {:tag type})
             argsym (gensym "args")

             ;; we are emulating JS .call where the first argument will become this inside the fn
             ;; but this is not actually what we want when emulating IFn since we need "this"
             ;; so the first arg is always dropped instead and we dispatch to the actual protocol fns
             call-fn
             `(fn [unused#]
                (this-as ~this-sym
                  (case (-> (js-arguments) (alength) (dec))
                    ~@(reduce
                        (core/fn [form [args & body]]
                          (core/let [arity (core/-> args (count) (core/dec))]
                            (conj
                              form
                              arity
                              (concat
                                (core/list
                                  (symbol (core/str ".cljs$core$IFn$_invoke$arity$" arity))
                                  this-sym)
                                (core/for [ar (range arity)]
                                  `(aget (js-arguments) ~(core/inc ar)))))))
                        []
                        meths)
                    (throw (js/Error. (str "Invalid arity: " (-> (js-arguments) (alength) (dec)))))
                    )))]

    (concat
      [`(set! ~(extend-prefix type-sym 'call) ~(with-meta call-fn (meta form)))
       `(set! ~(extend-prefix type-sym 'apply)
          ~(with-meta
             `(fn ~[this-sym argsym]
                (this-as ~this-sym
                  (.apply (.-call ~this-sym) ~this-sym
                    (.concat (array ~this-sym) (cljs.core/aclone ~argsym)))))
             (meta form)))]
      (ifn-invoke-methods type type-sym form))))

           (.replace \/ \$))
       "$"))

;; fixes an issue where the cljs.core variant assumes that `resolve-var` will only return
;; a js/foo symbol if x is also js/something which isn't true in many cases for shadow-cljs
;; where npm deps especially resolve some/foo to js/module$something.foo
