diff --git a/sci b/sci index 0bdd57d6..3b624621 160000 --- a/sci +++ b/sci @@ -1 +1 @@ -Subproject commit 0bdd57d66da35d7a9c7ea3b10666a6b4b786808a +Subproject commit 3b62462112bde39d166914d0e424075ed18195cf diff --git a/src/aaaa_this_has_to_be_first/because_patches.clj b/src/aaaa_this_has_to_be_first/because_patches.clj index e884315a..f13b10a4 100644 --- a/src/aaaa_this_has_to_be_first/because_patches.clj +++ b/src/aaaa_this_has_to_be_first/because_patches.clj @@ -1,3 +1,4 @@ (ns aaaa-this-has-to-be-first.because-patches ;; we need pprint loaded first, it patches pprint to not bloat the GraalVM binary - (:require [babashka.impl.pprint])) + (:require [babashka.impl.patches.datafy] + [babashka.impl.pprint])) diff --git a/src/babashka/impl/classes.clj b/src/babashka/impl/classes.clj index b8dd017a..01940c16 100644 --- a/src/babashka/impl/classes.clj +++ b/src/babashka/impl/classes.clj @@ -316,6 +316,10 @@ java.util.Random java.util.regex.Matcher java.util.regex.Pattern + java.util.ArrayDeque + java.util.ArrayList + java.util.Collections + java.util.Comparator java.util.Base64 java.util.Base64$Decoder java.util.Base64$Encoder @@ -323,6 +327,7 @@ java.util.Locale java.util.Map java.util.MissingResourceException + java.util.NoSuchElementException java.util.Optional java.util.Properties java.util.Set diff --git a/src/babashka/impl/datafy.clj b/src/babashka/impl/datafy.clj index b080bd61..d0c7a3e5 100644 --- a/src/babashka/impl/datafy.clj +++ b/src/babashka/impl/datafy.clj @@ -1,46 +1,10 @@ (ns babashka.impl.datafy {:no-doc true} (:refer-clojure :exclude [create-ns]) - (:require [babashka.impl.common :refer [ctx]] - [babashka.impl.protocols :as protocols] - [clojure.core.protocols :as p] - [clojure.datafy] ;; ensure datafy is loaded, we're going to override - ;; its clojure.lang.Namespace implementation for - ;; datafy - [clojure.reflect] - [sci.core :as sci :refer [copy-var]] - [sci.impl.namespaces :refer [sci-ns-name sci-ns-publics sci-ns-imports sci-ns-interns]] - [sci.impl.vars]) - (: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)))) + (:require + [babashka.impl.protocols :as protocols] + [sci.core :as sci :refer [copy-var]] + [sci.impl.vars])) (def datafy-ns (sci/create-ns 'clojure.datafy nil)) diff --git a/src/babashka/impl/patches/datafy.clj b/src/babashka/impl/patches/datafy.clj new file mode 100644 index 00000000..c0127599 --- /dev/null +++ b/src/babashka/impl/patches/datafy.clj @@ -0,0 +1,38 @@ +(ns babashka.impl.patches.datafy + (:require [babashka.impl.common :refer [ctx]] + [clojure.core.protocols :as p] + [clojure.datafy] + ;; ensure datafy is loaded, we're going to override its + ;; clojure.lang.Namespace implementation for datafy + [clojure.reflect] + [sci.impl.namespaces :refer [sci-ns-name sci-ns-publics sci-ns-imports sci-ns-interns]] + [sci.impl.vars]) + (:import [sci.impl.vars SciNamespace])) + +(defn- sortmap [m] + (into (sorted-map) m)) + +(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)))) diff --git a/src/babashka/impl/protocols.clj b/src/babashka/impl/protocols.clj index f5ef9325..6494a0d0 100644 --- a/src/babashka/impl/protocols.clj +++ b/src/babashka/impl/protocols.clj @@ -1,7 +1,13 @@ (ns babashka.impl.protocols - (:require [clojure.datafy :as d] + (:require [babashka.impl.protocols :as protocols] + [clojure.core.protocols :as p] + [clojure.datafy :as d] + ;; ensure datafy is loaded, we're going to override its + ;; clojure.lang.Namespace implementation for datafy + [clojure.reflect] [sci.core :as sci :refer [copy-var]] - [sci.impl.types :as types])) + [sci.impl.types :as types] + [sci.impl.vars])) ;;;; datafy @@ -26,13 +32,30 @@ ;; note: Clojure itself will handle checking metadata for impls (d/nav coll k v)) -;;;; sci namespace (def protocols-ns (sci/create-ns 'clojure.core.protocols nil)) (def protocols-namespace - {'Datafiable (sci/new-var 'clojure.core.protocols/Datafiable {:methods #{'datafy} - :ns protocols-ns} {:ns protocols-ns}) + {;; Datafiable + 'Datafiable (sci/new-var 'clojure.core.protocols/Datafiable {:methods #{'datafy} + :protocol p/Datafiable + :ns protocols-ns} + {:ns protocols-ns}) 'datafy (copy-var datafy protocols-ns) + + ;; Navigable 'Navigable (sci/new-var 'clojure.core.protocols/Navigable {:methods #{'nav} - :ns protocols-ns} {:ns protocols-ns}) - 'nav (copy-var nav protocols-ns)}) + :protocol p/Navigable + :ns protocols-ns} + {:ns protocols-ns}) + 'nav (copy-var nav protocols-ns) + + ;; IKVReduce only added for satisies? check for now. We can implement + ;; kv-reduce in the future, but this needs patching some functions like + ;; update-vals, etc. + 'IKVReduce (sci/new-var 'clojure.core.protocols/IKVReduce {:protocol p/IKVReduce + ;; :methods #{'kv-reduce} + :ns protocols-ns} + {:ns protocols-ns}) + ;; 'kv-reduce (copy-var kv-reduce protocols-ns) + } + ) diff --git a/test/babashka/main_test.clj b/test/babashka/main_test.clj index 26ef871f..63d98a06 100644 --- a/test/babashka/main_test.clj +++ b/test/babashka/main_test.clj @@ -792,6 +792,11 @@ true"))) (deftest InetAddress-test (is (= "192.168.2.2" (bb nil "(-> (java.net.InetAddress/getByName \"192.168.2.2\") (.getHostAddress))")))) +(deftest satisfies-protocols-test + #_(is (true? (bb nil "(satisfies? clojure.core.protocols/Datafiable {})"))) + #_(is (true? (bb nil "(satisfies? clojure.core.protocols/Navigable {})"))) + (is (true? (bb nil "(satisfies? clojure.core.protocols/IKVReduce {})")))) + ;;;; Scratch (comment