|
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