Skip to content

CLJS-3322: Upgrade to latest Closure Library - handle non-legacy GCL goog.module namespaces #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
org.clojure/clojure {:mvn/version "1.10.0"}
org.clojure/core.specs.alpha {:mvn/version "0.1.24"}
org.clojure/data.json {:mvn/version "0.2.6"}
org.clojure/google-closure-library {:mvn/version "0.0-20201211-3e6c510d"}
org.clojure/google-closure-library {:mvn/version "0.0-20211011-0726fdeb"}
org.clojure/spec.alpha {:mvn/version "0.1.143"}
org.clojure/tools.reader {:mvn/version "1.3.3"}
org.clojure/test.check {:mvn/version "0.10.0-alpha3"}}
Expand Down
2 changes: 1 addition & 1 deletion pom.template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<dependency>
<groupId>org.clojure</groupId>
<artifactId>google-closure-library</artifactId>
<version>0.0-20201211-3e6c510d</version>
<version>0.0-20210811-6da97fe1</version>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
[org.clojure/tools.reader "1.3.3"]
[org.clojure/test.check "0.10.0-alpha3" :scope "test"]
[com.cognitect/transit-clj "0.8.309"]
[org.clojure/google-closure-library "0.0-20201211-3e6c510d"]
[org.clojure/google-closure-library "0.0-20210811-6da97fe1"]
[com.google.javascript/closure-compiler-unshaded "v20210808"]]
:profiles {:1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
:uberjar {:aot :all :main cljs.main}
Expand Down
2 changes: 1 addition & 1 deletion script/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CORE_SPECS_ALPHA_RELEASE="0.1.24"
CLOSURE_RELEASE="20210808"
DJSON_RELEASE="0.2.6"
TRANSIT_RELEASE="0.8.309"
GCLOSURE_LIB_RELEASE="0.0-20201211-3e6c510d"
GCLOSURE_LIB_RELEASE="0.0-20210811-6da97fe1"
TREADER_RELEASE="1.3.3"
TEST_CHECK_RELEASE="0.10.0-alpha3"

Expand Down
4 changes: 4 additions & 0 deletions src/main/cljs/cljs/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2284,6 +2284,10 @@ reduces them without incurring seq initialization"
(not (identical? n js/Infinity))
(== (js/parseFloat n) (js/parseInt n 10))))

(def
^{:doc "INTERNAL: do not use"}
LongImpl goog.math.Long)

(defn int?
"Return true if x satisfies integer? or is an instance of goog.math.Integer
or goog.math.Long."
Expand Down
4 changes: 2 additions & 2 deletions src/main/cljs/cljs/loader.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
(ns cljs.loader
(:require [goog.object :as gobj]
[goog.html.legacyconversions :as legacy])
(:import [goog.module ModuleLoader]
[goog.module ModuleManager]))
(:import [goog.module ModuleManager]
[goog.module ModuleLoader]))

(def module-infos MODULE_INFOS) ;; set by compiler
(def module-uris
Expand Down
5 changes: 4 additions & 1 deletion src/main/cljs/clojure/browser/repl.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,10 @@
(let [ret (.require__ js/goog src)]
(when (= reload "reload-all")
(set! (.-cljsReloadAll_ js/goog) false))
ret))))))
;; handle requires from Closure Library goog.modules
(if (js/goog.isInModuleLoader_)
(js/goog.module.getInternal_ src)
ret)))))))

(defn connect
"Connects to a REPL server from an HTML document. After the
Expand Down
36 changes: 35 additions & 1 deletion src/main/clojure/cljs/analyzer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,12 @@
(or (contains? global-exports (symbol module))
(contains? global-exports (name module)))))

