diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ebf1ed1..4b6db737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ * `orchard.namespace` functionality is now parallelized when possible. +### Bugs Fixed + +* [#123](https://github.com/clojure-emacs/orchard/pull/123): Fix info lookups from namespaces that don't yet exist + ## 0.7.1 (2021-04-18) ### Bugs Fixed diff --git a/src/orchard/info.clj b/src/orchard/info.clj index 3ce6d09e..e02dec39 100644 --- a/src/orchard/info.clj +++ b/src/orchard/info.clj @@ -63,30 +63,34 @@ (defn clj-meta {:added "0.5"} - [{:keys [dialect ns sym computed-ns unqualified-sym]}] + [{:keys [dialect ns sym computed-ns unqualified-sym] :as opts}] {:pre [(= dialect :clj)]} (let [ns (or ns computed-ns)] - (or - ;; it's a special (special-symbol?) - (m/special-sym-meta sym) - ;; it's a var - (some-> ns (m/resolve-var sym) (m/var-meta)) - ;; it's a Java constructor/static member symbol - (some-> ns (java/resolve-symbol sym)) - ;; it's an unqualified sym maybe referred - (some-> ns (m/resolve-var unqualified-sym) (m/var-meta)) - ;; it's a Java class/record type symbol - (some-> ns (java/resolve-type unqualified-sym)) - ;; it's an alias for another ns - (some-> ns (m/resolve-aliases) (get sym) (m/ns-meta)) - ;; We use :unqualified-sym *exclusively* here because because our :ns is - ;; too ambiguous. - ;; - ;; Observe the incorrect behavior (should return nil, there is a test): - ;; - ;; (info '{:ns clojure.core :sym non-existing}) ;;=> {:author "Rich Hickey" :ns clojure.core ...} - ;; - (some-> (find-ns unqualified-sym) (m/ns-meta))))) + (if-not (and ns (find-ns ns)) + ;; Lookups in files whose namespaces don't exist yet should still be able + ;; to resolve built-ins and fully-qualified syms + (recur (assoc opts :ns 'clojure.core)) + (or + ;; it's a special (special-symbol?) + (m/special-sym-meta sym) + ;; it's a var + (some-> ns (m/resolve-var sym) (m/var-meta)) + ;; it's a Java constructor/static member symbol + (some-> ns (java/resolve-symbol sym)) + ;; it's an unqualified sym maybe referred + (some-> ns (m/resolve-var unqualified-sym) (m/var-meta)) + ;; it's a Java class/record type symbol + (some-> ns (java/resolve-type unqualified-sym)) + ;; it's an alias for another ns + (some-> ns (m/resolve-aliases) (get sym) (m/ns-meta)) + ;; We use :unqualified-sym *exclusively* here because because our :ns is + ;; too ambiguous. + ;; + ;; Observe the incorrect behavior (should return nil, there is a test): + ;; + ;; (info '{:ns clojure.core :sym non-existing}) ;;=> {:author "Rich Hickey" :ns clojure.core ...} + ;; + (some-> (find-ns unqualified-sym) (m/ns-meta)))))) (defn cljs-meta {:added "0.5"} diff --git a/test/orchard/info_test.clj b/test/orchard/info_test.clj index c36b92c1..25e7d3a7 100644 --- a/test/orchard/info_test.clj +++ b/test/orchard/info_test.clj @@ -467,6 +467,22 @@ :returns int})) (is (re-find #"Returns the greater of two" (:doc i)))))) +(deftest info-undefined-namespace-test + (testing "Fully qualified sym can still be resolved" + (is (= '{:added "1.2" + :ns clojure.string + :name upper-case + :file "clojure/string.clj"} + (select-keys (info/info* {:ns 'gibberish :sym 'clojure.string/upper-case}) + [:added :ns :name :file])))) + (testing "clojure.core syms can still be resolved" + (is (= '{:added "1.0" + :ns clojure.core + :name merge + :file "clojure/core.clj"} + (select-keys (info/info* {:ns 'gibberish :sym 'merge}) + [:added :ns :name :file]))))) + (deftest javadoc-info-unit-test (testing "Get an HTTP URL for a Sun/Oracle Javadoc" (testing "Javadoc 1.7 format"