reader-conditional?

added
1.7

ns
clojure.core

type
function

(reader-conditional? value)

Return true if the value is the data representation of a reader conditional

                (reader-conditional? (read-string {:read-cond :preserve} "#?(:clj (Math/exp 1))"))
;;=> true
(reader-conditional? (reader-conditional '(:clj (Math/exp 1)) false))
;;=> true

(reader-conditional? "#?(:clj (Math/exp 1))")
;;=> false
(reader-conditional? '#?(:clj (Math/exp 1)))
;;=> false
            
                ;;;; Let's say we have the source code for a Clojure program:

(def source-code
  "(defn str-to [type s]
     (case type
       :int #?(:clj (Integer/parseInt s) :cljs (js/parseInt s))
       #?@(:clj [:long (Long/parseLong s)])
       :float #?(:clj (Float/parseFloat s) :cljs (js/parseFloat s))
       #?@(:clj [:double (Double/parseDouble s)])))")

;;;; Here's a function that finds all the reader conditionals
;;;; in a given source code which contain a specific platform tag:

(defn find-reader-conditionals [code tag]
  (->> code
    (read-string {:read-cond :preserve}) ;; read into Clojure data structures
    (tree-seq seqable? identity)         ;; lazy seq of all forms
    (filter reader-conditional?)         ;; keep only reader conditionals
    (filter #(some #{tag} (:form %)))))  ;; keep only reader conds with tag

(pprint (find-reader-conditionals source-code :clj))
;;=> (#?(:clj (Integer/parseInt s) :cljs (js/parseInt s))
;;    #?@(:clj [:long (Long/parseLong s)])
;;    #?(:clj (Float/parseFloat s) :cljs (js/parseFloat s))
;;    #?@(:clj [:double (Double/parseDouble s)]))

(pprint (find-reader-conditionals source-code :cljs))
;;=> (#?(:clj (Integer/parseInt s) :cljs (js/parseInt s))
;;    #?(:clj (Float/parseFloat s) :cljs (js/parseFloat s)))