Skip to content

Commit 9c1c727

Browse files
author
dnolen
committed
CLJS-2678: Infer-externs doesn't work for JS modules using global-exports
1 parent c37442c commit 9c1c727

3 files changed

Lines changed: 43 additions & 22 deletions

File tree

src/main/clojure/cljs/analyzer.cljc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,13 @@
976976

977977
(defmethod resolve* :global
978978
[sym full-ns current-ns]
979-
{:name (symbol (str current-ns) (str (munge-global-export full-ns) "." (name sym)))
980-
:ns current-ns})
979+
(let [pre (into '[Object] (->> (string/split (name sym) #"\.") (map symbol) vec))]
980+
(when-not (has-extern? pre)
981+
(swap! env/*compiler* update-in
982+
(into [::namespaces current-ns :externs] pre) merge {}))
983+
{:name (symbol (str current-ns) (str (munge-global-export full-ns) "." (name sym)))
984+
:ns current-ns
985+
:tag (with-meta 'js {:prefix pre})}))
981986

982987
(defmethod resolve* :default
983988
[sym full-ns current-ns]

src/main/clojure/cljs/env.cljc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,23 @@ state that is accessed/maintained by many different components."}
4343
;; implementation-dependent data.
4444
(def ^:dynamic *compiler* nil)
4545

46+
(defn default-compiler-env* [options]
47+
(merge
48+
{:cljs.analyzer/namespaces {'cljs.user {:name 'cljs.user}}
49+
:cljs.analyzer/constant-table {}
50+
:cljs.analyzer/data-readers {}
51+
:cljs.analyzer/externs #?(:clj (when (:infer-externs options)
52+
(externs/externs-map (:externs-sources options)))
53+
:cljs nil)
54+
:options options}
55+
#?@(:clj [(when (= (:target options) :nodejs)
56+
{:node-module-index deps/native-node-modules})
57+
{:js-dependency-index (deps/js-dependency-index options)}])))
58+
4659
(defn default-compiler-env
4760
([] (default-compiler-env {}))
4861
([options]
49-
(atom
50-
(merge
51-
{:cljs.analyzer/namespaces {'cljs.user {:name 'cljs.user}}
52-
:cljs.analyzer/constant-table {}
53-
:cljs.analyzer/data-readers {}
54-
:cljs.analyzer/externs #?(:clj (when (:infer-externs options)
55-
(externs/externs-map (:externs-sources options)))
56-
:cljs nil)
57-
:options options}
58-
#?@(:clj [(when (= (:target options) :nodejs)
59-
{:node-module-index deps/native-node-modules})
60-
{:js-dependency-index (deps/js-dependency-index options)}])))))
62+
(atom (default-compiler-env* options))))
6163

6264
#?(:clj
6365
(defmacro with-compiler-env

src/test/clojure/cljs/analyzer_tests.clj

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -862,14 +862,17 @@
862862
"goog.isArrayLike;" "Java.type;" "Object.out;" "Object.out.println;"
863863
"Object.error;" "Object.error.println;"])
864864

865-
(defn infer-test-helper [{:keys [forms externs warnings warn with-core? opts]}]
866-
(let [test-cenv (if with-core?
867-
(env/default-compiler-env
868-
(closure/add-externs-sources (merge {:infer-externs true} opts)))
869-
(atom
870-
{::a/externs
871-
(externs/externs-map
872-
(closure/load-externs {:externs (or externs [])}))}))
865+
(defn infer-test-helper
866+
[{:keys [forms externs warnings warn js-dependency-index with-core? opts]}]
867+
(let [test-cenv (atom
868+
(cond->
869+
(if with-core?
870+
(env/default-compiler-env*
871+
(closure/add-externs-sources (merge {:infer-externs true} opts)))
872+
{::a/externs
873+
(externs/externs-map
874+
(closure/load-externs {:externs (or externs [])}))})
875+
js-dependency-index (assoc :js-dependency-index js-dependency-index)))
873876
wrap (if with-core?
874877
#(comp/with-core-cljs nil %)
875878
#(do (%)))]
@@ -1052,3 +1055,14 @@
10521055
(not (string/includes? res "COMPILED"))
10531056
(not (string/includes? res "goog"))
10541057
(is (zero? (count @ws)))))
1058+
1059+
(deftest test-cljs-2678-global-exports-infer
1060+
(let [ws (atom [])
1061+
res (infer-test-helper
1062+
{:js-dependency-index {"react" {:global-exports '{react React}}}
1063+
:forms '[(ns foo.core
1064+
(:require [react :as react]))
1065+
(.log js/console react/Component)]
1066+
:warnings ws
1067+
:warn false})]
1068+
(is (= "Object.Component;\n" res))))

0 commit comments

Comments
 (0)