clojurific 0.12.1 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +3 -2
  2. package/cljf/launcher.js +15 -8
  3. package/package.json +2 -2
  4. package/compiler/deps.edn +0 -9
  5. package/compiler/src/main/cljs/cljs/analyzer/passes/and_or.cljc +0 -118
  6. package/compiler/src/main/cljs/cljs/analyzer/passes/lite.cljc +0 -32
  7. package/compiler/src/main/cljs/cljs/analyzer/passes.cljc +0 -32
  8. package/compiler/src/main/cljs/cljs/bootstrap_nodejs.js +0 -154
  9. package/compiler/src/main/cljs/cljs/core/specs/alpha.cljc +0 -272
  10. package/compiler/src/main/cljs/cljs/core/specs/alpha.cljs +0 -10
  11. package/compiler/src/main/cljs/cljs/core.cljs +0 -13194
  12. package/compiler/src/main/cljs/cljs/esm/goog/array.js +0 -61
  13. package/compiler/src/main/cljs/cljs/esm/goog/math.js +0 -1846
  14. package/compiler/src/main/cljs/cljs/esm/goog/object.js +0 -80
  15. package/compiler/src/main/cljs/cljs/esm/goog/string.js +0 -192
  16. package/compiler/src/main/cljs/cljs/esm/goog/userAgent/product.js +0 -10
  17. package/compiler/src/main/cljs/cljs/esm/goog.js +0 -90
  18. package/compiler/src/main/cljs/cljs/esm/karma.cljs +0 -103
  19. package/compiler/src/main/cljs/cljs/esm/lazy.clj +0 -51
  20. package/compiler/src/main/cljs/cljs/esm/lazy.cljs +0 -49
  21. package/compiler/src/main/cljs/cljs/esm/node_test.cljs +0 -21
  22. package/compiler/src/main/cljs/cljs/esm/repl_runtime.cljs +0 -353
  23. package/compiler/src/main/cljs/cljs/externs.js +0 -27
  24. package/compiler/src/main/cljs/cljs/imul.js +0 -11
  25. package/compiler/src/main/cljs/cljs/js.clj +0 -24
  26. package/compiler/src/main/cljs/cljs/js.cljs +0 -1432
  27. package/compiler/src/main/cljs/cljs/loader.cljs +0 -107
  28. package/compiler/src/main/cljs/cljs/main.clj +0 -67
  29. package/compiler/src/main/cljs/cljs/math.cljs +0 -869
  30. package/compiler/src/main/cljs/cljs/module_deps.js +0 -250
  31. package/compiler/src/main/cljs/cljs/nodejs.cljs +0 -27
  32. package/compiler/src/main/cljs/cljs/nodejs_externs.js +0 -3
  33. package/compiler/src/main/cljs/cljs/nodejscli.cljs +0 -22
  34. package/compiler/src/main/cljs/cljs/pprint.cljc +0 -167
  35. package/compiler/src/main/cljs/cljs/pprint.cljs +0 -3325
  36. package/compiler/src/main/cljs/cljs/proxy/impl.cljs +0 -32
  37. package/compiler/src/main/cljs/cljs/proxy.cljs +0 -184
  38. package/compiler/src/main/cljs/cljs/reader.clj +0 -18
  39. package/compiler/src/main/cljs/cljs/reader.cljs +0 -214
  40. package/compiler/src/main/cljs/cljs/repl.cljs +0 -206
  41. package/compiler/src/main/cljs/cljs/source_map/base64.cljs +0 -25
  42. package/compiler/src/main/cljs/cljs/source_map/base64_vlq.cljs +0 -102
  43. package/compiler/src/main/cljs/cljs/source_map.cljs +0 -305
  44. package/compiler/src/main/cljs/cljs/spec/alpha.cljc +0 -564
  45. package/compiler/src/main/cljs/cljs/spec/alpha.cljs +0 -1510
  46. package/compiler/src/main/cljs/cljs/spec/gen/alpha.cljc +0 -68
  47. package/compiler/src/main/cljs/cljs/spec/gen/alpha.cljs +0 -183
  48. package/compiler/src/main/cljs/cljs/spec/test/alpha.cljc +0 -329
  49. package/compiler/src/main/cljs/cljs/spec/test/alpha.cljs +0 -380
  50. package/compiler/src/main/cljs/cljs/stacktrace.cljc +0 -578
  51. package/compiler/src/main/cljs/cljs/test.cljc +0 -458
  52. package/compiler/src/main/cljs/cljs/test.cljs +0 -606
  53. package/compiler/src/main/cljs/clojure/browser/dom.cljs +0 -152
  54. package/compiler/src/main/cljs/clojure/browser/event.cljs +0 -101
  55. package/compiler/src/main/cljs/clojure/browser/net.cljs +0 -181
  56. package/compiler/src/main/cljs/clojure/browser/repl/preload.cljs +0 -13
  57. package/compiler/src/main/cljs/clojure/browser/repl.cljs +0 -283
  58. package/compiler/src/main/cljs/clojure/core/protocols.cljs +0 -29
  59. package/compiler/src/main/cljs/clojure/core/reducers.cljs +0 -312
  60. package/compiler/src/main/cljs/clojure/data.cljs +0 -162
  61. package/compiler/src/main/cljs/clojure/datafy.cljs +0 -63
  62. package/compiler/src/main/cljs/clojure/edn.cljs +0 -55
  63. package/compiler/src/main/cljs/clojure/reflect.cljs +0 -57
  64. package/compiler/src/main/cljs/clojure/set.cljs +0 -165
  65. package/compiler/src/main/cljs/clojure/string.cljs +0 -290
  66. package/compiler/src/main/cljs/clojure/walk.cljs +0 -98
  67. package/compiler/src/main/cljs/clojure/zip.cljs +0 -291
  68. package/compiler/src/main/cljs/process/env.cljs +0 -12
  69. package/compiler/src/main/cljs/shadow/resource.clj +0 -60
  70. package/compiler/src/main/cljs/shadow/resource.cljs +0 -10
  71. package/compiler/src/main/clojure/cljs/analyzer/api.cljc +0 -299
  72. package/compiler/src/main/clojure/cljs/analyzer/impl/namespaces.cljc +0 -68
  73. package/compiler/src/main/clojure/cljs/analyzer/impl.cljc +0 -59
  74. package/compiler/src/main/clojure/cljs/analyzer/macros.clj +0 -57
  75. package/compiler/src/main/clojure/cljs/analyzer/utils.clj +0 -36
  76. package/compiler/src/main/clojure/cljs/analyzer.cljc +0 -5292
  77. package/compiler/src/main/clojure/cljs/build/api.clj +0 -309
  78. package/compiler/src/main/clojure/cljs/cli.clj +0 -812
  79. package/compiler/src/main/clojure/cljs/closure.clj +0 -3440
  80. package/compiler/src/main/clojure/cljs/compiler/api.clj +0 -101
  81. package/compiler/src/main/clojure/cljs/compiler/macros.clj +0 -16
  82. package/compiler/src/main/clojure/cljs/compiler.cljc +0 -2748
  83. package/compiler/src/main/clojure/cljs/core/macros.clj +0 -43
  84. package/compiler/src/main/clojure/cljs/core/server.clj +0 -167
  85. package/compiler/src/main/clojure/cljs/core.cljc +0 -3719
  86. package/compiler/src/main/clojure/cljs/env/macros.clj +0 -37
  87. package/compiler/src/main/clojure/cljs/env.cljc +0 -102
  88. package/compiler/src/main/clojure/cljs/esm/repl/nrepl.clj +0 -151
  89. package/compiler/src/main/clojure/cljs/esm/repl.clj +0 -878
  90. package/compiler/src/main/clojure/cljs/esm.clj +0 -987
  91. package/compiler/src/main/clojure/cljs/externs/default.edn +0 -1549
  92. package/compiler/src/main/clojure/cljs/externs.clj +0 -479
  93. package/compiler/src/main/clojure/cljs/foreign/node.clj +0 -207
  94. package/compiler/src/main/clojure/cljs/instant.clj +0 -54
  95. package/compiler/src/main/clojure/cljs/js_deps.cljc +0 -412
  96. package/compiler/src/main/clojure/cljs/module_graph.cljc +0 -402
  97. package/compiler/src/main/clojure/cljs/repl/bootstrap.clj +0 -53
  98. package/compiler/src/main/clojure/cljs/repl/browser.clj +0 -540
  99. package/compiler/src/main/clojure/cljs/repl/node.clj +0 -253
  100. package/compiler/src/main/clojure/cljs/repl/node_repl.js +0 -114
  101. package/compiler/src/main/clojure/cljs/repl/reflect.clj +0 -85
  102. package/compiler/src/main/clojure/cljs/repl/server.clj +0 -236
  103. package/compiler/src/main/clojure/cljs/repl.cljc +0 -1615
  104. package/compiler/src/main/clojure/cljs/server/browser.clj +0 -54
  105. package/compiler/src/main/clojure/cljs/server/node.clj +0 -54
  106. package/compiler/src/main/clojure/cljs/source_map/base64.clj +0 -28
  107. package/compiler/src/main/clojure/cljs/source_map/base64_vlq.clj +0 -104
  108. package/compiler/src/main/clojure/cljs/source_map.clj +0 -369
  109. package/compiler/src/main/clojure/cljs/support.cljc +0 -18
  110. package/compiler/src/main/clojure/cljs/tagged_literals.cljc +0 -93
  111. package/compiler/src/main/clojure/cljs/util.cljc +0 -420
  112. package/compiler/src/main/clojure/cljs/vendor/bridge.clj +0 -42
  113. package/compiler/src/main/clojure/cljs/vendor/clojure/data/json.clj +0 -809
  114. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/default_data_readers.clj +0 -303
  115. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/edn.clj +0 -440
  116. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/commons.clj +0 -131
  117. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/errors.clj +0 -214
  118. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/inspect.clj +0 -91
  119. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/utils.clj +0 -127
  120. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/reader_types.clj +0 -431
  121. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader.clj +0 -1035
  122. package/compiler/src/main/clojure/cljs/vendor/cognitect/transit.clj +0 -479
  123. /package/{compiler/no-clojurescript → no-clojurescript}/deps.edn +0 -0
