# HG changeset patch # User Steve Losh # Date 1597984466 14400 # Node ID 7fbb6f4abee83746c5baa79564a79408dd3a034d # Parent 6c1bac83e3c9047e27422d84568d698ce267036f Fix `Undefined function (SETF CCL:SLOT-DEFINITION-INITARGS)` in CCL The MOP calls this an "accessor" so I feel like I shouldn't need to do this, but CCL only defines this function as a reader. Instead of `setf`ing it, we can wrap `make-instance` and hack the initargs we pass to `call-next-method`. diff -r 6c1bac83e3c9 -r 7fbb6f4abee8 .TODO.done --- a/.TODO.done Thu Aug 20 23:21:01 2020 -0400 +++ b/.TODO.done Fri Aug 21 00:34:26 2020 -0400 @@ -1,6 +1,8 @@ Add read/print disabling mechanism | id:1268bf0b10c13aec23aafbd8f5e236db1e485fa5 Optimize discarding | id:93105ef9d21d33bfb10c67fcac36bc60434d3fb4 +Add after-read and before-print functions | id:9f982ca45b68d644159e0c64f0dc1b185f72a2f8 Add opaque-json type | id:a1a380eb9782d088693dfb75402b99c2b30cf039 Add size and depth limits | id:ab9b49ec993f1e46c34b9d627549f41cad80609d Add fuzz tests against other implementations | id:cd53968480f72453ee820d65a180efe6da0fef71 +Fix `Undefined function (SETF CCL:SLOT-DEFINITION-INITARGS)` in CCL | id:e834dd6749849e10669a643019337533e87f5cdd Add basic unit tests | id:ed372a368fce619ce8230043635de5258212f607 diff -r 6c1bac83e3c9 -r 7fbb6f4abee8 TODO --- a/TODO Thu Aug 20 23:21:01 2020 -0400 +++ b/TODO Fri Aug 21 00:34:26 2020 -0400 @@ -1,8 +1,6 @@ Fix :allow-print and :allow-read to set t when removing them during class redef. | id:21cce1bed829a138de33b33e3ad3219f7888be04 Clean up error hierarchy | id:3d3efa4af649474151661a9d294080ab24e22ff7 Add basic wrapper definition | id:861f048b3b69079dedf8779be1cb73c05e6fc732 -Add after-read and before-print functions | id:9f982ca45b68d644159e0c64f0dc1b185f72a2f8 Add extra key preservation | id:cfb63b37d87893083fc98477ec3d488fb909a984 Test reading explicit types, not just t. | id:d2def699c46f12c02d49c01c869fc9b927bda72d Add more MOP-based tests (including errors). | id:df727baeb41bad02c7d79b92f98c24c8a28ca772 -Fix `Undefined function (SETF CCL:SLOT-DEFINITION-INITARGS)` in CCL | id:e834dd6749849e10669a643019337533e87f5cdd diff -r 6c1bac83e3c9 -r 7fbb6f4abee8 src/mop.lisp --- a/src/mop.lisp Thu Aug 20 23:21:01 2020 -0400 +++ b/src/mop.lisp Fri Aug 21 00:34:26 2020 -0400 @@ -34,6 +34,20 @@ (before-print :initarg :json/before-print :accessor before-print :initform nil) (after-read :initarg :json/after-read :accessor after-read :initform nil))) +(defmethod make-instance ((class (eql (find-class 'json-effective-slot-definition))) &rest initargs) + ;; We need to wrap this to make sure that every JSON slot has at least one + ;; initarg, so we can use it when calling `make-instance` during reading. + ;; + ;; If none of the direct slots have an initarg, we'll gensym one. Otherwise + ;; we can use an existing one and not clutter things up. + (apply #'call-next-method class + (append + (when (null (getf initargs :initargs)) + (list :initargs + (list (gensym (string (getf initargs :name)))))) + initargs))) + + (defmethod c2mop:direct-slot-definition-class ((class json-class) &rest initargs) (if (getf initargs :json) (find-class 'json-direct-slot-definition) @@ -48,7 +62,6 @@ ;; like it does in direct-slot-definition-class. So we need another way to ;; know which class to use here. (or *effective-slot-definition-class* (call-next-method))) - (defmethod c2mop:compute-effective-slot-definition ((class json-class) name direct-slots) (if (not (some (lambda (dslot) (typep dslot 'json-direct-slot-definition)) @@ -56,22 +69,21 @@ (call-next-method) (let* ((*effective-slot-definition-class* (find-class 'json-effective-slot-definition)) (eslot (call-next-method)) - (dslot (first direct-slots)) ; todo be smarter about coalescing these - (initarg (gensym (format nil "json-initarg-~A" name)))) ; todo nicer name + (dslot (first direct-slots))) + ;; todo be smarter about coalescing this stuff (setf (json-name eslot) (if (slot-boundp dslot 'json-name) (json-name dslot) (funcall (slot-name-to-json-name class) name)) ; todo make this less shitty (json-class eslot) (if (slot-boundp dslot 'json-class) (canonicalize-class-designator (json-class dslot)) '(t)) - (json-initarg eslot) initarg ; todo nicer name + (json-initarg eslot) (first (c2mop:slot-definition-initargs eslot)) (after-read eslot) (if (slot-boundp dslot 'after-read) (after-read dslot) nil) (before-print eslot) (if (slot-boundp dslot 'before-print) (before-print dslot) nil)) - (push initarg (c2mop:slot-definition-initargs eslot)) eslot)))