Fix make-array transforms.
[sbcl.git] / tests / mop-2.impure-cload.lisp
index 0f229a0..cc1042e 100644 (file)
@@ -6,7 +6,7 @@
 ;;;; While most of SBCL is derived from the CMU CL system, the test
 ;;;; files (like this one) were written from scratch after the fork
 ;;;; from CMU CL.
-;;;; 
+;;;;
 ;;;; This software is in the public domain and is provided with
 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
 ;;;; more information.
@@ -55,6 +55,9 @@
              (setf (cdr entry) new-value))
          new-value))
 
+  (defun dynamic-slot-names (instance)
+    (mapcar #'car (gethash instance table)))
+
    (defun dynamic-slot-boundp (instance slot-name)
       (let* ((alist (gethash instance table))
              (entry (assoc slot-name alist)))
@@ -66,7 +69,6 @@
         (unless (null entry)
           (setf (gethash instance table) (delete entry alist))))
       instance)
-
 )
 
 (defmethod allocate-instance ((class dynamic-slot-class) &key)
         (call-next-method))))
 
 (defmethod (setf slot-value-using-class) (new-value (class dynamic-slot-class)
-                                         instance slotd)
+                                          instance slotd)
   (let ((slot (find slotd (class-slots class))))
     (if (and slot (dynamic-slot-p slot))
-       (write-dynamic-slot-value new-value instance (slot-definition-name slotd))
-       (call-next-method))))
+        (write-dynamic-slot-value new-value instance (slot-definition-name slotd))
+        (call-next-method))))
 
 (defmethod slot-boundp-using-class ((class dynamic-slot-class)
-                                   instance slotd)
+                                    instance slotd)
   (let ((slot (find slotd (class-slots class))))
     (if (and slot (dynamic-slot-p slot))
         (dynamic-slot-boundp instance (slot-definition-name slotd))
         (call-next-method))))
 
 (defmethod slot-makunbound-using-class ((class dynamic-slot-class)
-                                       instance slotd)
+                                        instance slotd)
   (let ((slot (find slotd (class-slots class))))
     (if (and slot (dynamic-slot-p slot))
         (dynamic-slot-makunbound instance (slot-definition-name slotd))
 
 (defmethod (setf slot-value-using-class) (new-value
                                           (class dynamic-slot-subclass)
-                                         instance slotd)
+                                          instance slotd)
   (let ((slot (find slotd (class-slots class))))
     (if (and slot (dynamic-slot-p slot))
-       (write-dynamic-slot-value new-value instance (slot-definition-name slotd))
-       (call-next-method))))
+        (write-dynamic-slot-value new-value instance (slot-definition-name slotd))
+        (call-next-method))))
 
 (defmethod slot-boundp-using-class ((class dynamic-slot-subclass)
                                     instance slotd)
   (let ((slot (find slotd (class-slots class))))
     (if (and slot (dynamic-slot-p slot))
-       (dynamic-slot-boundp instance (slot-definition-name slotd))
-       (call-next-method))))
+        (dynamic-slot-boundp instance (slot-definition-name slotd))
+        (call-next-method))))
 
 (defclass test-class-3 (test-class-1)
   ((slot2 :initarg :slot2 :initform t :allocation :dynamic)
 (assert (not (slot-boundp *three* 'slot1)))
 (assert (eq (slot-value *three* 'slot2) t))
 (assert (= (slot-value *three* 'slot3) 3))
+
+(defmethod slot-missing ((class dynamic-slot-class) instance slot-name operation &optional v)
+  (declare (ignore v))
+  (list :slot-missing slot-name))
+
+;;; Test redefinition adding a dynamic slot
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform t :allocation :dynamic)
+   (slot3 :initarg :slot3)
+   (slot4 :initarg :slot4 :initform 42 :allocation :dynamic))
+  (:metaclass dynamic-slot-subclass))
+(assert (= 42 (slot-value *three* 'slot4)))
+
+;;; Test redefinition removing a dynamic slot
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform t :allocation :dynamic)
+   (slot3 :initarg :slot3))
+  (:metaclass dynamic-slot-subclass))
+(assert (equal (list :slot-missing 'slot4) (slot-value *three* 'slot4)))
+
+;;; Test redefinition making a dynamic slot local
+;;;
+;;; NOTE: seriously underspecified. We muddle somehow.
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform 'ok :allocation :instance)
+   (slot3 :initarg :slot3))
+  (:metaclass dynamic-slot-subclass))
+(let* ((slots (class-slots (find-class 'test-class-3)))
+       (slot (find 'slot2 slots :key #'slot-definition-name)))
+  (assert (eq :instance (slot-definition-allocation slot)))
+  (assert (eq 'ok (slot-value *three* 'slot2))))
+
+;;; Test redefinition making a local slot dynamic again
+;;;
+;;; NOTE: seriously underspecified. We muddle somehow.
+;;; This picks up the old value from the table, not the
+;;; new initform.
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform 'ok? :allocation :dynamic)
+   (slot3 :initarg :slot3))
+  (:metaclass dynamic-slot-subclass))
+(let* ((slots (class-slots (find-class 'test-class-3)))
+       (slot (find 'slot2 slots :key #'slot-definition-name)))
+  (assert (eq :dynamic (slot-definition-allocation slot)))
+  (assert (eq t (slot-value *three* 'slot2))))
+
+;;; Test redefinition making a dynamic slot local, with
+;;; UPDATE-INSTANCE-FOR-REDEFINED-CLASS unbinding the dynamic slot.
+;;; Then we make it dynamic again.
+;;;
+;;; NOTE: seriously underspecified. We muddle somehow.
+(defmethod update-instance-for-redefined-class :after ((obj test-class-3) add drop plist
+                                                       &rest inits)
+  (declare (ignore inits))
+  (let* ((class (class-of obj))
+         (slots (class-slots class)))
+    (dolist (name (dynamic-slot-names obj))
+      (let ((slotd (find name slots :key #'slot-definition-name)))
+        (unless (and slotd (eq :dynamic (slot-definition-allocation slotd)))
+          (dynamic-slot-makunbound obj name))))))
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform 'ok :allocation :instance)
+   (slot3 :initarg :slot3))
+  (:metaclass dynamic-slot-subclass))
+(let* ((slots (class-slots (find-class 'test-class-3)))
+       (slot (find 'slot2 slots :key #'slot-definition-name)))
+  (assert (eq :instance (slot-definition-allocation slot)))
+  (assert (eq 'ok (slot-value *three* 'slot2))))
+(defclass test-class-3 (test-class-1)
+  ((slot2 :initarg :slot2 :initform 'ok! :allocation :dynamic)
+   (slot3 :initarg :slot3))
+  (:metaclass dynamic-slot-subclass))
+(let* ((slots (class-slots (find-class 'test-class-3)))
+       (slot (find 'slot2 slots :key #'slot-definition-name)))
+  (assert (eq :dynamic (slot-definition-allocation slot)))
+  (assert (eq 'ok! (slot-value *three* 'slot2))))