@@ -1,1432 +0,0 @@
1
- ; Copyright (c) Rich Hickey. All rights reserved.
2
- ; The use and distribution terms for this software are covered by the
3
- ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
- ; which can be found in the file epl-v10.html at the root of this distribution.
5
- ; By using this software in any fashion, you are agreeing to be bound by
6
- ; the terms of this license.
7
- ; You must not remove this notice, or any other, from this software.
8
-
9
- (ns cljs.js
10
- (:refer-clojure :exclude [require eval])
11
- (:require-macros [cljs.js :refer [dump-core]]
12
- [cljs.env.macros :as env])
13
- (:require [clojure.string :as string]
14
- [clojure.walk :as walk]
15
- [cljs.env :as env]
16
- [cljs.spec.alpha]
17
- [cljs.analyzer :as ana]
18
- [cljs.compiler :as comp]
19
- [cljs.tools.reader :as r]
20
- [cljs.tools.reader.reader-types :as rt]
21
- [cljs.tagged-literals :as tags]
22
- [goog.crypt.base64 :as base64]
23
- [cljs.source-map :as sm])
24
- (:import [goog.string StringBuffer]))
25
-
26
- (js/goog.require "cljs.core$macros")
27
-
28
- (defn- debug-prn
29
- [& args]
30
- (binding [*print-fn* *print-err-fn*]
31
- (apply println args)))
32
-
33
- (defn ns->relpath
34
- "Given a namespace as a symbol return the relative path sans extension"
35
- [ns-sym]
36
- (string/replace (ana/munge-path ns-sym) \. \/))
37
-
38
- (defn file->ns
39
- [file]
40
- (let [lib-name (subs (string/replace file "/" ".")
41
- 0 (- (count file) 5))]
42
- (symbol (demunge lib-name))))
43
-
44
- (defn- drop-macros-suffix
45
- [ns-name]
46
- (when ns-name
47
- (if (string/ends-with? ns-name "$macros")
48
- (subs ns-name 0 (- (count ns-name) 7))
49
- ns-name)))
50
-
51
- (defn- elide-macros-suffix
52
- [sym]
53
- (symbol (drop-macros-suffix (namespace sym)) (name sym)))
54
-
55
- (defn- resolve-symbol
56
- [sym]
57
- (if (string/starts-with? (str sym) ".")
58
- sym
59
- (elide-macros-suffix (ana/resolve-symbol sym))))
60
-
61
- (defn- read [eof rdr]
62
- (binding [*ns* (symbol (drop-macros-suffix (str *ns*)))]
63
- (r/read {:eof eof :read-cond :allow :features #{:cljs}} rdr)))
64
-
65
- (defn- atom? [x]
66
- (instance? Atom x))
67
-
68
- (defn- valid-name? [x]
69
- (or (nil? x) (symbol? x) (string? x)))
70
-
71
- (defn- valid-opts? [x]
72
- (or (nil? x) (map? x)))
73
-
74
- (defonce
75
- ^{:doc "Each runtime environment provides a different way to load a library.
76
- Whatever function *load-fn* is bound to will be passed two arguments - a
77
- map and a callback function: The map will have the following keys:
78
-
79
- :name - the name of the library (a symbol)
80
- :macros - modifier signaling a macros namespace load
81
- :path - munged relative library path (a string)
82
-
83
- It is up to the implementor to correctly resolve the corresponding .cljs,
84
- .cljc, or .js resource (the order must be respected). If :macros is true
85
- resolution should only consider .clj or .cljc resources (the order must be
86
- respected). Upon resolution the callback should be invoked with a map
87
- containing the following keys:
88
-
89
- :lang - the language, :clj or :js
90
- :source - the source of the library (a string)
91
- :file - optional, the file path, it will be added to AST's :file keyword
92
- (but not in :meta)
93
- :cache - optional, if a :clj namespace has been precompiled to :js, can
94
- give an analysis cache for faster loads.
95
- :source-map - optional, if a :clj namespace has been precompiled to :js, can
96
- give a V3 source map JSON
97
-
98
- If the resource could not be resolved, the callback should be invoked with
99
- nil."
100
- :dynamic true}
101
- *load-fn*
102
- (fn [m cb]
103
- (throw (js/Error. "No *load-fn* set"))))
104
-
105
- (defonce
106
- ^{:doc "Each runtime environment provides various ways to eval JavaScript
107
- source. Whatever function *eval-fn* is bound to will be passed a map
108
- containing the following keys:
109
-
110
- :source - the source of the library (string)
111
- :name - used to unique identify the script (symbol)
112
- :cache - if the source was originally ClojureScript, will be given the
113
- analysis cache.
114
-
115
- The result of evaluation should be the return value."
116
- :dynamic true}
117
- *eval-fn*
118
- (fn [m]
119
- (throw (js/Error. "No *eval-fn* set"))))
120
-
121
- (defn js-eval
122
- "A default JavaScript evaluation function."
123
- [{:keys [source] :as resource}]
124
- (js/eval source))
125
-
126
- (defn- wrap-error [ex]
127
- {:error ex})
128
-
129
- (defn empty-state
130
- "Construct an empty compiler state. Required to invoke analyze, compile,
131
- eval and eval-str."
132
- ([]
133
- (doto (env/default-compiler-env)
134
- (swap!
135
- (fn [state]
136
- (-> state
137
- (assoc-in [::ana/namespaces 'cljs.core] (dump-core)))))))
138
- ([init]
139
- (doto (empty-state) (swap! init))))
140
-
141
- (defn load-analysis-cache! [state ns cache]
142
- (swap! state assoc-in [::ana/namespaces ns] cache))
143
-
144
- (defn load-source-map! [state ns sm-json]
145
- (let [sm (sm/decode (.parse js/JSON sm-json))]
146
- (swap! state assoc-in [:source-maps ns] sm)))
147
-
148
- (defn- sm-data []
149
- (atom
150
- {:source-map (sorted-map)
151
- :gen-col 0
152
- :gen-line 0}))
153
-
154
- (defn- prefix [s pre]
155
- (str pre s))
156
-
157
- (defn- append-source-map
158
- [state name source sb sm-data {:keys [output-dir asset-path source-map-timestamp] :as opts}]
159
- (let [t (.valueOf (js/Date.))
160
- mn (if name
161
- (munge (str name))
162
- (str "cljs-" t))
163
- smn (cond-> mn
164
- name (string/replace "." "/"))
165
- ts (.valueOf (js/Date.))
166
- out (or output-dir asset-path)
167
- src (cond-> (str smn ".cljs")
168
- (true? source-map-timestamp) (str "?rel=" ts)
169
- out (prefix (str out "/")))
170
- file (cond-> (str smn ".js")
171
- (true? source-map-timestamp) (str "?rel=" ts)
172
- out (prefix (str out "/")))
173
- json (sm/encode {src (:source-map sm-data)}
174
- {:lines (+ (:gen-line sm-data) 3)
175
- :file file :sources-content [source]})]
176
- (when (:verbose opts) (debug-prn json))
177
- (swap! state assoc-in
178
- [:source-maps (symbol mn)] (sm/invert-reverse-map (:source-map sm-data)))
179
- (.append sb
180
- (str "\n//# sourceURL=" file
181
- "\n//# sourceMappingURL=data:application/json;base64,"
182
- (-> (js/encodeURIComponent json)
183
- (string/replace #"%([0-9A-F]{2})" (fn [[_ match]]
184
- (.fromCharCode js/String (str "0x" match))))
185
- (base64/encodeString))))))
186
-
187
- (defn- alias-map
188
- [compiler cljs-ns]
189
- (->> (env/with-compiler-env compiler
190
- (ana/get-aliases cljs-ns))
191
- (remove (fn [[k v]] (symbol-identical? k v)))
192
- (into {})))
193
-
194
- ;; -----------------------------------------------------------------------------
195
- ;; Analyze
196
-
197
- (declare ^{:arglists '([bound-vars source name opts cb])} eval-str*)
198
-
199
- (def *loaded* (atom #{}))
200
-
201
- (defn- run-async!
202
- "Like cljs.core/run!, but for an async procedure, and with the
203
- ability to break prior to processing the entire collection.
204
-
205
- Chains successive calls to the supplied procedure for items in
206
- the collection. The procedure should accept an item from the
207
- collection and a callback of one argument. If the break? predicate,
208
- when applied to the procedure callback value, yields a truthy
209
- result, terminates early calling the supplied cb with the callback
210
- value. Otherwise, when complete, calls cb with nil."
211
- [proc coll break? cb]
212
- (if (seq coll)
213
- (proc (first coll)
214
- (fn [res]
215
- (if (break? res)
216
- (cb res)
217
- (run-async! proc (rest coll) break? cb))))
218
- (cb nil)))
219
-
220
- (declare ^{:arglists '([name cb]
221
- [name opts cb]
222
- [bound-vars name opts cb]
223
- [bound-vars name reload opts cb])} require)
224
-
225
- (defn- process-deps
226
- [bound-vars names opts cb]
227
- (run-async! (fn [name cb]
228
- (require bound-vars name nil opts cb))
229
- names
230
- :error
231
- cb))
232
-
233
- (defn- process-macros-deps
234
- [bound-vars cache opts cb]
235
- (process-deps bound-vars
236
- (distinct (vals (:require-macros cache)))
237
- (-> opts
238
- (assoc :macros-ns true)
239
- (dissoc :emit-constants :optimize-constants))
240
- cb))
241
-
242
- (defn- process-libs-deps
243
- [bound-vars cache opts cb]
244
- (process-deps bound-vars
245
- (distinct (concat (vals (:requires cache)) (vals (:imports cache))))
246
- (dissoc opts :macros-ns)
247
- cb))
248
-
249
- (defn- pre-file-side-effects
250
- [st name file opts]
251
- (when (:verbose opts)
252
- (debug-prn "Pre-file side-effects" file))
253
- ;; In case any constants are defined in the namespace, flush any analysis metadata
254
- ;; so that the constants can be defined wihtout triggering re-defined errors.
255
- (when (and (get-in @st [::ana/namespaces name :defs])
256
- (not ('#{cljs.core cljs.core$macros} name)))
257
- (swap! st update ::ana/namespaces dissoc name)))
258
-
259
- (defn- post-file-side-effects
260
- [file opts]
261
- (when (:verbose opts)
262
- (debug-prn "Post-file side-effects" file))
263
- ;; Note, we don't (set! *unchecked-arrays* false) here, as that would interpreted
264
- ;; an intrinsic affecting the compilation of this file, emitting a no-op. We bypass this
265
- ;; and emit our own runtime assignment code.
266
- (js* "cljs.core._STAR_unchecked_arrays_STAR_ = false;"))
267
-
268
- (defn require
269
- ([name cb]
270
- (require name nil cb))
271
- ([name opts cb]
272
- (require nil name opts cb))
273
- ([bound-vars name opts cb]
274
- (require bound-vars name nil opts cb))
275
- ([bound-vars name reload opts cb]
276
- (let [bound-vars (merge
277
- {:*compiler* (env/default-compiler-env)
278
- :*data-readers* tags/*cljs-data-readers*
279
- :*load-macros* (:load-macros opts true)
280
- :*analyze-deps* (:analyze-deps opts true)
281
- :*load-fn* (or (:load opts) *load-fn*)
282
- :*eval-fn* (or (:eval opts) *eval-fn*)}
283
- bound-vars)
284
- aname (cond-> name (:macros-ns opts) ana/macro-ns-name)]
285
- (when (= :reload reload)
286
- (swap! *loaded* disj aname))
287
- (when (= :reload-all reload)
288
- (reset! *loaded* #{}))
289
- (when (:verbose opts)
290
- (debug-prn (str "Loading " name (when (:macros-ns opts) " macros") " namespace")))
291
- (if-not (contains? @*loaded* aname)
292
- (let [env (:*env* bound-vars)]
293
- (try
294
- ((:*load-fn* bound-vars)
295
- {:name name
296
- :macros (:macros-ns opts)
297
- :path (ns->relpath name)}
298
- (fn [resource]
299
- (assert (or (map? resource) (nil? resource))
300
- "*load-fn* may only return a map or nil")
301
- (if resource
302
- (let [{:keys [lang source cache source-map file]} resource]
303
- (condp keyword-identical? lang
304
- :clj (do
305
- (pre-file-side-effects (:*compiler* bound-vars) aname file opts)
306
- (eval-str* bound-vars source name (assoc opts :cljs-file file)
307
- (fn [res]
308
- (post-file-side-effects file opts)
309
- (if (:error res)
310
- (cb res)
311
- (do
312
- (swap! *loaded* conj aname)
313
- (cb {:value true}))))))
314
- :js (process-macros-deps bound-vars cache opts
315
- (fn [res]
316
- (if (:error res)
317
- (cb res)
318
- (process-libs-deps bound-vars cache opts
319
- (fn [res]
320
- (if (:error res)
321
- (cb res)
322
- (let [res (try
323
- ((:*eval-fn* bound-vars) resource)
324
- (when cache
325
- (load-analysis-cache!
326
- (:*compiler* bound-vars) aname cache)
327
- (ana/register-specs cache))
328
- (when source-map
329
- (load-source-map!
330
- (:*compiler* bound-vars) aname source-map))
331
- (catch :default cause
332
- (wrap-error
333
- (ana/error env
334
- (str "Could not require " name) cause))))]
335
- (if (:error res)
336
- (cb res)
337
- (do
338
- (swap! *loaded* conj aname)
339
- (cb {:value true}))))))))))
340
- (cb (wrap-error
341
- (ana/error env
342
- (str "Invalid :lang specified " lang ", only :clj or :js allowed"))))))
343
- (cb (wrap-error
344
- (ana/error env
345
- (ana/error-message (if (:macros-ns opts)
346
- :undeclared-macros-ns
347
- :undeclared-ns)
348
- {:ns-sym name :js-provide (cljs.core/name name)})))))))
349
- (catch :default cause
350
- (cb (wrap-error
351
- (ana/error env
352
- (str "Could not require " name) cause))))))
353
- (cb {:value true})))))
354
-
355
- (defn- patch-alias-map
356
- [compiler in from to]
357
- (let [patch (fn [k add-if-present?]
358
- (swap! compiler update-in [::ana/namespaces in k]
359
- (fn [m]
360
- (let [replaced (walk/postwalk-replace {from to} m)]
361
- (if (and add-if-present?
362
- (some #{to} (vals replaced)))
363
- (assoc replaced from to)
364
- replaced)))))
365
- patch-renames (fn [k]
366
- (swap! compiler update-in [::ana/namespaces in k]
367
- (fn [m]
368
- (when m
369
- (reduce (fn [acc [renamed qualified-sym :as entry]]
370
- (if (= (str from) (namespace qualified-sym))
371
- (assoc acc renamed (symbol (str to) (name qualified-sym)))
372
- (merge acc entry)))
373
- {} m)))))]
374
- (patch :requires true)
375
- (patch :require-macros true)
376
- (patch :uses false)
377
- (patch :use-macros false)
378
- (patch-renames :renames)
379
- (patch-renames :rename-macros)))
380
-
381
- (defn- self-require? [deps opts]
382
- (and (true? (:def-emits-var opts)) (some #{ana/*cljs-ns*} deps)))
383
-
384
- (defn- load-deps
385
- ([bound-vars ana-env lib deps cb]
386
- (load-deps bound-vars ana-env lib deps nil nil cb))
387
- ([bound-vars ana-env lib deps reload opts cb]
388
- (when (:verbose opts)
389
- (debug-prn "Loading dependencies for" lib))
390
- (binding [ana/*cljs-dep-set* (let [lib (if (self-require? deps opts)
391
- 'cljs.user
392
- lib)]
393
- (vary-meta (conj (:*cljs-dep-set* bound-vars) lib)
394
- update-in [:dep-path] conj lib))]
395
- (let [bound-vars (assoc bound-vars :*cljs-dep-set* ana/*cljs-dep-set*)]
396
- (if-not (every? #(not (contains? ana/*cljs-dep-set* %)) deps)
397
- (cb (wrap-error
398
- (ana/error ana-env
399
- (str "Circular dependency detected "
400
- (apply str
401
- (interpose " -> "
402
- (conj (-> ana/*cljs-dep-set* meta :dep-path)
403
- (some ana/*cljs-dep-set* deps))))))))
404
- (if (seq deps)
405
- (let [dep (first deps)
406
- opts' (-> opts
407
- (dissoc :context)
408
- (dissoc :def-emits-var)
409
- (dissoc :ns))]
410
- (require bound-vars dep reload opts'
411
- (fn [res]
412
- (when (:verbose opts)
413
- (debug-prn "Loading result:" res))
414
- (if-not (:error res)
415
- (load-deps bound-vars ana-env lib (next deps) nil opts cb)
416
- (if-let [cljs-dep (let [cljs-ns (ana/clj-ns->cljs-ns dep)]
417
- (get {dep nil} cljs-ns cljs-ns))]
418
- (require bound-vars cljs-dep opts'
419
- (fn [res]
420
- (if (:error res)
421
- (cb res)
422
- (do
423
- (patch-alias-map (:*compiler* bound-vars) lib dep cljs-dep)
424
- (load-deps bound-vars ana-env lib (next deps) nil opts
425
- (fn [res]
426
- (if (:error res)
427
- (cb res)
428
- (cb (update res :aliased-loads assoc dep cljs-dep)))))))))
429
- (cb res))))))
430
- (cb {:value nil})))))))
431
-
432
- (declare ^{:arglists '([bound-vars source name opts cb])} analyze-str*)
433
-
434
- (defn- analyze-deps
435
- ([bound-vars ana-env lib deps cb]
436
- (analyze-deps bound-vars ana-env lib deps nil cb))
437
- ([bound-vars ana-env lib deps opts cb]
438
- (binding [ana/*cljs-dep-set* (vary-meta (conj (:*cljs-dep-set* bound-vars) lib)
439
- update-in [:dep-path] conj lib)]
440
- (let [compiler @(:*compiler* bound-vars)
441
- bound-vars (assoc bound-vars :*cljs-dep-set* ana/*cljs-dep-set*)]
442
- (if-not (every? #(not (contains? ana/*cljs-dep-set* %)) deps)
443
- (cb (wrap-error
444
- (ana/error ana-env
445
- (str "Circular dependency detected "
446
- (apply str
447
- (interpose " -> "
448
- (conj (-> ana/*cljs-dep-set* meta :dep-path)
449
- (some ana/*cljs-dep-set* deps))))))))
450
- (if (seq deps)
451
- (let [dep (first deps)]
452
- (try
453
- ((:*load-fn* bound-vars) {:name dep :path (ns->relpath dep)}
454
- (fn [resource]
455
- (assert (or (map? resource) (nil? resource))
456
- "*load-fn* may only return a map or nil")
457
- (if-not resource
458
- (if-let [cljs-dep (let [cljs-ns (ana/clj-ns->cljs-ns dep)]
459
- (get {dep nil} cljs-ns cljs-ns))]
460
- (do
461
- (patch-alias-map (:*compiler* bound-vars) lib dep cljs-dep)
462
- (analyze-deps bound-vars ana-env lib (cons cljs-dep (next deps)) opts
463
- (fn [res]
464
- (if (:error res)
465
- (cb res)
466
- (cb (update res :aliased-loads assoc dep cljs-dep))))))
467
- (cb (wrap-error
468
- (ana/error ana-env
469
- (ana/error-message :undeclared-ns
470
- {:ns-sym dep :js-provide (name dep)})))))
471
- (let [{:keys [name lang source file]} resource]
472
- (condp keyword-identical? lang
473
- :clj (do
474
- (pre-file-side-effects (:*compiler* bound-vars) name file opts)
475
- (analyze-str* bound-vars source name (assoc opts :cljs-file file)
476
- (fn [res]
477
- (post-file-side-effects file opts)
478
- (if-not (:error res)
479
- (analyze-deps bound-vars ana-env lib (next deps) opts cb)
480
- (cb res)))))
481
- :js (analyze-deps bound-vars ana-env lib (next deps) opts cb)
482
- (wrap-error
483
- (ana/error ana-env
484
- (str "Invalid :lang specified " lang ", only :clj or :js allowed"))))))))
485
- (catch :default cause
486
- (cb (wrap-error
487
- (ana/error ana-env
488
- (str "Could not analyze dep " dep) cause))))))
489
- (cb {:value nil})))))))
490
-
491
- (defn- load-macros [bound-vars k macros lib reload reloads opts cb]
492
- (if (seq macros)
493
- (let [nsym (first (vals macros))
494
- k (or (reload k)
495
- (get-in reloads [k nsym])
496
- (and (= nsym name) (:*reload-macros* bound-vars) :reload)
497
- nil)
498
- opts' (-> opts
499
- (assoc :macros-ns true)
500
- (dissoc :context)
501
- (dissoc :def-emits-var)
502
- (dissoc :ns)
503
- (dissoc :emit-constants :optimize-constants))]
504
- (require bound-vars nsym k opts'
505
- (fn [res]
506
- (if-not (:error res)
507
- (load-macros bound-vars k (next macros) lib reload reloads opts cb)
508
- (if-let [cljs-dep (let [cljs-ns (ana/clj-ns->cljs-ns nsym)]
509
- (get {nsym nil} cljs-ns cljs-ns))]
510
- (require bound-vars cljs-dep k opts'
511
- (fn [res]
512
- (if (:error res)
513
- (cb res)
514
- (do
515
- (patch-alias-map (:*compiler* bound-vars) lib nsym cljs-dep)
516
- (load-macros bound-vars k (next macros) lib reload reloads opts
517
- (fn [res]
518
- (if (:error res)
519
- (cb res)
520
- (cb (update res :aliased-loads assoc nsym cljs-dep)))))))))
521
- (cb res))))))
522
- (cb {:value nil})))
523
-
524
- (defn- rewrite-ns-ast
525
- ([ast smap]
526
- (rewrite-ns-ast ast smap false))
527
- ([ast smap macros?]
528
- (let [[uk rk renk] (if macros?
529
- [:use-macros :require-macros :rename-macros]
530
- [:uses :requires :renames])
531
- rewrite-renames (fn [m]
532
- (when m
533
- (reduce (fn [acc [renamed qualified-sym :as entry]]
534
- (let [from (symbol (namespace qualified-sym))
535
- to (get smap from)]
536
- (if (some? to)
537
- (assoc acc renamed (symbol (str to) (name qualified-sym)))
538
- (merge acc entry))))
539
- {} m)))
540
- rewrite-deps (fn [deps]
541
- (into []
542
- (map (fn [dep]
543
- (if-let [new-dep (get smap dep)]
544
- new-dep
545
- dep)))
546
- deps))]
547
- (-> ast
548
- (update uk #(walk/postwalk-replace smap %))
549
- (update rk #(merge smap (walk/postwalk-replace smap %)))
550
- (update renk rewrite-renames)
551
- (update :deps rewrite-deps)))))
552
-
553
- (defn- check-macro-autoload-inferring-missing
554
- [{:keys [requires name] :as ast} cenv]
555
- (let [namespaces (-> @cenv ::ana/namespaces)
556
- missing-require-macros (into {}
557
- (filter (fn [[_ full-ns]]
558
- (let [{:keys [use-macros require-macros]} (get namespaces full-ns)]
559
- (or (some #{full-ns} (vals use-macros))
560
- (some #{full-ns} (vals require-macros))))))
561
- requires)
562
- ast' (update-in ast [:require-macros] merge missing-require-macros)]
563
- (swap! cenv update-in [::ana/namespaces name :require-macros] merge missing-require-macros)
564
- ast'))
565
-
566
- (defn- ns-side-effects
567
- ([bound-vars ana-env ast opts cb]
568
- (ns-side-effects false bound-vars ana-env ast opts cb))
569
- ([load bound-vars ana-env {:keys [op] :as ast} opts cb]
570
- (when (:verbose opts)
571
- (debug-prn "Namespace side effects for" (:name ast)))
572
- (if (#{:ns :ns*} op)
573
- (letfn [(check-uses-and-load-macros [res rewritten-ast]
574
- (let [env (:*compiler* bound-vars)
575
- {:keys [uses use-macros reload reloads name]} rewritten-ast]
576
- (if (:error res)
577
- (cb res)
578
- (if (:*load-macros* bound-vars)
579
- (do
580
- (when (:verbose opts) (debug-prn "Processing :use-macros for" name))
581
- (load-macros bound-vars :use-macros use-macros name reload reloads opts
582
- (fn [res]
583
- (if (:error res)
584
- (cb res)
585
- (let [{:keys [require-macros] :as rewritten-ast} (rewrite-ns-ast rewritten-ast (:aliased-loads res) true)]
586
- (when (:verbose opts) (debug-prn "Processing :require-macros for" (:name ast)))
587
- (load-macros bound-vars :require-macros require-macros name reload reloads opts
588
- (fn [res']
589
- (if (:error res')
590
- (cb res')
591
- (let [{:keys [use-macros] :as rewritten-ast} (rewrite-ns-ast rewritten-ast (:aliased-loads res) true)
592
- res' (try
593
- (when (seq use-macros)
594
- (when (:verbose opts) (debug-prn "Checking :use-macros for" (:name ast)))
595
- (binding [ana/*analyze-deps* (:*analyze-deps* bound-vars)
596
- env/*compiler* (:*compiler* bound-vars)]
597
- (ana/check-use-macros use-macros env)))
598
- {:value nil}
599
- (catch :default cause
600
- (wrap-error
601
- (ana/error ana-env
602
- (str "Could not parse ns form " (:name ast)) cause))))]
603
- (if (:error res')
604
- (cb res')
605
- (try
606
- (binding [ana/*analyze-deps* (:*analyze-deps* bound-vars)
607
- env/*compiler* (:*compiler* bound-vars)]
608
- (let [ast' (-> rewritten-ast
609
- (ana/check-use-macros-inferring-missing env)
610
- (ana/check-rename-macros-inferring-missing env)
611
- (check-macro-autoload-inferring-missing env))]
612
- (cb {:value ast'})))
613
- (catch :default cause
614
- (cb (wrap-error
615
- (ana/error ana-env
616
- (str "Could not parse ns form " (:name ast)) cause)))))))))))))))
617
- (try
618
- (when (:verbose opts) (debug-prn "Checking uses"))
619
- (ana/check-uses
620
- (when (and (:*analyze-deps* bound-vars) (seq uses))
621
- (ana/missing-uses uses env))
622
- env)
623
- (cb {:value ast})
624
- (catch :default cause
625
- (cb (wrap-error
626
- (ana/error ana-env
627
- (str "Could not parse ns form " (:name ast)) cause)))))))))]
628
- (cond
629
- (and load (seq (:deps ast)))
630
- (let [{:keys [reload name deps]} ast]
631
- (load-deps bound-vars ana-env name deps (or (:require reload) (:use reload)) (dissoc opts :macros-ns)
632
- #(check-uses-and-load-macros % (rewrite-ns-ast ast (:aliased-loads %)))))
633
-
634
- (and (not load) (:*analyze-deps* bound-vars) (seq (:deps ast)))
635
- (analyze-deps bound-vars ana-env (:name ast) (:deps ast) (dissoc opts :macros-ns)
636
- #(check-uses-and-load-macros % (rewrite-ns-ast ast (:aliased-loads %))))
637
-
638
- :else
639
- (check-uses-and-load-macros {:value nil} ast)))
640
- (cb {:value ast}))))
641
-
642
- (defn- node-side-effects
643
- [bound-vars sb deps ns-name emit-nil-result?]
644
- (doseq [dep deps]
645
- (.append sb
646
- (with-out-str
647
- (comp/emitln (munge ns-name) "."
648
- (ana/munge-node-lib dep)
649
- " = require('" dep "');"))))
650
- (when (and (seq deps) emit-nil-result?)
651
- (.append sb "null;")))
652
-
653
- (defn- global-exports-side-effects
654
- [bound-vars sb deps ns-name opts]
655
- (let [{:keys [js-dependency-index]} @(:*compiler* bound-vars)]
656
- (doseq [dep deps]
657
- (let [{:keys [global-exports]} (get js-dependency-index (name dep))]
658
- (.append sb
659
- (with-out-str
660
- (comp/emit-global-export ns-name global-exports dep opts)))))
661
- (when (and (seq deps) (:def-emits-var opts))
662
- (.append sb "null;"))))
663
-
664
- (defn- trampoline-safe
665
- "Returns a new function that calls f but discards any return value,
666
- returning nil instead, thus avoiding any inadvertent trampoline continuation
667
- if a function happens to be returned."
668
- [f]
669
- (comp (constantly nil) f))
670
-
671
- (defn- analyze-str* [bound-vars source name opts cb]
672
- (let [rdr (rt/indexing-push-back-reader source 1 name)
673
- cb (trampoline-safe cb)
674
- eof (js-obj)
675
- aenv (ana/empty-env)
676
- the-ns (or (:ns opts) 'cljs.user)
677
- bound-vars (cond-> (merge bound-vars {:*cljs-ns* the-ns})
678
- (:source-map opts) (assoc :*sm-data* (sm-data)))]
679
- (trampoline
680
- (fn analyze-loop [last-ast ns]
681
- (binding [env/*compiler* (:*compiler* bound-vars)
682
- ana/*cljs-ns* ns
683
- ana/*checked-arrays* (:checked-arrays opts)
684
- ana/*cljs-static-fns* (:static-fns opts)
685
- ana/*fn-invoke-direct* (and (:static-fns opts) (:fn-invoke-direct opts))
686
- *ns* (create-ns ns)
687
- ana/*passes* (:*passes* bound-vars)
688
- r/*alias-map* (alias-map @(:*compiler* bound-vars) ns)
689
- r/*data-readers* (:*data-readers* bound-vars)
690
- r/resolve-symbol resolve-symbol
691
- comp/*source-map-data* (:*sm-data* bound-vars)
692
- ana/*cljs-file* (:cljs-file opts)]
693
- (let [res (try
694
- {:value (read eof rdr)}
695
- (catch :default cause
696
- (wrap-error
697
- (ana/error aenv
698
- (str "Could not analyze " name) cause))))]
699
- (if (:error res)
700
- (cb res)
701
- (let [form (:value res)]
702
- (if-not (identical? eof form)
703
- (let [aenv (cond-> (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
704
- (:context opts) (assoc :context (:context opts))
705
- (:def-emits-var opts) (assoc :def-emits-var true))
706
- res (try
707
- {:value (ana/analyze aenv form nil opts)}
708
- (catch :default cause
709
- (wrap-error
710
- (ana/error aenv
711
- (str "Could not analyze " name) cause))))]
712
- (if (:error res)
713
- (cb res)
714
- (let [ast (:value res)]
715
- (if (#{:ns :ns*} (:op ast))
716
- ((trampoline-safe ns-side-effects) bound-vars aenv ast opts
717
- (fn [res]
718
- (if (:error res)
719
- (cb res)
720
- (trampoline analyze-loop ast (:name ast)))))
721
- #(analyze-loop ast ns)))))
722
- (cb {:value last-ast}))))))) nil the-ns)))
723
-
724
- (defn analyze-str
725
- "Analyze ClojureScript source. The compiler state will be populated with
726
- the results of analyzes. The parameters:
727
-
728
- state (atom)
729
- the compiler state
730
-
731
- source (string)
732
- the ClojureScript source
733
-
734
- name (symbol or string)
735
- optional, the name of the source
736
-
737
- opts (map)
738
- compilation options.
739
-
740
- :eval - eval function to invoke, see *eval-fn*
741
- :load - library resolution function, see *load-fn*
742
- :source-map - set to true to generate inline source map information
743
- :def-emits-var - sets whether def (and derived) forms return either a Var
744
- (if set to true) or the def init value (if false).
745
- Defaults to false.
746
- :checked-arrays - if :warn or :error, checks inferred types and values passed
747
- to aget/aset. Logs for incorrect values if :warn, throws if
748
- :error. Defaults to false.
749
- :static-fns - employ static dispatch to specific function arities in
750
- emitted JavaScript, as opposed to making use of the
751
- `call` construct. Defaults to false.
752
- :fn-invoke-direct - if `true`, does not generate `.call(null...)` calls for
753
- unknown functions, but instead direct invokes via
754
- `f(a0,a1...)`. Defaults to `false`.
755
- :target - use `:nodejs` if targeting Node.js. Takes no other options
756
- at the moment.
757
- :ns - optional, the namespace in which to evaluate the source.
758
- :verbose - optional, emit details from compiler activity. Defaults to
759
- false.
760
- :context - optional, sets the context for the source. Possible values
761
- are `:expr`, `:statement` and `:return`. Defaults to
762
- `:statement`.
763
-
764
- cb (function)
765
- callback, will be invoked with a map. If successful the map will contain
766
- a key :value, the actual value is not meaningful. If unsuccessful the
767
- map will contain a key :error with an ex-info instance describing the cause
768
- of failure."
769
- ([state source cb]
770
- (analyze-str state source nil cb))
771
- ([state source name cb]
772
- (analyze-str state source name nil cb))
773
- ([state source name opts cb]
774
- {:pre [(atom? state) (string? source)
775
- (valid-name? name) (valid-opts? opts) (fn? cb)]}
776
- (analyze-str*
777
- {:*compiler* state
778
- :*data-readers* tags/*cljs-data-readers*
779
- :*passes* (or (:passes opts) ana/*passes*)
780
- :*analyze-deps* (:analyze-deps opts true)
781
- :*cljs-dep-set* ana/*cljs-dep-set*
782
- :*load-macros* (:load-macros opts true)
783
- :*load-fn* (or (:load opts) *load-fn*)
784
- :*eval-fn* (or (:eval opts) *eval-fn*)}
785
- source name opts cb)))
786
-
787
- ;; -----------------------------------------------------------------------------
788
- ;; Eval
789
-
790
- (declare ^{:arglists '([])} clear-fns!)
791
-
792
- (defn- eval* [bound-vars form opts cb]
793
- (let [the-ns (or (:ns opts) 'cljs.user)
794
- bound-vars (cond-> (merge bound-vars {:*cljs-ns* the-ns})
795
- (:source-map opts) (assoc :*sm-data* (sm-data)))]
796
- (clear-fns!)
797
- (binding [env/*compiler* (:*compiler* bound-vars)
798
- *eval-fn* (:*eval-fn* bound-vars)
799
- ana/*cljs-ns* (:*cljs-ns* bound-vars)
800
- ana/*checked-arrays* (:checked-arrays opts)
801
- ana/*cljs-static-fns* (:static-fns opts)
802
- ana/*fn-invoke-direct* (and (:static-fns opts) (:fn-invoke-direct opts))
803
- *ns* (create-ns (:*cljs-ns* bound-vars))
804
- r/*alias-map* (alias-map @(:*compiler* bound-vars) (:*cljs-ns* bound-vars))
805
- r/*data-readers* (:*data-readers* bound-vars)
806
- r/resolve-symbol resolve-symbol
807
- comp/*source-map-data* (:*sm-data* bound-vars)]
808
- (let [aenv (ana/empty-env)
809
- aenv (cond-> (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
810
- (:context opts) (assoc :context (:context opts))
811
- (:def-emits-var opts) (assoc :def-emits-var true))
812
- res (try
813
- {:value (ana/analyze aenv form nil opts)}
814
- (catch :default cause
815
- (wrap-error
816
- (ana/error aenv
817
- (str "Could not eval " form) cause))))]
818
- (if (:error res)
819
- (cb res)
820
- (let [ast (:value res)
821
- [node-deps ast] (if (keyword-identical? (:target opts) :nodejs)
822
- (let [{node-libs true libs-to-load false} (group-by ana/node-module-dep? (:deps ast))]
823
- [node-libs (assoc ast :deps libs-to-load)])
824
- [nil ast])]
825
- (if (#{:ns :ns*} (:op ast))
826
- (ns-side-effects true bound-vars aenv ast opts
827
- (fn [res]
828
- (if (:error res)
829
- (cb res)
830
- (let [ns-name (:name ast)
831
- sb (StringBuffer.)]
832
- (.append sb
833
- (with-out-str (comp/emitln (str "goog.provide(\"" (comp/munge ns-name) "\");"))))
834
- (when-not (nil? node-deps)
835
- (node-side-effects bound-vars sb node-deps ns-name (:def-emits-var opts)))
836
- (global-exports-side-effects bound-vars sb
837
- (filter ana/dep-has-global-exports? (:deps ast))
838
- ns-name opts)
839
- (cb (try
840
- {:ns ns-name :value ((:*eval-fn* bound-vars) {:source (.toString sb)})}
841
- (catch :default cause
842
- (wrap-error (ana/error aenv "ERROR" cause)))))))))
843
- (let [src (with-out-str (comp/emit ast))]
844
- (cb (try
845
- {:value ((:*eval-fn* bound-vars) {:source src})}
846
- (catch :default cause
847
- (wrap-error (ana/error aenv "ERROR" cause)))))))))))))
848
-
849
- (defn eval
850
- "Evaluate a single ClojureScript form. The parameters:
851
-
852
- state (atom)
853
- the compiler state
854
-
855
- form (s-expr)
856
- the ClojureScript source
857
-
858
- opts (map)
859
- compilation options.
860
-
861
- :eval - eval function to invoke, see *eval-fn*
862
- :load - library resolution function, see *load-fn*
863
- :source-map - set to true to generate inline source map information
864
- :def-emits-var - sets whether def (and derived) forms return either a Var
865
- (if set to true) or the def init value (if false). Default
866
- is false.
867
- :checked-arrays - if :warn or :error, checks inferred types and values passed
868
- to aget/aset. Logs for incorrect values if :warn, throws if
869
- :error. Defaults to false.
870
- :static-fns - employ static dispatch to specific function arities in
871
- emitted JavaScript, as opposed to making use of the
872
- `call` construct. Defaults to false.
873
- :fn-invoke-direct - if `true`, does not generate `.call(null...)` calls for
874
- unknown functions, but instead direct invokes via
875
- `f(a0,a1...)`. Defaults to `false`.
876
- :target - use `:nodejs` if targeting Node.js. Takes no other options
877
- at the moment.
878
- :ns - optional, the namespace in which to evaluate the source.
879
- :verbose - optional, emit details from compiler activity. Defaults to
880
- false.
881
- :context - optional, sets the context for the source. Possible values
882
- are `:expr`, `:statement` and `:return`. Defaults to
883
- `:statement`.
884
-
885
- cb (function)
886
- callback, will be invoked with a map. If successful the map will contain
887
- a key :value with the result of evalution. If unsuccessful the map will
888
- contain a key :error with an ex-info instance describing the cause of
889
- failure."
890
- ([state form cb]
891
- (eval state form nil cb))
892
- ([state form opts cb]
893
- (eval*
894
- {:*compiler* state
895
- :*data-readers* tags/*cljs-data-readers*
896
- :*analyze-deps* (:analyze-deps opts true)
897
- :*cljs-dep-set* ana/*cljs-dep-set*
898
- :*load-macros* (:load-macros opts true)
899
- :*load-fn* (or (:load opts) *load-fn*)
900
- :*eval-fn* (or (:eval opts) *eval-fn*)}
901
- form opts cb)))
902
-
903
- ;; -----------------------------------------------------------------------------
904
- ;; Compile
905
-
906
- (defn- compile-str* [bound-vars source name opts cb]
907
- (let [rdr (rt/indexing-push-back-reader source 1 name)
908
- cb (trampoline-safe cb)
909
- eof (js-obj)
910
- aenv (ana/empty-env)
911
- sb (StringBuffer.)
912
- the-ns (or (:ns opts) 'cljs.user)
913
- bound-vars (cond-> (merge bound-vars {:*cljs-ns* the-ns})
914
- (:source-map opts) (assoc :*sm-data* (sm-data)))]
915
- (trampoline
916
- (fn compile-loop [ns]
917
- (binding [env/*compiler* (:*compiler* bound-vars)
918
- *eval-fn* (:*eval-fn* bound-vars)
919
- ana/*cljs-ns* ns
920
- ana/*checked-arrays* (:checked-arrays opts)
921
- ana/*cljs-static-fns* (:static-fns opts)
922
- ana/*fn-invoke-direct* (and (:static-fns opts) (:fn-invoke-direct opts))
923
- *ns* (create-ns ns)
924
- r/*alias-map* (alias-map @(:*compiler* bound-vars) ns)
925
- r/*data-readers* (:*data-readers* bound-vars)
926
- r/resolve-symbol resolve-symbol
927
- comp/*source-map-data* (:*sm-data* bound-vars)]
928
- (let [res (try
929
- {:value (read eof rdr)}
930
- (catch :default cause
931
- (wrap-error
932
- (ana/error aenv
933
- (str "Could not compile " name) cause))))]
934
- (if (:error res)
935
- (cb res)
936
- (let [form (:value res)]
937
- (if-not (identical? eof form)
938
- (let [aenv (cond-> (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
939
- (:context opts) (assoc :context (:context opts))
940
- (:def-emits-var opts) (assoc :def-emits-var true))
941
- res (try
942
- {:value (ana/analyze aenv form nil opts)}
943
- (catch :default cause
944
- (wrap-error
945
- (ana/error aenv
946
- (str "Could not compile " name) cause))))]
947
- (if (:error res)
948
- (cb res)
949
- (let [ast (:value res)
950
- [node-deps ast] (if (keyword-identical? (:target opts) :nodejs)
951
- (let [{node-libs true libs-to-load false} (group-by ana/node-module-dep? (:deps ast))]
952
- [node-libs (assoc ast :deps libs-to-load)])
953
- [nil ast])]
954
- (if (#{:ns :ns*} (:op ast))
955
- ((trampoline-safe ns-side-effects) bound-vars aenv ast opts
956
- (fn [res]
957
- (if (:error res)
958
- (cb res)
959
- (let [ns-name (:name ast)]
960
- (.append sb (with-out-str (comp/emit (:value res))))
961
- (when-not (nil? node-deps)
962
- (node-side-effects bound-vars sb node-deps ns-name (:def-emits-var opts)))
963
- (trampoline compile-loop (:name ast))))))
964
- (do
965
- (.append sb (with-out-str (comp/emit ast)))
966
- #(compile-loop ns))))))
967
- (do
968
- (when (:source-map opts)
969
- (append-source-map env/*compiler*
970
- name source sb @comp/*source-map-data* opts))
971
- (cb {:value (.toString sb)})))))))) the-ns)))
972
-
973
- (defn compile-str
974
- "Compile ClojureScript source into JavaScript. The parameters:
975
-
976
- state (atom)
977
- the compiler state
978
-
979
- source (string)
980
- the ClojureScript source
981
-
982
- name (symbol or string)
983
- optional, the name of the source - used as key in :source-maps
984
-
985
- opts (map)
986
- compilation options.
987
-
988
- :eval - eval function to invoke, see *eval-fn*
989
- :load - library resolution function, see *load-fn*
990
- :source-map - set to true to generate inline source map information
991
- :def-emits-var - sets whether def (and derived) forms return either a Var
992
- (if set to true) or the def init value (if false). Default
993
- is false.
994
- :checked-arrays - if :warn or :error, checks inferred types and values passed
995
- to aget/aset. Logs for incorrect values if :warn, throws if
996
- :error. Defaults to false.
997
- :static-fns - employ static dispatch to specific function arities in
998
- emitted JavaScript, as opposed to making use of the
999
- `call` construct. Defaults to false.
1000
- :fn-invoke-direct - if `true`, does not generate `.call(null...)` calls for
1001
- unknown functions, but instead direct invokes via
1002
- `f(a0,a1...)`. Defaults to `false`.
1003
- :target - use `:nodejs` if targeting Node.js. Takes no other options
1004
- at the moment.
1005
- :ns - optional, the namespace in which to evaluate the source.
1006
- :verbose - optional, emit details from compiler activity. Defaults to
1007
- false.
1008
- :context - optional, sets the context for the source. Possible values
1009
- are `:expr`, `:statement` and `:return`. Defaults to
1010
- `:statement`.
1011
-
1012
- cb (function)
1013
- callback, will be invoked with a map. If successful the map will contain
1014
- a key :value with the compilation result (string). If unsuccessful the map
1015
- will contain a key :error with an ex-info instance describing the cause
1016
- of failure."
1017
- ([state source cb]
1018
- (compile-str state source nil cb))
1019
- ([state source name cb]
1020
- (compile-str state source name nil cb))
1021
- ([state source name opts cb]
1022
- {:pre [(atom? state) (string? source)
1023
- (valid-name? name) (valid-opts? opts) (fn? cb)]}
1024
- (compile-str*
1025
- {:*compiler* state
1026
- :*data-readers* tags/*cljs-data-readers*
1027
- :*cljs-dep-set* ana/*cljs-dep-set*
1028
- :*analyze-deps* (:analyze-deps opts true)
1029
- :*load-macros* (:load-macros opts true)
1030
- :*load-fn* (or (:load opts) *load-fn*)
1031
- :*eval-fn* (or (:eval opts) *eval-fn*)
1032
- :*sm-data* (when (:source-map opts) (sm-data))}
1033
- source name opts cb)))
1034
-
1035
- ;; -----------------------------------------------------------------------------
1036
- ;; Evaluate String
1037
-
1038
- (defn- eval-str* [bound-vars source name opts cb]
1039
- (let [rdr (rt/indexing-push-back-reader source 1 name)
1040
- cb (trampoline-safe cb)
1041
- eof (js-obj)
1042
- aenv (ana/empty-env)
1043
- sb (StringBuffer.)
1044
- the-ns (or (:ns opts) 'cljs.user)
1045
- bound-vars (cond-> (merge bound-vars {:*cljs-ns* the-ns})
1046
- (:source-map opts) (assoc :*sm-data* (sm-data)))
1047
- aname (cond-> name (:macros-ns opts) ana/macro-ns-name)]
1048
- (when (:verbose opts) (debug-prn "Evaluating" name))
1049
- (clear-fns!)
1050
- (trampoline
1051
- (fn compile-loop [ns]
1052
- (binding [env/*compiler* (:*compiler* bound-vars)
1053
- *eval-fn* (:*eval-fn* bound-vars)
1054
- ana/*cljs-ns* ns
1055
- ana/*checked-arrays* (:checked-arrays opts)
1056
- ana/*cljs-static-fns* (:static-fns opts)
1057
- ana/*fn-invoke-direct* (and (:static-fns opts) (:fn-invoke-direct opts))
1058
- *ns* (create-ns ns)
1059
- r/*alias-map* (alias-map @(:*compiler* bound-vars) ns)
1060
- r/*data-readers* (:*data-readers* bound-vars)
1061
- r/resolve-symbol resolve-symbol
1062
- comp/*source-map-data* (:*sm-data* bound-vars)
1063
- ana/*cljs-file* (:cljs-file opts)]
1064
- (let [res (try
1065
- {:value (read eof rdr)}
1066
- (catch :default cause
1067
- (wrap-error
1068
- (ana/error aenv
1069
- (str "Could not eval " name) cause))))]
1070
- (if (:error res)
1071
- (cb res)
1072
- (let [form (:value res)]
1073
- (if-not (identical? eof form)
1074
- (let [aenv (cond-> (assoc aenv :ns (ana/get-namespace ns))
1075
- (:context opts) (assoc :context (:context opts))
1076
- (:def-emits-var opts) (assoc :def-emits-var true))
1077
- res (try
1078
- {:value (ana/analyze aenv form nil opts)}
1079
- (catch :default cause
1080
- (wrap-error
1081
- (ana/error aenv
1082
- (str "Could not eval " name) cause))))]
1083
- (if (:error res)
1084
- (cb res)
1085
- (let [ast (:value res)
1086
- ns' ana/*cljs-ns*
1087
- [node-deps ast] (if (keyword-identical? (:target opts) :nodejs)
1088
- (let [{node-libs true libs-to-load false} (group-by ana/node-module-dep? (:deps ast))]
1089
- [node-libs (assoc ast :deps libs-to-load)])
1090
- [nil ast])]
1091
- (if (#{:ns :ns*} (:op ast))
1092
- (do
1093
- (.append sb
1094
- (with-out-str (comp/emitln (str "goog.provide(\"" (comp/munge (:name ast)) "\");"))))
1095
- ((trampoline-safe ns-side-effects) true bound-vars aenv ast opts
1096
- (fn [res]
1097
- (if (:error res)
1098
- (cb res)
1099
- (let [ns-name (:name ast)]
1100
- (when-not (nil? node-deps)
1101
- (node-side-effects bound-vars sb node-deps ns-name (:def-emits-var opts)))
1102
- (global-exports-side-effects bound-vars sb
1103
- (filter ana/dep-has-global-exports? (:deps ast))
1104
- ns-name opts)
1105
- (trampoline compile-loop ns'))))))
1106
- (do
1107
- (env/with-compiler-env (assoc @(:*compiler* bound-vars) :options opts)
1108
- (.append sb (with-out-str (comp/emit ast))))
1109
- #(compile-loop ns'))))))
1110
- (do
1111
- (when (:source-map opts)
1112
- (append-source-map env/*compiler*
1113
- aname source sb @comp/*source-map-data* opts))
1114
- (when (symbol? aname)
1115
- (ana/dump-specs aname))
1116
- (let [js-source (.toString sb)
1117
- evalm {:lang :clj
1118
- :name name
1119
- :path (ns->relpath name)
1120
- :source js-source
1121
- :cache (get-in @env/*compiler* [::ana/namespaces aname])}
1122
- complete (fn [res]
1123
- (if (:error res)
1124
- (cb res)
1125
- (do
1126
- (when (:verbose opts)
1127
- (debug-prn js-source))
1128
- (let [res (try
1129
- {:ns ns :value (*eval-fn* evalm)}
1130
- (catch :default cause
1131
- (wrap-error (ana/error aenv "ERROR" cause))))]
1132
- (cb res)))))]
1133
- (if-let [f (:cache-source opts)]
1134
- ((trampoline-safe f) evalm complete)
1135
- (complete {:value nil}))))))))))
1136
- (:*cljs-ns* bound-vars))))
1137
-
1138
- (defn eval-str
1139
- "Evalute ClojureScript source given as a string. The parameters:
1140
-
1141
- state (atom)
1142
- the compiler state
1143
-
1144
- source (string)
1145
- the ClojureScript source
1146
-
1147
- name (symbol or string)
1148
- optional, the name of the source - used as key in :source-maps
1149
-
1150
- opts (map)
1151
- compilation options.
1152
-
1153
- :eval - eval function to invoke, see *eval-fn*
1154
- :load - library resolution function, see *load-fn*
1155
- :source-map - set to true to generate inline source map information
1156
- :cache-source - optional, a function to run side-effects with the
1157
- compilation result prior to actual evalution. This function
1158
- takes two arguments, the first is the eval map, the source
1159
- will be under :source. The second argument is a callback of
1160
- one argument. If an error occurs an :error key should be
1161
- supplied.
1162
- :def-emits-var - sets whether def (and derived) forms return either a Var
1163
- (if set to true) or the def init value (if false). Default
1164
- is false.
1165
- :checked-arrays - if :warn or :error, checks inferred types and values passed
1166
- to aget/aset. Logs for incorrect values if :warn, throws if
1167
- :error. Defaults to false.
1168
- :static-fns - employ static dispatch to specific function arities in
1169
- emitted JavaScript, as opposed to making use of the
1170
- `call` construct. Defaults to false.
1171
- :fn-invoke-direct - if `true`, does not generate `.call(null...)` calls for
1172
- unknown functions, but instead direct invokes via
1173
- `f(a0,a1...)`. Defaults to `false`.
1174
- :target - use `:nodejs` if targeting Node.js. Takes no other options
1175
- at the moment.
1176
- :ns - optional, the namespace in which to evaluate the source.
1177
- :verbose - optional, emit details from compiler activity. Defaults to
1178
- false.
1179
- :context - optional, sets the context for the source. Possible values
1180
- are `:expr`, `:statement` and `:return`. Defaults to
1181
- `:statement`.
1182
-
1183
- cb (function)
1184
- callback, will be invoked with a map. If succesful the map will contain
1185
- a :value key with the result of evaluation and :ns the current namespace.
1186
- If unsuccessful will contain a :error key with an ex-info instance describing
1187
- the cause of failure."
1188
- ([state source cb]
1189
- (eval-str state source nil cb))
1190
- ([state source name cb]
1191
- (eval-str state source name nil cb))
1192
- ([state source name opts cb]
1193
- {:pre [(atom? state) (string? source)
1194
- (valid-name? name) (valid-opts? opts) (fn? cb)]}
1195
- (eval-str*
1196
- {:*compiler* state
1197
- :*data-readers* tags/*cljs-data-readers*
1198
- :*analyze-deps* (:analyze-deps opts true)
1199
- :*cljs-dep-set* ana/*cljs-dep-set*
1200
- :*load-macros* (:load-macros opts true)
1201
- :*load-fn* (or (:load opts) *load-fn*)
1202
- :*eval-fn* (or (:eval opts) *eval-fn*)}
1203
- source name opts cb)))
1204
-
1205
- ;;; Support for cljs.core/eval
1206
-
1207
- ;; The following volatiles and fns set up a scheme to
1208
- ;; emit function values into JavaScript as numeric
1209
- ;; references that are looked up. Needed to implement eval.
1210
-
1211
- (defonce ^:private fn-index (volatile! 0))
1212
- (defonce ^:private fn-refs (volatile! {}))
1213
-
1214
- (defn- clear-fns!
1215
- "Clears saved functions."
1216
- []
1217
- (vreset! fn-refs {}))
1218
-
1219
- (defn- put-fn
1220
- "Saves a function, returning a numeric representation."
1221
- [f]
1222
- (let [n (vswap! fn-index inc)]
1223
- (vswap! fn-refs assoc n f)
1224
- n))
1225
-
1226
- (defn- get-fn
1227
- "Gets a function, given its numeric representation."
1228
- [n]
1229
- (get @fn-refs n))
1230
-
1231
- (defn- emit-fn [f]
1232
- (print "cljs.js.get_fn(" (put-fn f) ")"))
1233
-
1234
- (defmethod comp/emit-constant* js/Function
1235
- [f]
1236
- (emit-fn f))
1237
-
1238
- (defmethod comp/emit-constant* cljs.core/Var
1239
- [f]
1240
- (emit-fn f))
1241
-
1242
- (defn- eval-impl
1243
- ([form]
1244
- (eval-impl form (.-name *ns*)))
1245
- ([form ns]
1246
- (let [result (atom nil)]
1247
- (let [st env/*compiler*]
1248
- (eval st form
1249
- {:ns ns
1250
- :context :expr
1251
- :def-emits-var true}
1252
- (fn [{:keys [value error]}]
1253
- (if error
1254
- (throw error)
1255
- (reset! result value)))))
1256
- @result)))
1257
-
1258
- (set! *eval* eval-impl)
1259
-
1260
- (comment
1261
- (require '[cljs.js :as cljs]
1262
- '[cljs.analyzer :as ana])
1263
-
1264
- (def vm (js/require "vm"))
1265
- (def fs (js/require "fs"))
1266
- (def st (cljs/empty-state))
1267
-
1268
- (set! *target* "nodejs")
1269
-
1270
- (defn node-eval [{:keys [name source]}]
1271
- (.runInThisContext vm source (str (munge name) ".js")))
1272
-
1273
- (def libs
1274
- {'bootstrap-test.core :cljs
1275
- 'bootstrap-test.macros :clj
1276
- 'bootstrap-test.helper :clj})
1277
-
1278
- (defn node-load [{:keys [name macros]} cb]
1279
- (if (contains? libs name)
1280
- (let [path (str "src/test/cljs/" (cljs/ns->relpath name)
1281
- "." (cljs.core/name (get libs name)))]
1282
- (.readFile fs path "utf-8"
1283
- (fn [err src]
1284
- (cb (if-not err
1285
- {:lang :clj :source src}
1286
- (.error js/console err))))))
1287
- (cb nil)))
1288
-
1289
- (defn elide-env [env ast opts]
1290
- (dissoc ast :env))
1291
-
1292
- (cljs/analyze-str st "(+ 1 1)" nil
1293
- {:passes [ana/infer-type elide-env]
1294
- :eval node-eval}
1295
- (fn [{:keys [value]}]
1296
- (println value)))
1297
-
1298
- (cljs/eval st '(defn foo [a b] (+ a b))
1299
- {:eval node-eval}
1300
- (fn [res]
1301
- (println res)))
1302
-
1303
- (cljs/compile-str st "(defprotocol IFoo (foo [this]))"
1304
- (fn [{:keys [value]}]
1305
- (println "Source:")
1306
- (println value)))
1307
-
1308
- (cljs/eval-str st
1309
- "(defn foo [a b] (+ a b))
1310
- (defn bar [c d] (+ c d))"
1311
- nil
1312
- {:eval node-eval}
1313
- (fn [res]
1314
- (println res)))
1315
-
1316
- (cljs/eval-str st "1"
1317
- nil
1318
- {:eval node-eval
1319
- :context :expr}
1320
- (fn [res]
1321
- (println res)))
1322
-
1323
- (cljs/eval-str st "(def x 1)"
1324
- nil
1325
- {:eval node-eval
1326
- :context :expr
1327
- :def-emits-var true}
1328
- (fn [res]
1329
- (println res)))
1330
-
1331
- (cljs/eval st '(ns foo.bar)
1332
- {:eval node-eval}
1333
- (fn [res]
1334
- (println res)))
1335
-
1336
- (cljs/eval st '(def x 1)
1337
- {:eval node-eval
1338
- :context :expr
1339
- :def-emits-var true
1340
- :ns 'foo.bar}
1341
- (fn [res]
1342
- (println res)))
1343
-
1344
- (cljs/compile-str st "(defn foo\n[a b]\n(+ a b))" 'cljs.foo
1345
- {:verbose true :source-map true}
1346
- (fn [js-source]
1347
- (println "Source:")
1348
- (println js-source)))
1349
-
1350
- (cljs/eval-str st
1351
- "(ns foo.bar (:require [bootstrap-test.core]))\n(bootstrap-test.core/foo 3 4)"
1352
- 'foo.bar
1353
- {:verbose true
1354
- :source-map true
1355
- :eval node-eval
1356
- :load node-load}
1357
- (fn [ret]
1358
- (println ret)))
1359
-
1360
- (cljs/eval-str st
1361
- "(ns foo.bar (:require-macros [bootstrap-test.macros :refer [foo]]))\n(foo 4 4)"
1362
- 'foo.bar
1363
- {:verbose true
1364
- :source-map true
1365
- :eval node-eval
1366
- :load node-load}
1367
- (fn [{:keys [error] :as res}]
1368
- (if error
1369
- (do
1370
- (println "Error:" error)
1371
- (println (.. error -cause -stack)))
1372
- (println "Result:" res))))
1373
-
1374
- (cljs/compile-str st
1375
- "(ns foo.bar (:require-macros [bootstrap-test.macros :refer [foo]]))\n(foo 4 4)"
1376
- 'foo.bar
1377
- {:verbose true
1378
- :source-map true
1379
- :eval node-eval
1380
- :load node-load}
1381
- (fn [{:keys [error] :as res}]
1382
- (if error
1383
- (do
1384
- (println "Error:" error)
1385
- (println (.. error -cause -stack)))
1386
- (println "Result:" res))))
1387
-
1388
- (cljs/eval-str st
1389
- "(ns foo.bar)\n(first [1 2 3])"
1390
- 'foo.bar
1391
- {:verbose true
1392
- :source-map true
1393
- :eval node-eval
1394
- :load node-load}
1395
- (fn [{:keys [error] :as res}]
1396
- (if error
1397
- (do
1398
- (println error)
1399
- (println (.. error -cause -stack)))
1400
- (println res))))
1401
-
1402
- (cljs/eval-str st
1403
- "(ns foo.bar)\n(map inc [1 2 3])"
1404
- 'foo.bar
1405
- {:verbose true
1406
- :source-map true
1407
- :eval node-eval
1408
- :load node-load}
1409
- (fn [{:keys [error] :as res}]
1410
- (if error
1411
- (do
1412
- (println error)
1413
- (println (.. error -cause -stack)))
1414
- (println res))))
1415
-
1416
- ;; *NOT* source mapped under Node.js
1417
- ;; source-map-support does not yet work, users will need to map
1418
- ;; themselves
1419
- (cljs/eval-str st
1420
- "(ns foo.bar)\n(ffirst [1 2 3])"
1421
- 'foo.bar
1422
- {:verbose true
1423
- :source-map true
1424
- :eval node-eval
1425
- :load node-load}
1426
- (fn [{:keys [error] :as res}]
1427
- (if error
1428
- (do
1429
- (println error)
1430
- (println (.. error -cause -stack)))
1431
- (println res))))
1432
- )