src/method-impl.lisp, etc.: Add a `readonly' message property.
[sod] / src / class-make-impl.lisp
index da6cd2c..1da8bac 100644 (file)
@@ -84,7 +84,7 @@
 ;;; Slots.
 
 (defmethod make-sod-slot
-    ((class sod-class) name type pset &optional location)
+    ((class sod-class) name type pset &key location)
   (with-default-error-location (location)
     (when (typep type 'c-function-type)
       (error "Slot declarations cannot have function type"))
@@ -99,8 +99,8 @@
       (with-slots (slots) class
        (setf slots (append slots (list slot))))
       (when initarg-name
-       (make-sod-slot-initarg-using-slot class initarg-name
-                                         slot pset location))
+       (make-sod-slot-initarg-using-slot class initarg-name slot pset
+                                         :location location))
       slot)))
 
 (defmethod shared-initialize :after ((slot sod-slot) slot-names &key pset)
 ;;; Slot initializers.
 
 (defmethod make-sod-instance-initializer
-    ((class sod-class) nick name value pset &optional location)
+    ((class sod-class) nick name value pset &key location inhibit-initargs)
   (with-default-error-location (location)
     (let* ((slot (find-instance-slot-by-name class nick name))
           (initarg-name (get-property pset :initarg :id))
       (with-slots (instance-initializers) class
        (unless (or initarg-name initializer)
          (error "Slot initializer declaration with no effect"))
-       (when initarg-name
-         (make-sod-slot-initarg-using-slot class initarg-name slot
-                                           pset location))
+       (when (and initarg-name (not inhibit-initargs))
+         (make-sod-slot-initarg-using-slot class initarg-name slot pset
+                                           :location location))
        (when initializer
          (setf instance-initializers
                (append instance-initializers (list initializer)))))
       initializer)))
 
 (defmethod make-sod-class-initializer
-    ((class sod-class) nick name value pset &optional location)
+    ((class sod-class) nick name value pset &key location)
   (with-default-error-location (location)
     (let* ((slot (find-class-slot-by-name class nick name))
           (initializer (make-sod-initializer-using-slot
   nil)
 
 (defmethod make-sod-user-initarg
-    ((class sod-class) name type pset &optional default location)
+    ((class sod-class) name type pset &key default location)
   (with-slots (initargs) class
     (push (make-instance (get-property pset :initarg-class :symbol
                                       'sod-user-initarg)
          initargs)))
 
 (defmethod make-sod-slot-initarg
-    ((class sod-class) name nick slot-name pset &optional location)
+    ((class sod-class) name nick slot-name pset &key location)
   (let ((slot (find-instance-slot-by-name class nick slot-name)))
-    (make-sod-slot-initarg-using-slot class name slot pset location)))
+    (make-sod-slot-initarg-using-slot class name slot pset
+                                     :location location)))
 
 (defmethod make-sod-slot-initarg-using-slot
-    ((class sod-class) name (slot sod-slot) pset &optional location)
+    ((class sod-class) name (slot sod-slot) pset &key location)
   (with-slots (initargs) class
     (with-slots ((type %type)) slot
-      (push (make-instance (get-property pset :initarg-class :symbol
-                                        'sod-slot-initarg)
-                          :location (file-location location)
-                          :class class :name name :type type :slot slot)
-           initargs))))
+      (setf initargs
+           (append initargs
+                   (cons (make-instance (get-property pset :initarg-class
+                                                      :symbol
+                                                      'sod-slot-initarg)
+                                        :location (file-location location)
+                                        :class class :name name
+                                        :type type :slot slot)
+                         nil))))))
 
 (defmethod sod-initarg-default ((initarg sod-initarg)) nil)
 
 ;;; Initialization and teardown fragments.
 
 (defmethod make-sod-class-initfrag
-    ((class sod-class) frag pset &optional location)
+    ((class sod-class) frag pset &key location)
   (declare (ignore pset location))
   (with-slots (initfrags) class
     (setf initfrags (append initfrags (list frag)))))
 
 (defmethod make-sod-class-tearfrag
-    ((class sod-class) frag pset &optional location)
+    ((class sod-class) frag pset &key location)
   (declare (ignore pset location))
   (with-slots (tearfrags) class
     (setf tearfrags (append tearfrags (list frag)))))
 ;;; Messages.
 
 (defmethod make-sod-message
-    ((class sod-class) name type pset &optional location)
+    ((class sod-class) name type pset &key location)
   (with-default-error-location (location)
     (let* ((msg-class (or (get-property pset :message-class :symbol)
                          (and (get-property pset :combination :keyword)
 
 (defmethod shared-initialize :after
     ((message sod-message) slot-names &key pset)
-  (declare (ignore slot-names pset))
   (with-slots ((type %type)) message
-    (check-message-type message type)))
+    (check-message-type message type))
+  (default-slot-from-property (message 'readonlyp slot-names)
+      (pset :readonly :boolean)
+    nil))
 
 (defmethod check-message-type ((message sod-message) (type c-function-type))
   nil)
 ;;; Methods.
 
 (defmethod make-sod-method
-    ((class sod-class) nick name type body pset &optional location)
+    ((class sod-class) nick name type body pset &key location)
   (with-default-error-location (location)
     (let* ((message (find-message-by-name class nick name))
           (method (make-sod-method-using-message message class