|
6 | 6 | [cljs.analyzer.api :as ana] |
7 | 7 | [cljs.closure] |
8 | 8 | [cljs.env] |
9 | | - [clojure.string :as str])) |
| 9 | + [clojure.string :as str] |
| 10 | + [codox.utils :as util])) |
10 | 11 |
|
11 | 12 | (defn- cljs-filename? [filename] |
12 | 13 | (or (.endsWith filename ".cljs") |
|
51 | 52 | (multimethod? opts) :multimethod |
52 | 53 | :else :var)) |
53 | 54 |
|
54 | | -(defn- read-var [file vars var] |
55 | | - (let [vt (var-type var)] |
| 55 | +(defn- read-var [source-path file vars var] |
| 56 | + (let [vt (var-type var) |
| 57 | + normalize (partial util/normalize-to-source-path source-path)] |
56 | 58 | (-> var |
57 | | - (select-keys [:name :line :arglists :doc :dynamic :added :deprecated :doc/format]) |
| 59 | + (select-keys [:name :file :line :arglists :doc :dynamic :added :deprecated :doc/format]) |
58 | 60 | (update-some :name (comp symbol name)) |
59 | 61 | (update-some :arglists remove-quote) |
60 | 62 | (update-some :doc correct-indent) |
61 | | - (assoc-some :file (if (= vt :macro) (:file var) (.getPath file)) |
62 | | - :type vt |
63 | | - :members (map (partial read-var file vars) |
64 | | - (protocol-methods var vars)))))) |
65 | | - |
66 | | -(defn- read-publics [state namespace file] |
67 | | - (let [vars (vals (ana/ns-publics state namespace))] |
| 63 | + (update-some :file normalize) |
| 64 | + (assoc-some :type vt |
| 65 | + :members (->> (protocol-methods var vars) |
| 66 | + (map (partial read-var source-path file vars)) |
| 67 | + (map util/remove-empties) |
| 68 | + (map #(dissoc % :file :line)) |
| 69 | + (sort-by :name))) |
| 70 | + util/remove-empties))) |
| 71 | + |
| 72 | +(defn- unreferenced-protocol-fn? |
| 73 | + "Tools like potemkin import-vars can create a new function in one namespace point to an existing function within a protocol. |
| 74 | + In these cases, we want to include the new function." |
| 75 | + [source-path actual-file vars] |
| 76 | + (let [meta-file (util/normalize-to-source-path source-path (:file vars)) |
| 77 | + actual-file (util/normalize-to-source-path source-path (str actual-file))] |
| 78 | + (and (:protocol vars) (= meta-file actual-file)))) |
| 79 | + |
| 80 | +(defn- read-publics [state namespace source-path file] |
| 81 | + (let [vars (vals (ana/ns-publics state namespace)) |
| 82 | + unreferenced-protocol? (partial unreferenced-protocol-fn? source-path file)] |
68 | 83 | (->> vars |
69 | | - (remove :protocol) |
70 | 84 | (remove :anonymous) |
| 85 | + (remove unreferenced-protocol?) |
71 | 86 | (remove no-doc?) |
72 | | - (map (partial read-var file vars)) |
| 87 | + (map (partial read-var source-path file vars)) |
73 | 88 | (sort-by (comp str/lower-case :name))))) |
74 | 89 |
|
75 | 90 | (defn- analyze-file [file] |
|
80 | 95 | (ana/analyze-file state file opts)) |
81 | 96 | state)) |
82 | 97 |
|
83 | | -(defn- read-file [path file exception-handler] |
| 98 | +(defn- read-file [source-path file exception-handler] |
84 | 99 | (try |
85 | | - (let [source (io/file path file) |
| 100 | + |
| 101 | + (let [source (io/file source-path file) |
86 | 102 | ns-name (:ns (ana/parse-ns source)) |
87 | 103 | state (analyze-file source)] |
88 | 104 | {ns-name |
89 | 105 | (-> (ana/find-ns state ns-name) |
90 | 106 | (select-keys [:name :doc]) |
91 | 107 | (update-some :doc correct-indent) |
92 | 108 | (merge (-> ns-name meta (select-keys [:no-doc]))) |
93 | | - (assoc :publics (read-publics state ns-name file)))}) |
| 109 | + (util/remove-empties) |
| 110 | + (assoc :publics (read-publics state ns-name source-path file)))}) |
94 | 111 | (catch Exception e |
95 | 112 | (exception-handler e file)))) |
96 | 113 |
|
|
129 | 146 | ([paths {:keys [exception-handler] |
130 | 147 | :or {exception-handler default-exception-handler}}] |
131 | 148 | (mapcat (fn [path] |
132 | | - (let [path (io/file path) |
| 149 | + (let [path (io/file (util/canonical-path path)) |
133 | 150 | file-reader #(read-file path % exception-handler)] |
134 | 151 | (->> (find-files path) |
135 | 152 | (map file-reader) |
|
0 commit comments