sod-message class
sod-message-class generic
sod-message-name generic
+ sod-message-readonly-p generic
sod-message-type generic
sod-method class
sod-method-body generic
sod-message sod-class t
sod-message-name
sod-message
+sod-message-readonly-p
+ sod-message
sod-message-receiver-type
sod-message sod-class
sod-message-type
\&key :location}}
\end{describe*}
-\begin{describe}{cls}{sod-message () \&key :name :location :class :type}
+\begin{describe}{cls}
+ {sod-message () \&key :name :location :readonly :class :type}
\end{describe}
\begin{describe*}
{\dhead{gf}{sod-message-name @<message> @> @<string>}
\dhead{meth}{sod-message}
{file-location (@<message> sod-message) @> @<floc>}
+ \dhead{gf}{sod-message-readonly-p @<message> @> @<generalized-boolean>}
\dhead{gf}{sod-message-class @<message> @> @<class>}
\dhead{gf}{sod-message-type @<message> @> @<c-type>}}
\end{describe*}
\begin{description}
\item[@|message_class|] A symbol naming the Lisp class to use to represent
the message.
+\item[@|readonly|] A boolean indicating whether the message guarantees not to
+ modify its receiver. If this is true, the receiver will be declared
+ @"const".
\item[@|combination|] A keyword naming the aggregating method combination to
use.
\item[@|most_specific|] A keyword, either @`first' or @`last', according to
(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)
;;;--------------------------------------------------------------------------
;;; Messages and methods.
-(export '(sod-message sod-message-name sod-message-class sod-message-type))
+(export '(sod-message sod-message-name sod-message-readonly-p
+ sod-message-class sod-message-type))
(defclass sod-message ()
((name :initarg :name :type string :reader sod-message-name)
(location :initarg :location :initform (file-location nil)
:type file-location :reader file-location)
+ (readonlyp :initarg :readonly :initform nil :type t
+ :reader sod-message-readonly-p)
(%class :initarg :class :type sod-class :reader sod-message-class)
(%type :initarg :type :type c-function-type :reader sod-message-type))
(:documentation
* The `location' states where in the user's source the slot was defined.
It gets used in error messages.
+ * The `readonly' flag indicates whether the message receiver can modify
+ itself in response to this message. If set, the receiver will be
+ declared `const'.
+
* The `class' states which class defined the message.
* The `type' is a function type describing the message's arguments and
(defmethod sod-message-receiver-type ((message sod-message)
(class sod-class))
- (c-type (* (class class))))
+ (c-type (* (class class
+ (and (sod-message-readonly-p message) :const)))))
(export 'simple-message)
(defclass simple-message (basic-message)
;; Effective method function details.
(emf-name (effective-method-function-name method))
- (ilayout-type (c-type (* (struct (ilayout-struct-tag class)))))
+ (ilayout-type (c-type (* (struct (ilayout-struct-tag class)
+ (and (sod-message-readonly-p
+ message)
+ :const)))))
(emf-type (c-type (fun (lisp return-type)
("sod__obj" (lisp ilayout-type))
. entry-args))))
(:documentation
"Return the type of the `me' argument in a MESSAGE received by CLASS.
- Typically this will just be `CLASS *'."))
+ Typically this will just be `CLASS *' or `const CLASS *'."))
(export 'sod-message-applicable-methods)
(defgeneric sod-message-applicable-methods (message class)