(defn goog-module-dep?
[module]
(let [[module _] (lib&sublib module)
module-type (get-in @env/*compiler* [:js-dependency-index (str module) :module])]
(= :goog module-type)))

(defn confirm-var-exists
([env prefix suffix]
(let [warn (confirm-var-exist-warning env prefix suffix)]
Expand Down Expand Up @@ -1010,6 +1016,12 @@
(str "node$module$" (munge (string/replace (str name) #"[.\/]" #?(:clj "\\$"
:cljs "$$")))))

(defn munge-goog-module-lib
([name]
(str "goog$module$" (munge (string/replace (str name) #"[.\/]" #?(:clj "\\$" :cljs "$$")))))
([ns name]
(str (munge ns) "." (munge-goog-module-lib name))))

(defn munge-global-export [name]
(str "global$module$" (munge (string/replace (str name) #"[.\/]" #?(:clj "\\$"
:cljs "$$")))))
Expand All @@ -1031,6 +1043,7 @@

(defn ns->module-type [ns]
(cond
(goog-module-dep? ns) :goog-module
(js-module-exists? ns) :js
(node-module-dep? ns) :node
(dep-has-global-exports? ns) :global))
Expand Down Expand Up @@ -1072,6 +1085,12 @@
:op :js-var
:foreign true}))

(defmethod resolve* :goog-module
[env sym full-ns current-ns]
{:name (symbol (str current-ns) (str (munge-goog-module-lib full-ns) "." (name sym)))
:ns current-ns
:op :var})

(defmethod resolve* :global
[env sym full-ns current-ns]
(let [pre (extern-pre sym current-ns)]
Expand Down Expand Up @@ -1135,6 +1154,15 @@
:op :js-var
:ns current-ns})))

(defn resolve-import
"goog.modules are deterministically assigned to a property of the namespace,
we cannot expect the reference will be globally available, so we resolve to
namespace local reference."
[env import]
(if (goog-module-dep? import)
(symbol (munge-goog-module-lib (-> env :ns :name) import))
import))

;; core.async calls `macroexpand-1` manually with an ill-formed
;; :locals map. Normally :locals maps symbols maps, but
;; core.async adds entries mapping symbols to symbols. We work
Expand Down Expand Up @@ -1207,7 +1235,13 @@
;; check if prefix is some existing def
(if-let [resolved (resolve-var env prefix nil false)]
(update resolved :name #(symbol (str % "." suffix)))
(let [idx (.lastIndexOf s ".")
;; glib imports (i.e. (:import [goog.module ModuleLoader])
;; are always just dotted symbols after the recursion
(let [s (str
(cond->> s
(goog-module-dep? sym)
(resolve-import env)))
idx (.lastIndexOf (str s) ".")
pre (subs s 0 idx)
suf (subs s (inc idx))]
{:op :var
Expand Down
18 changes: 18 additions & 0 deletions src/main/clojure/cljs/compiler.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,9 @@
(let [{node-libs true libs-to-load false} (group-by ana/node-module-dep? libs)]
[node-libs libs-to-load])
[nil libs]))
[goog-modules libs-to-load] (let [{goog-modules true libs-to-load false}
(group-by ana/goog-module-dep? libs-to-load)]
[goog-modules libs-to-load])
global-exports-libs (filter ana/dep-has-global-exports? libs-to-load)]
(when (-> libs meta :reload-all)
(emitln "if(!COMPILED) " loaded-libs-temp " = " loaded-libs " || cljs.core.set([\"cljs.core\"]);")
Expand Down Expand Up @@ -1336,11 +1339,26 @@
:else
(when-not (= lib 'goog)
(emitln "goog.require('" (munge lib) "');"))))
;; Node Libraries
(doseq [lib node-libs]
(let [[lib' sublib] (ana/lib&sublib lib)]
(emitln (munge ns-name) "."
(ana/munge-node-lib lib)
" = require('" lib' "')" (sublib-select sublib) ";")))
;; Google Closure Library Modules (i.e. goog.module(...))
;; these must be assigned to vars
(doseq [lib goog-modules]
(let [[lib' sublib] (ana/lib&sublib lib)]
(emitln "goog.require('" lib' "');")
;; we emit goog.scope here to suppress a Closure error about
;; goog.module.get when compiling - meant to discourage incorrect
;; usage by hand written code - not applicable here
(emitln "goog.scope(function(){")
(emitln (munge ns-name) "."
(ana/munge-goog-module-lib lib)
" = goog.module.get('" lib' "')" (sublib-select sublib) ";")
(emitln "});")))
;; Global Exports
(doseq [lib global-exports-libs]
(let [{:keys [global-exports]} (get js-dependency-index (name (-> lib ana/lib&sublib first)))]
(emit-global-export ns-name global-exports lib)))
Expand Down
10 changes: 5 additions & 5 deletions src/main/clojure/cljs/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1430,9 +1430,9 @@
(core/let [psym (resolve p)
pfn-prefix (subs (core/str psym) 0
(clojure.core/inc (.indexOf (core/str psym) "/")))]
(cons `(goog.object/set ~psym ~type true)
(cons `(unchecked-set ~psym ~type true)
(map (core/fn [[f & meths :as form]]
`(goog.object/set ~(symbol (core/str pfn-prefix f))
`(unchecked-set ~(symbol (core/str pfn-prefix f))
~type ~(with-meta `(fn ~@meths) (meta form))))
sigs))))

Expand Down Expand Up @@ -2672,8 +2672,8 @@
(js-obj* '())
`(let [~@(apply concat (clojure.set/map-invert expr->local))
~obj ~(js-obj* (filter-on-keys core/string? kvs))]
~@(map (core/fn [[k v]] `(goog.object/set ~obj ~k ~v)) sym-pairs)
~@(map (core/fn [[k v]] `(goog.object/set ~obj ~v ~(core/get kvs k))) expr->local)
~@(map (core/fn [[k v]] `(unchecked-set ~obj ~k ~v)) sym-pairs)
~@(map (core/fn [[k v]] `(unchecked-set ~obj ~v ~(core/get kvs k))) expr->local)
~obj))))

(core/defmacro alength [a]
Expand Down Expand Up @@ -2888,7 +2888,7 @@
(core/list 'js* "''+~{}" s))

(core/defmacro es6-iterable [ty]
`(goog.object/set (.-prototype ~ty) cljs.core/ITER_SYMBOL
`(unchecked-set (.-prototype ~ty) cljs.core/ITER_SYMBOL
(fn []
(this-as this#
(cljs.core/es6-iterator this#)))))
Expand Down
Loading