Search code examples
clojure

Clojure code to analyze clojure code


I'd like to analyze a file of foreign clojure code. I'm currently using clojure.tools.reader to read all the forms:

(require '[clojure.tools.reader :as reader])

(defn read-all-forms [f]
  (let [rdr (indexing-push-back-reader (slurp f))
        EOF (Object.)
        opts {:eof EOF}]
    (loop [ret []]
      (let [form (reader/read opts rdr)]
        (if (= EOF form)
          ret
          (recur (conj ret form)))))))

This generally works, except when it encounters a double-colon keyword that refers to an aliased ns. Example:

(ns foo
  (:require [foo.bar :as bar]))

::bar/baz

Fails with:

ExceptionInfo Invalid token: ::bar/baz

Is there a way to use clojure.tools.reader to read the file and resolve keywords like this? Am I supposed to somehow keep track of the *alias-map* myself?


Solution

  • tools.reader uses clojure.tools.reader/*alias-map* if it's bound, otherwise it uses (ns-aliases *ns*) to resolve aliases. So if you have auto-resolved keywords in your file, you will need to use one of those approaches to allow auto-resolved aliases to be resolved.