Skip to content

Commit 58d2e8c

Browse files
committed
Pull mvn javadoc html source for 3rd party deps
1 parent 95afe09 commit 58d2e8c

File tree

3 files changed

+58
-14
lines changed

3 files changed

+58
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
.cpcache
2+
.DS_Store

src/clojure/java/doc/api.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
(print-signatures (javadoc-data-fn s param-tags)))
3131

3232
(defmacro sigs
33-
"print method signatures in param tags form"
33+
"print method signatures in qualified method / param tags form
34+
Examples:
35+
(sigs String/valueOf) ; Print all valueOf signatures"
3436
[class-or-method]
3537
`(sigs-fn ~(str class-or-method) '~(:param-tags (meta class-or-method))))

src/clojure/java/doc/impl.clj

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
(ns clojure.java.doc.impl
22
(:require
3-
[clojure.string :as str])
3+
[clojure.string :as str]
4+
[clojure.tools.deps :as deps])
45
(:import [com.vladsch.flexmark.html2md.converter FlexmarkHtmlConverter]
5-
[org.jsoup Jsoup]))
6+
[org.jsoup Jsoup]
7+
[java.util.jar JarFile]))
68

79
(set! *warn-on-reflection* true)
810

@@ -15,15 +17,54 @@
1517
{:current-version version-str
1618
:minimum-version min-version})))))
1719

18-
(defn- javadoc-url [^String classname]
20+
(defn- find-jar-coords [jar-url-str]
21+
(let [libs (:libs (deps/create-basis {:aliases []}))]
22+
(first (for [[lib-sym lib-info] libs
23+
path (:paths lib-info)
24+
:when (str/includes? jar-url-str path)]
25+
{:protocol :jar
26+
:lib lib-sym
27+
:version (select-keys lib-info [:mvn/version])}))))
28+
29+
(defn- find-javadoc-coords [^Class c]
30+
(let [class-name (.getName c)
31+
url (.getResource c (str (.getSimpleName c) ".class"))]
32+
(merge
33+
{:class-name class-name}
34+
(case (.getProtocol url)
35+
"jar" (find-jar-coords (.toString url))
36+
"jrt" {:protocol :jrt :lib 'java/java}
37+
"file" nil))))
38+
39+
(defn- download-javadoc-jar [{:keys [lib version]}]
40+
(let [javadoc-lib (symbol (str lib "$javadoc"))
41+
deps-map {:deps {javadoc-lib version} :mvn/repos (:mvn/repos (deps/root-deps))}
42+
result (deps/resolve-deps deps-map {})]
43+
(first (:paths (get result javadoc-lib)))))
44+
45+
(defn- extract-html-from-jar [jar-path class-name]
46+
(with-open [jar (JarFile. ^String jar-path)]
47+
(if-let [entry (.getJarEntry jar (str (str/replace class-name "." "/") ".html"))]
48+
(slurp (.getInputStream jar entry))
49+
(throw (ex-info (str "Could not find HTML for class in javadoc jar: " class-name)
50+
{:class-name class-name :jar-path jar-path})))))
51+
52+
(defn- javadoc-url [^String classname ^Class klass]
1953
(let [java-version (System/getProperty "java.specification.version")
20-
_ (check-java-version java-version)
21-
classname (str/replace classname #"\$.*" "")
22-
klass (Class/forName classname)
2354
module-name (.getName (.getModule klass))
2455
url-path (.replace classname \. \/)]
56+
(check-java-version java-version)
2557
(str "https://docs.oracle.com/en/java/javase/" java-version "/docs/api/" module-name "/" url-path ".html")))
2658

59+
(defn- get-javadoc-html [^String classname]
60+
(let [classname (str/replace classname #"\$.*" "")
61+
klass (Class/forName classname)
62+
coords (find-javadoc-coords klass)]
63+
(case (:protocol coords)
64+
:jar (extract-html-from-jar (download-javadoc-jar coords) classname)
65+
:jrt (slurp (javadoc-url classname klass))
66+
(throw (ex-info (str "No javadoc available for local class: " classname) {:class-name classname})))))
67+
2768
(defn- html-to-md [^String html]
2869
(.convert ^FlexmarkHtmlConverter (.build (FlexmarkHtmlConverter/builder)) html))
2970

@@ -130,9 +171,10 @@
130171
[s param-tags]
131172
(let [[class-part method-part] (str/split s #"/\.?" 2)
132173
class-name (resolve-class-name class-part)
133-
doc (Jsoup/parse (slurp (javadoc-url class-name)))
134-
class-desc-section (.selectFirst doc "section.class-description")
135-
method-rows (.select doc "div.method-summary-table.col-second")
174+
html (get-javadoc-html class-name)
175+
doc (Jsoup/parse ^String html)
176+
class-desc-section (.selectFirst ^org.jsoup.nodes.Document doc "section.class-description")
177+
method-rows (.select ^org.jsoup.nodes.Document doc "div.method-summary-table.col-second")
136178
all-methods (vec (for [^org.jsoup.nodes.Element method-div method-rows]
137179
(let [desc-div ^org.jsoup.nodes.Element (.nextElementSibling method-div)
138180
signature (.text (.select method-div "code"))
@@ -141,10 +183,9 @@
141183
is-static? (and modifier-html (str/includes? modifier-html "static"))]
142184
{:signature signature
143185
:description (.text (.select desc-div ".block"))
144-
:static? is-static?
145-
:clojure-call (clojure-call-syntax class-part signature is-static?)})))
146-
class-html (.outerHtml class-desc-section)
147-
result {:classname class-name
186+
:static? is-static?
187+
:clojure-call (clojure-call-syntax class-part signature is-static?)})))
188+
class-html (.outerHtml ^org.jsoup.nodes.Element class-desc-section) result {:classname class-name
148189
:class-description-html class-html
149190
:class-description-md (html-to-md class-html)
150191
:methods all-methods}]

0 commit comments

Comments
 (0)