Skip to content

Commit

Permalink
Fix info lookups from namespaces that don't yet exist
Browse files Browse the repository at this point in the history
Currently when doing a `var-info` from a file before evaluating the `ns` form
always fails. The namespace object does not yet exist, and so none of the var
resolution strategies work.

However fully-qualified vars, namespace names, or built-ins (clojure.core
functions) could all be resolved, and it's frustrating that they aren't.

This adds a check to see if `(find-ns ns)` returns anything. If not then we are
initiating the lookup from a namespace that has not yet been defined, in which
case none of the lookup strategies will proceed, so we continue with doing the
lookup as if it had been initiated from `clojure.core`.
  • Loading branch information
plexus authored and bbatsov committed Sep 20, 2021
1 parent ca5fae9 commit 7d7f752
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 26 additions & 22 deletions src/orchard/info.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
Expand Down
16 changes: 16 additions & 0 deletions test/orchard/info_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 7d7f752

Please sign in to comment.