X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/e85df3ff84611b7c790f9ffb46dfca77e2a717c0..ced609b8c5cc865f25cf5cce91a3d7dc9c85bdee:/src/class-make-impl.lisp?ds=sidebyside diff --git a/src/class-make-impl.lisp b/src/class-make-impl.lisp index 8aacd40..ed6189f 100644 --- a/src/class-make-impl.lisp +++ b/src/class-make-impl.lisp @@ -28,24 +28,6 @@ (cl:in-package #:sod) ;;;-------------------------------------------------------------------------- ;;; Classes. -(defun maximum (items order what) - "Return a maximum item according to the non-strict partial ORDER." - (reduce (lambda (best this) - (cond ((funcall order best this) best) - ((funcall order this best) this) - (t (error "Unable to choose best ~A." what)))) - items)) - -(defmethod guess-metaclass ((class sod-class)) - "Default metaclass-guessing function for classes. - - Return the most specific metaclass of any of the CLASS's direct - superclasses." - (maximum (mapcar #'sod-class-metaclass - (sod-class-direct-superclasses class)) - #'sod-subclass-p - (format nil "metaclass for `~A'" class))) - (defmethod shared-initialize :after ((class sod-class) slot-names &key pset) "Specific behaviour for SOD class initialization. @@ -67,11 +49,11 @@ (default-slot-from-property (class 'nickname slot-names) (pset :nick :id) (string-downcase (slot-value class 'name))) - ;; If no metaclass, guess one in a (Lisp) class-specific way. + ;; Set the metaclass if the appropriate property has been provided; + ;; otherwise leave it unbound for now, and we'll sort out the mess during + ;; finalization. (default-slot-from-property (class 'metaclass slot-names) - (pset :metaclass :id meta (find-sod-class meta)) - (and (sod-class-direct-superclasses class) - (guess-metaclass class))) + (pset :metaclass :id meta (find-sod-class meta))) ;; If no chain-link, then start a new chain here. (default-slot-from-property (class 'chain-link slot-names) @@ -142,7 +124,7 @@ (defmethod make-sod-initializer-using-slot :slot slot :value-kind value-kind :value-form value-form - :location location + :location (file-location location) :pset pset)) (defmethod shared-initialize :after @@ -208,7 +190,7 @@ (defmethod make-sod-method-using-message :class class :type type :body body - :location location + :location (file-location location) :pset pset)) (defmethod sod-message-method-class @@ -239,15 +221,38 @@ (defmethod check-method-type ((method sod-method) (message sod-message) (type c-type)) (error "Methods must have function type, not ~A" type)) +(export 'check-method-return-type) +(defun check-method-return-type (method-type wanted-type) + "Signal an error unless METHOD-TYPE does not return the WANTED-TYPE." + (let ((method-returns (c-type-subtype method-type))) + (unless (c-type-equal-p method-returns wanted-type) + (error "Method return type ~A should be ~A" + method-returns wanted-type)))) + +(export 'check-method-return-type-against-message) +(defun check-method-return-type-against-message (method-type message-type) + "Signal an error unless METHOD-TYPE and MESSAGE-TYPE return the same type." + (let ((message-returns (c-type-subtype message-type)) + (method-returns (c-type-subtype method-type))) + (unless (c-type-equal-p message-returns method-returns) + (error "Method return type ~A doesn't match message ~A" + method-returns message-returns)))) + +(export 'check-method-argument-lists) +(defun check-method-argument-lists (method-type message-type) + "Signal an error unless METHOD-TYPE and MESSAGE-TYPE have matching argument + lists. + + This checks that the two types have matching lists of arguments." + (unless (argument-lists-compatible-p (c-function-arguments message-type) + (c-function-arguments method-type)) + (error "Method arguments ~A don't match message ~A" + method-type message-type))) + (defmethod check-method-type ((method sod-method) (message sod-message) (type c-function-type)) (with-slots ((msgtype %type)) message - (unless (c-type-equal-p (c-type-subtype msgtype) - (c-type-subtype type)) - (error "Method return type ~A doesn't match message ~A" - (c-type-subtype msgtype) (c-type-subtype type))) - (unless (argument-lists-compatible-p (c-function-arguments msgtype) - (c-function-arguments type)) - (error "Method arguments ~A don't match message ~A" type msgtype)))) + (check-method-return-type-against-message type msgtype) + (check-method-argument-lists type msgtype))) ;;;----- That's all, folks --------------------------------------------------