diff --git a/src/babashka/impl/datafy.clj b/src/babashka/impl/datafy.clj new file mode 100644 index 00000000..e9644f4d --- /dev/null +++ b/src/babashka/impl/datafy.clj @@ -0,0 +1,46 @@ +(ns babashka.impl.datafy + {:no-doc true} + (:refer-clojure :exclude [create-ns]) + (:require [clojure.core.protocols :as p] + [clojure.datafy :as datafy] + [clojure.reflect] + [sci.core :refer [create-ns copy-var]] + [sci.impl.namespaces :refer [sci-ns-name sci-ns-publics sci-ns-imports sci-ns-interns]] + [sci.impl.vars] + [babashka.impl.common :refer [ctx]]) + (:import [sci.impl.vars SciNamespace])) + +(defn- sortmap [m] + (into (sorted-map) m)) + +;; Overrides for what is defined in clojure.datafy +(extend-protocol p/Datafiable + clojure.lang.Namespace + (datafy [n] + ;; Override this with the default Object implementation. It bloats bb with 30mb and memory usage of GraalVM will peak! + #_(with-meta {:name (.getName n) + :publics (-> n ns-publics sortmap) + :imports (-> n ns-imports sortmap) + :interns (-> n ns-interns sortmap)} + (meta n)) + n) + java.lang.Class + (datafy [c] + ;; Statically use clojure.reflect instead of leaning on requiring-resolve + (let [{:keys [members] :as ret} (clojure.reflect/reflect c)] + (assoc ret :name (-> c .getName symbol) :members (->> members (group-by :name) sortmap))))) + +(extend-protocol p/Datafiable + SciNamespace + (datafy [n] + (with-meta {:name (sci-ns-name n) + :publics (->> n (sci-ns-publics @ctx) sortmap) + :imports (->> n (sci-ns-imports @ctx) sortmap) + :interns (->> n (sci-ns-interns @ctx) sortmap)} + (meta n)))) + +(def datafy-ns (create-ns 'clojure.data nil)) + +(def datafy-namespace + {'datafy (copy-var datafy/datafy datafy-ns) + 'nav (copy-var datafy/nav datafy-ns)}) diff --git a/src/babashka/main.clj b/src/babashka/main.clj index adec274d..d52cde29 100644 --- a/src/babashka/main.clj +++ b/src/babashka/main.clj @@ -16,6 +16,7 @@ [babashka.impl.common :as common] [babashka.impl.curl :refer [curl-namespace]] [babashka.impl.data :as data] + [babashka.impl.datafy :refer [datafy-namespace]] [babashka.impl.features :as features] [babashka.impl.pods :as pods] [babashka.impl.repl :as repl] @@ -368,7 +369,8 @@ If neither -e, -f, or --socket-repl are specified, then the first argument that 'babashka.curl curl-namespace 'babashka.pods pods/pods-namespace 'bencode.core bencode-namespace - 'clojure.java.browse browse-namespace} + 'clojure.java.browse browse-namespace + 'clojure.datafy datafy-namespace} features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace)) features/yaml? (assoc 'clj-yaml.core @(resolve 'babashka.impl.yaml/yaml-namespace) 'flatland.ordered.map @(resolve 'babashka.impl.ordered/ordered-map-ns))