Skip to content

Commit 9e662c3

Browse files
Deraendnolen
authored andcommitted
CLJS-1367: Better api call arguments
This change adds additional arity for api calls which need compiler-env. Old arities continue to use the dynamic var. Also, api calls which take options map as argument, now use :warning-handlers options to set value for dynamic var cljs.analyzer/*cljs-warning-handlers*.
1 parent 70d9405 commit 9e662c3

File tree

5 files changed

+153
-81
lines changed

5 files changed

+153
-81
lines changed

src/main/clojure/cljs/analyzer/api.clj

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@
4242

4343
(defn get-options
4444
"Return the compiler options from compiler state."
45-
[]
46-
(get @env/*compiler* :options))
45+
([] (get-options env/*compiler*))
46+
([state]
47+
(get @state :options)))
4748

4849
(defn analyze
4950
"Given an environment, a map containing {:locals (mapping of names to bindings), :context
@@ -52,9 +53,13 @@
5253
containing at least :form, :op and :env keys). If expr has any (immediately)
5354
nested exprs, must have :children [exprs...] entry. This will
5455
facilitate code walking without knowing the details of the op set."
55-
([env form] (ana/analyze env form nil))
56-
([env form name] (ana/analyze env form name nil))
57-
([env form name opts] (ana/analyze env form name opts)))
56+
([env form] (analyze env form nil))
57+
([env form name] (analyze env form name nil))
58+
([env form name opts] (analyze env/*compiler* env form name opts))
59+
([state env form name opts]
60+
(env/with-compiler-env state
61+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
62+
(ana/analyze env form name opts)))))
5863

5964
(defn forms-seq
6065
"Seq of Clojure/ClojureScript forms from rdr, a java.io.Reader. Optionally
@@ -72,9 +77,13 @@
7277
be used for *analyze-deps* and *load-macros* bindings respectively. This
7378
function does _not_ side-effect the ambient compilation environment unless
7479
requested via opts where :restore is false."
75-
([src] (ana/parse-ns src nil nil))
76-
([src opts] (ana/parse-ns src nil opts))
77-
([src dest opts] (ana/parse-ns src dest opts)))
80+
([src] (parse-ns src nil nil))
81+
([src opts] (parse-ns src nil opts))
82+
([src dest opts] (parse-ns env/*compiler* src dest opts))
83+
([state src dest opts]
84+
(env/with-compiler-env state
85+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
86+
(ana/parse-ns src dest opts)))))
7887

7988
(defn analyze-file
8089
"Given a java.io.File, java.net.URL or a string identifying a resource on the
@@ -85,8 +94,12 @@
8594
compiler options, if :cache-analysis true will cache analysis to
8695
\":output-dir/some/ns/foo.cljs.cache.edn\". This function does not return a
8796
meaningful value."
88-
([f] (ana/analyze-file f nil))
89-
([f opts] (ana/analyze-file f opts)))
97+
([f] (analyze-file f nil))
98+
([f opts] (analyze-file env/*compiler* f opts))
99+
([state f opts]
100+
(env/with-compiler-env state
101+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
102+
(ana/analyze-file f opts)))))
90103

91104
;; =============================================================================
92105
;; Main API
@@ -105,53 +118,59 @@
105118
(defn all-ns
106119
"Return all namespaces. Analagous to clojure.core/all-ns but
107120
returns symbols identifying namespaces not Namespace instances."
108-
[]
109-
(keys (get @env/*compiler* ::ana/namespaces)))
121+
([] (all-ns env/*compiler*))
122+
([state]
123+
(keys (get @state ::ana/namespaces))))
110124

111125
(defn find-ns
112126
"Given a namespace return the corresponding namespace analysis map. Analagous
113127
to clojure.core/find-ns."
114-
[sym]
115-
{:pre [(symbol? sym)]}
116-
(get-in @env/*compiler* [::ana/namespaces sym]))
128+
([sym] (find-ns env/*compiler* sym))
129+
([state sym]
130+
{:pre [(symbol? sym)]}
131+
(get-in @state [::ana/namespaces sym])))
117132

118133
(defn ns-interns
119134
"Given a namespace return all the var analysis maps. Analagous to
120135
clojure.core/ns-interns but returns var analysis maps not vars."
121-
[ns]
122-
{:pre [(symbol? ns)]}
123-
(merge
124-
(get-in @env/*compiler* [::ana/namespaces ns :macros])
125-
(get-in @env/*compiler* [::ana/namespaces ns :defs])))
136+
([ns] (ns-interns env/*compiler*))
137+
([state ns]
138+
{:pre [(symbol? ns)]}
139+
(merge
140+
(get-in @state [::ana/namespaces ns :macros])
141+
(get-in @state [::ana/namespaces ns :defs]))))
126142

127143
(defn ns-publics
128144
"Given a namespace return all the public var analysis maps. Analagous to
129145
clojure.core/ns-publics but returns var analysis maps not vars."
130-
[ns]
131-
{:pre [(symbol? ns)]}
132-
(->> (merge
133-
(get-in @env/*compiler* [::ana/namespaces ns :macros])
134-
(get-in @env/*compiler* [::ana/namespaces ns :defs]))
135-
(remove (fn [[k v]] (:private v)))
136-
(into {})))
146+
([ns] (ns-publics env/*compiler*))
147+
([state ns]
148+
{:pre [(symbol? ns)]}
149+
(->> (merge
150+
(get-in @state [::ana/namespaces ns :macros])
151+
(get-in @state [::ana/namespaces ns :defs]))
152+
(remove (fn [[k v]] (:private v)))
153+
(into {}))))
137154

138155
(defn ns-resolve
139156
"Given a namespace and a symbol return the corresponding var analysis map.
140157
Analagous to clojure.core/ns-resolve but returns var analysis map not Var."
141-
[ns sym]
142-
{:pre [(symbol? ns) (symbol? sym)]}
143-
(get-in @env/*compiler* [::ana/namespaces ns :defs sym]))
158+
([ns sym] (ns-resolve env/*compiler* ns sym))
159+
([state ns sym]
160+
{:pre [(symbol? ns) (symbol? sym)]}
161+
(get-in @state [::ana/namespaces ns :defs sym])))
144162

145163
(defn remove-ns
146164
"Removes the namespace named by the symbol."
147-
[ns]
148-
{:pre [(symbol? ns)]}
149-
(swap! env/*compiler* update-in [::ana/namespaces] dissoc ns))
165+
([ns] (remove-ns env/*compiler* ns))
166+
([state ns]
167+
{:pre [(symbol? ns)]}
168+
(swap! state update-in [::ana/namespaces] dissoc ns)))
150169

151170
(defmacro in-cljs-user
152171
"Binds cljs.analyzer/*cljs-ns* to 'cljs.user and uses the given compilation
153172
environment atom and runs body."
154173
[env & body]
155174
`(binding [cljs.analyzer/*cljs-ns* 'cljs.user]
156175
(cljs.env/with-compiler-env ~env
157-
~@body)))
176+
~@body)))

src/main/clojure/cljs/build/api.clj

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,23 @@
5656
ClojureScript namespaces that require and use the macros from
5757
'example.macros :
5858
(cljs-dependents-for-macro-namespaces 'example.macros) ->
59-
('example.core 'example.util)
60-
61-
This must be called when cljs.env/*compiler* is bound to the
62-
compile env that you are inspecting. See cljs.env/with-compile-env."
63-
[namespaces]
64-
(map :name
65-
(let [namespaces-set (set namespaces)]
66-
(filter (fn [x] (not-empty
67-
(intersection namespaces-set (-> x :require-macros vals set))))
68-
(vals (:cljs.analyzer/namespaces @env/*compiler*))))))
59+
('example.core 'example.util)"
60+
([namespaces] (cljs-dependents-for-macro-namespaces env/*compiler* namespaces))
61+
([state namespaces]
62+
(map :name
63+
(let [namespaces-set (set namespaces)]
64+
(filter (fn [x] (not-empty
65+
(intersection namespaces-set (-> x :require-macros vals set))))
66+
(vals (:cljs.analyzer/namespaces @state)))))))
6967

7068
(defn cljs-ns-dependents
7169
"Given a namespace symbol return a seq of all dependent
7270
namespaces sorted in dependency order. Will include
7371
transient dependents."
74-
[ns]
75-
(ana/ns-dependents ns))
72+
([ns] (cljs-ns-dependents env/*compiler* ns))
73+
([state ns]
74+
(env/with-compiler-env state
75+
(ana/ns-dependents ns))))
7676

7777
(defn parse-js-ns
7878
"Given a Google Closure style JavaScript file or resource return the namespace
@@ -84,15 +84,22 @@
8484
(defn ^File src-file->target-file
8585
"Given a ClojureScript source file return the target file. May optionally
8686
provide build options with :output-dir specified."
87-
([src] (closure/src-file->target-file src))
88-
([src opts] (closure/src-file->target-file src opts)))
87+
([src] (src-file->target-file src nil))
88+
([src opts] (src-file->target-file env/*compiler* src opts))
89+
([state src opts]
90+
(env/with-compiler-env state
91+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
92+
(closure/src-file->target-file src opts)))))
8993

9094
(defn ^String src-file->goog-require
9195
"Given a ClojureScript or Google Closure style JavaScript source file return
9296
the goog.require statement for it."
93-
([src] (closure/src-file->goog-require src))
94-
([src options]
95-
(closure/src-file->goog-require src options)))
97+
([src] (src-file->goog-require src nil))
98+
([src options] (src-file->goog-require env/*compiler* src options))
99+
([state src options]
100+
(env/with-compiler-env state
101+
(binding [ana/*cljs-warning-handlers* (:warning-handlers options ana/*cljs-warning-handlers*)]
102+
(closure/src-file->goog-require src options)))))
96103

97104
;; =============================================================================
98105
;; Main API
@@ -156,8 +163,10 @@
156163

157164
(defn compile
158165
"Given a Compilable, compile it and return an IJavaScript."
159-
[opts compilable]
160-
(closure/compile compilable opts))
166+
([opts compilable] (compile env/*compiler* opts compilable))
167+
([state opts compilable]
168+
(env/with-compiler-env state
169+
(closure/compile compilable opts))))
161170

162171
(defn output-unoptimized
163172
"Ensure that all JavaScript source files are on disk (not in jars),
@@ -172,18 +181,22 @@
172181
(defn build
173182
"Given a source which can be compiled, produce runnable JavaScript."
174183
([source opts]
175-
(closure/build source opts))
184+
(build source opts nil))
176185
([source opts compiler-env]
177-
(closure/build source opts compiler-env)))
186+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
187+
(closure/build source opts compiler-env))))
178188

179189
(defn watch
180190
"Given a source which can be compiled, watch it for changes to produce."
181191
([source opts]
182-
(closure/watch source opts))
192+
(watch source opts (if-not (nil? env/*compiler*)
193+
env/*compiler*
194+
(env/default-compiler-env opts))))
183195
([source opts compiler-env]
184-
(closure/watch source opts compiler-env))
196+
(watch source opts compiler-env nil))
185197
([source opts compiler-env stop]
186-
(closure/watch source opts compiler-env stop)))
198+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
199+
(closure/watch source opts compiler-env stop))))
187200

188201
(comment
189202

@@ -204,4 +217,4 @@
204217
#(target-file-for-cljs-ns % "out-dev")
205218
(env/with-compiler-env test-cenv
206219
(ns-dependents 'clojure.string)))
207-
)
220+
)

src/main/clojure/cljs/compiler/api.clj

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,30 @@
1919

2020
(defn emit
2121
"Given an AST node generated by the analyzer emit JavaScript as a string."
22-
[ast]
23-
(with-out-str
24-
(comp/emit ast)))
22+
([ast] (emit env/*compiler* ast))
23+
([state ast]
24+
(env/with-compiler-env state
25+
(with-out-str
26+
(comp/emit ast)))))
2527

2628
(defn with-core-cljs
2729
"Ensure that core.cljs has been loaded."
2830
([] (comp/with-core-cljs nil))
29-
([opts] (comp/with-core-cljs opts (fn [])))
30-
([opts body] (comp/with-core-cljs opts body)))
31+
([opts] (with-core-cljs opts (fn [])))
32+
([opts body] (with-core-cljs env/*compiler* opts body))
33+
([state opts body]
34+
(env/with-compiler-env state
35+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
36+
(comp/with-core-cljs opts body)))))
3137

3238
(defn requires-compilation?
3339
"Return true if the src file requires compilation."
34-
([src dest]
35-
(comp/requires-compilation? src dest nil))
36-
([src dest opts]
37-
(comp/requires-compilation? src dest opts)))
40+
([src dest] (requires-compilation? src dest nil))
41+
([src dest opts] (requires-compilation? env/*compiler* src dest opts))
42+
([state src dest opts]
43+
(env/with-compiler-env state
44+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
45+
(comp/requires-compilation? src dest opts)))))
3846

3947
(defn compile-file
4048
"Compiles src to a file of the same name, but with a .js extension,
@@ -49,12 +57,13 @@
4957
5058
Returns a map containing {:ns .. :provides .. :requires .. :file ..}.
5159
If the file was not compiled returns only {:file ...}"
52-
([src]
53-
(comp/compile-file src))
54-
([src dest]
55-
(comp/compile-file src dest))
56-
([src dest opts]
57-
(comp/compile-file src dest opts)))
60+
([src] (compile-file src))
61+
([src dest] (compile-file src dest))
62+
([src dest opts] (compile-file env/*compiler* src dest opts))
63+
([state src dest opts]
64+
(env/with-compiler-env state
65+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
66+
(comp/compile-file src dest opts)))))
5867

5968
(defn cljs-files-in
6069
"Return a sequence of all .cljs and .cljc files in the given directory."
@@ -67,9 +76,10 @@
6776
directory mirroring the source directory structure. Returns a list
6877
of maps containing information about each file which was compiled
6978
in dependency order."
70-
([src-dir]
71-
(comp/compile-root src-dir "out"))
72-
([src-dir target-dir]
73-
(comp/compile-root src-dir target-dir nil))
74-
([src-dir target-dir opts]
75-
(comp/compile-root src-dir target-dir opts)))
79+
([src-dir] (compile-root src-dir "out"))
80+
([src-dir target-dir] (compile-root src-dir target-dir nil))
81+
([src-dir target-dir opts] (compile-root env/*compiler* src-dir target-dir opts))
82+
([state src-dir target-dir opts]
83+
(env/with-compiler-env state
84+
(binding [ana/*cljs-warning-handlers* (:warning-handlers opts ana/*cljs-warning-handlers*)]
85+
(with-bindings (api-opts opts) (comp/compile-root src-dir target-dir opts))))))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
(ns cljs.analyzer-api-tests
2+
(:require [cljs.analyzer.api :as ana-api])
3+
(:use clojure.test))
4+
5+
(def warning-form
6+
'(do (defn x [a b] (+ a b))
7+
(x 1 2 3 4)))
8+
9+
(defn warning-handler [counter]
10+
(fn [warning-type env extra]
11+
(when (ana-api/warning-enabled? warning-type)
12+
(swap! counter inc))))
13+
14+
(def test-cenv (atom {}))
15+
(def test-env (ana-api/empty-env))
16+
17+
(deftest with-warning-handlers-test
18+
(let [counter (atom 0)]
19+
(ana-api/analyze test-cenv test-env warning-form nil
20+
{:warning-handlers [(warning-handler counter)]})
21+
(is (= 1 @counter))))
22+
23+
(deftest vary-warning-handlers-test
24+
(let [counter (atom 0)]
25+
(cljs.analyzer/all-warn
26+
(ana-api/analyze test-cenv test-env warning-form nil
27+
{:warning-handlers [(warning-handler counter)]}))
28+
(is (= 1 @counter))))

src/test/clojure/cljs/build_api_tests.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,6 @@
111111
'(bar.core baz.core)))
112112
(is (= (env/with-compiler-env test-cenv
113113
(cljs-ns-dependents 'graph.foo.core))
114-
'(graph.bar.core graph.baz.core))))
114+
'(graph.bar.core graph.baz.core)))
115+
(is (= (cljs-ns-dependents test-cenv 'graph.foo.core)
116+
'(graph.bar.core graph.baz.core))))

0 commit comments

Comments
 (0)