[#83 #112] Add support for deftype (@isaksky)

This commit is contained in:
Isak Sky 2018-10-05 19:46:24 -06:00 committed by Peter Taoussanis
parent 192666c09e
commit 67dde8d7bd

View file

@ -13,7 +13,7 @@
[java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream
DataOutputStream Serializable ObjectOutputStream ObjectInputStream DataOutputStream Serializable ObjectOutputStream ObjectInputStream
DataOutput DataInput] DataOutput DataInput]
[java.lang.reflect Method] [java.lang.reflect Method Field Constructor]
[java.net URI] [java.net URI]
[java.util Date UUID] [java.util Date UUID]
[java.util.regex Pattern] [java.util.regex Pattern]
@ -21,7 +21,7 @@
APersistentMap APersistentVector APersistentSet APersistentMap APersistentVector APersistentSet
IPersistentMap ; IPersistentVector IPersistentSet IPersistentList IPersistentMap ; IPersistentVector IPersistentSet IPersistentList
PersistentQueue PersistentTreeMap PersistentTreeSet PersistentList PersistentQueue PersistentTreeMap PersistentTreeSet PersistentList
LazySeq IRecord ISeq])) LazySeq IRecord ISeq IType]))
(if (vector? enc/encore-version) (if (vector? enc/encore-version)
(enc/assert-min-encore-version [2 67 1]) (enc/assert-min-encore-version [2 67 1])
@ -106,7 +106,7 @@
49 :record-md 49 :record-md
80 :record-lg ; Used only for back-compatible thawing 80 :record-lg ; Used only for back-compatible thawing
81 :type ; TODO Implement? 81 :type
3 :nil 3 :nil
8 :true 8 :true
@ -905,6 +905,17 @@
(write-bytes-md out cname-ba))) (write-bytes-md out cname-ba)))
(-freeze-without-meta! (into {} x) out))) (-freeze-without-meta! (into {} x) out)))
(freezer IType
(let [aclass (class x)
cname (.getName aclass)]
(write-id out id-type)
(-freeze-without-meta! cname out)
(let [basis-method (.getMethod aclass "getBasis" nil)
basis (.invoke basis-method nil nil)]
(doseq [b basis]
(let [^Field cfield (.getField aclass (name b))]
(let [fvalue (.get cfield x)]
(-freeze-without-meta! fvalue out)))))))
(freezer Object (freezer Object
(when-debug (println (str "freeze-fallback: " (type x)))) (when-debug (println (str "freeze-fallback: " (type x))))
@ -1109,6 +1120,23 @@
:throwable e :throwable e
:nippy/unthawable {:class-name class-name :content content}})))) :nippy/unthawable {:class-name class-name :content content}}))))
(defn- read-type [in class-name]
(try
(let [aclass (clojure.lang.RT/classForName class-name)
basis-method (.getMethod aclass "getBasis" nil)
basis (.invoke basis-method nil nil)
cvalues (object-array (count basis))
ctors (.getConstructors aclass)
^Constructor ctor (aget ctors 0) ;; Is this safe?
]
(dotimes [i (count basis)]
(aset cvalues i (thaw-from-in! in)))
(.newInstance ctor (into-array Object cvalues)))
(catch Exception e
{:type :type
:throwable e
:nippy/unthawable {:class-name class-name}})))
(defn thaw-from-in! (defn thaw-from-in!
"Deserializes a frozen object from given DataInput to its original Clojure "Deserializes a frozen object from given DataInput to its original Clojure
data type. data type.
@ -1132,6 +1160,8 @@
id-record-md (read-record in (read-utf8 in (read-md-count in))) id-record-md (read-record in (read-utf8 in (read-md-count in)))
id-record-lg (read-record in (read-utf8 in (read-lg-count in))) id-record-lg (read-record in (read-utf8 in (read-lg-count in)))
id-type (read-type in (thaw-from-in! in))
id-nil nil id-nil nil
id-true true id-true true
id-false false id-false false
@ -1474,6 +1504,9 @@
;;;; Stress data ;;;; Stress data
(defrecord StressRecord [data]) (defrecord StressRecord [data])
(deftype StressType [data]
Object
(equals [a b] (= (.-data a) (.-data ^StressType b))))
(def stress-data "Reference data used for tests & benchmarks" (def stress-data "Reference data used for tests & benchmarks"
{:bytes (byte-array [(byte 1) (byte 2) (byte 3)]) {:bytes (byte-array [(byte 1) (byte 2) (byte 3)])
:nil nil :nil nil
@ -1533,6 +1566,7 @@
:date (java.util.Date.) :date (java.util.Date.)
:stress-record (StressRecord. "data") :stress-record (StressRecord. "data")
:stress-type (StressType. "data")
;; Serializable ;; Serializable
:throwable (Throwable. "Yolo") :throwable (Throwable. "Yolo")
@ -1548,7 +1582,7 @@
be benching against" be benching against"
(dissoc stress-data (dissoc stress-data
:bytes :throwable :exception :ex-info :queue :queue-empty :bytes :throwable :exception :ex-info :queue :queue-empty
:byte :stress-record :regex)) :byte :stress-record :stress-type :regex))
;;;; Tools ;;;; Tools