|
20 | 20 |
|
21 | 21 | (def ^:dynamic *ignore-var* false)
|
22 | 22 | (def ^:dynamic *source-file* nil)
|
| 23 | +(def ^:dynamic *goog-ns* nil) |
23 | 24 |
|
24 | 25 | ;; ------------------------------------------------------------------------------
|
25 | 26 | ;; Externs Parsing
|
|
37 | 38 | (if (.isString child)
|
38 | 39 | (symbol (.. child getString)))))))
|
39 | 40 |
|
| 41 | +(defn params->method-params [xs] |
| 42 | + (letfn [(not-opt? [x] |
| 43 | + (not (string/starts-with? (name x) "opt_")))] |
| 44 | + (let [required (into [] (take-while not-opt? xs)) |
| 45 | + opts (drop-while not-opt? xs)] |
| 46 | + (loop [ret [required] opts opts] |
| 47 | + (if-let [opt (first opts)] |
| 48 | + (recur (conj ret (conj (last ret) opt)) (drop 1 opts)) |
| 49 | + (seq ret)))))) |
| 50 | + |
40 | 51 | (defn get-var-info [^Node node]
|
41 | 52 | (when node
|
42 | 53 | (let [info (.getJSDocInfo node)]
|
|
50 | 61 | (.isConstructor info) (merge {:ctor qname})
|
51 | 62 | (.isInterface info) (merge {:iface qname})))
|
52 | 63 | (if (.hasReturnType info)
|
53 |
| - {:tag 'Function |
54 |
| - :ret-tag (get-tag (.getReturnType info)) |
55 |
| - :arglists (list (into [] (map symbol (.getParameterNames info))))}))) |
| 64 | + (let [arglist (into [] (map symbol (.getParameterNames info))) |
| 65 | + arglists (params->method-params arglist)] |
| 66 | + {:tag 'Function |
| 67 | + :fn-var true |
| 68 | + :ret-tag (get-tag (.getReturnType info)) |
| 69 | + :variadic? (boolean (some '#{var_args} arglist)) |
| 70 | + :max-fixed-arity (count (take-while #(not= 'var_args %) arglist)) |
| 71 | + :method-params arglists |
| 72 | + :arglists arglists})))) |
56 | 73 | {:file *source-file*
|
57 | 74 | :line (.getLineno node)}
|
58 | 75 | (when-let [doc (.getOriginalCommentString info)]
|
|
177 | 194 | (fn [m xs]
|
178 | 195 | (let [sym (last xs)]
|
179 | 196 | (cond-> m
|
180 |
| - (seq xs) (assoc sym (meta sym))))) |
| 197 | + (seq xs) (assoc sym (merge (meta sym) {:ns *goog-ns* :name sym}))))) |
181 | 198 | {} externs))
|
182 | 199 |
|
183 | 200 | (defn analyze-goog-file [f]
|
184 | 201 | (let [rsrc (io/resource f)
|
185 |
| - desc (js-deps/parse-js-ns (line-seq (io/reader rsrc)))] |
| 202 | + desc (js-deps/parse-js-ns (line-seq (io/reader rsrc))) |
| 203 | + ns (-> (:provides desc) first symbol)] |
186 | 204 | ;; TODO: figure out what to do about other provides
|
187 |
| - {:name (first (:provides desc)) |
188 |
| - :defs (parsed->defs |
189 |
| - (parse-externs |
190 |
| - (SourceFile/fromInputStream f (io/input-stream rsrc))))})) |
| 205 | + (binding [*goog-ns* ns] |
| 206 | + {:name ns |
| 207 | + :defs (parsed->defs |
| 208 | + (parse-externs |
| 209 | + (SourceFile/fromInputStream f (io/input-stream rsrc))))}))) |
191 | 210 |
|
192 | 211 | (comment
|
193 | 212 |
|
194 |
| - (analyze-goog-file "goog/string/string.js") |
| 213 | + (pprint (analyze-goog-file "goog/object/object.js")) |
| 214 | + |
| 215 | + (pprint (analyze-goog-file "goog/string/string.js")) |
195 | 216 |
|
196 | 217 | (require '[clojure.java.io :as io]
|
197 | 218 | '[cljs.closure :as closure]
|
|
0 commit comments