Skip to content
Permalink
Browse files

Move more functionality from cider-nrepl to orchard's info namespace

  • Loading branch information
bbatsov committed May 19, 2018
1 parent 5f2c497 commit b7ceb98b3d0b1f1035f9586a127cd23b3d18ff5c
Showing with 133 additions and 1 deletion.
  1. +59 −0 src/orchard/info.clj
  2. +74 −1 test/orchard/info_test.clj
@@ -35,3 +35,62 @@
(defn info-java
[class member]
(java/member-info class member))

(defn- resource-full-path [relative-path]
(io/resource relative-path (class-loader)))

(defn resource-path
"If it's a resource, return a tuple of the relative path and the full resource path."
[x]
(or (if-let [full (resource-full-path x)]
[x full])
(if-let [[_ relative] (re-find #".*jar!/(.*)" x)]
(if-let [full (resource-full-path relative)]
[relative full]))
;; handles load-file on jar resources from a cider buffer
(if-let [[_ relative] (re-find #".*jar:(.*)" x)]
(if-let [full (resource-full-path relative)]
[relative full]))))

(defn file-path
"For a file path, return a URL to the file if it exists and does not
represent a form evaluated at the REPL."
[x]
(when (seq x)
(let [f (io/file x)]
(when (and (.exists f)
(not (-> f .getName (.startsWith "form-init"))))
(io/as-url f)))))

(defn file-info
[path]
(let [[resource-relative resource-full] (resource-path path)]
(merge {:file (or (file-path path) resource-full path)}
;; Classpath-relative path if possible
(if resource-relative
{:resource resource-relative}))))

(defn javadoc-info
"Resolve a relative javadoc path to a URL and return as a map. Prefer javadoc
resources on the classpath; then use online javadoc content for core API
classes. If no source is available, return the relative path as is."
[path]
{:javadoc
(or (resource-full-path path)
;; [bug#308] `*remote-javadocs*` is outdated WRT Java
;; 8, so we try our own thing first.
(when (re-find #"^(java|javax|org.omg|org.w3c.dom|org.xml.sax)/" path)
(format "http://docs.oracle.com/javase/%d/docs/api/%s"
u/java-api-version path))
;; If that didn't work, _then_ we fallback on `*remote-javadocs*`.
(some (let [classname (.replaceAll path "/" ".")]
(fn [[prefix url]]
(when (.startsWith classname prefix)
(str url path))))
@javadoc/*remote-javadocs*)
path)})

;; TODO: Seems those were hardcoded here accidentally - we should
;; probably provide a simple API to register remote JavaDocs.
(javadoc/add-remote-javadoc "com.amazonaws." "http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/")
(javadoc/add-remote-javadoc "org.apache.kafka." "https://kafka.apache.org/090/javadoc/index.html?")
@@ -1,7 +1,8 @@
(ns orchard.info-test
(:require [clojure.test :refer :all]
[clojure.repl :as repl]
[orchard.info :as info]))
[orchard.info :as info]
[orchard.misc :as misc]))

(deftest see-also-test
(is (not-empty (info/see-also 'clojure.core 'map))))
@@ -35,3 +36,75 @@

(deftest info-java-test
(is (info/info-java 'clojure.lang.Atom 'swap)))

(deftest javadoc-info-unit-test
(testing "Get an HTTP URL for a Sun/Oracle Javadoc"
(testing "Javadoc 1.7 format"
(let [reply (info/javadoc-info "java/lang/StringBuilder.html#capacity()")
url (:javadoc reply)
exp-suffix "/docs/api/java/lang/StringBuilder.html#capacity()"]
(is (.endsWith url exp-suffix))))

(testing "Javadoc 1.8 format"
(let [reply (info/javadoc-info "java/lang/StringBuilder.html#capacity--")
url (:javadoc reply)
exp-suffix "/docs/api/java/lang/StringBuilder.html#capacity--"]
(is (.endsWith url exp-suffix)))))

(testing "Get general URL for a clojure javadoc"
(let [reply (info/javadoc-info "clojure/java/io.clj")
url (:javadoc reply)
url-type (class url)
exp-type java.net.URL]
(is (= url-type exp-type))))

(testing "Get URL for commonly used Java libraries via the *remote-javadocs* mechanism"
(let [reply (info/javadoc-info "com/amazonaws/services/lambda/AWSLambdaClient.html#listFunctions()")
url (:javadoc reply)]
(is (= url "http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/lambda/AWSLambdaClient.html#listFunctions()"))))

(testing "Get fall through URL type for other Javadocs (external libs?)"
(let [reply (info/javadoc-info "http://some/other/url")
url (:javadoc reply)]
(is (= url "http://some/other/url")))))

(deftest javadoc-url-test
(if (= misc/java-api-version 7)
(testing "java 1.7"
(is (= "http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#charAt(int)"
(-> (info/info-java 'java.lang.StringBuilder 'charAt)
(get :javadoc))))))

(if (= misc/java-api-version 8)
(testing "java 1.8"
(is (= "http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html#charAt-int-"
(-> (info/info-java 'java.lang.StringBuilder 'charAt)
(get :javadoc))))))

(if (= misc/java-api-version 9)
(testing "java 9"
(is (= "http://docs.oracle.com/javase/9/docs/api/java/lang/StringBuilder.html#charAt-int-"
(-> (info/info-java 'java.lang.StringBuilder 'charAt)
(get :javadoc)))))))

;;; resource path test
(defn file
[x]
(:file (info/file-info x)))

(defn relative
[x]
(:resource (info/file-info x)))

(deftest resource-path-test
(is (= (class (file (subs (str (clojure.java.io/resource "clojure/core.clj")) 4)))
java.net.URL))
(is (= (class (file "clojure/core.clj"))
java.net.URL))
(is (= (class (file "clojure-1.7.0.jar:clojure/core.clj"))
java.net.URL))
(is (= (class (file "test/orchard/info_test.clj"))
java.net.URL))
(is (relative "clojure/core.clj"))
(is (nil? (relative "notclojure/core.clj")))
(is (nil? (info/resource-path "jar:file:fake.jar!/fake/file.clj"))))

0 comments on commit b7ceb98

Please sign in to comment.
You can’t perform that action at this time.