X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/675b48242d0f5c6f2f2563003a1d2fd87e06522c..f458e64e36509fa8c204f1dbcafff1d3dc059619:/src/method-impl.lisp diff --git a/src/method-impl.lisp b/src/method-impl.lisp index 630570b..6c751a4 100644 --- a/src/method-impl.lisp +++ b/src/method-impl.lisp @@ -249,28 +249,45 @@ ;;;-------------------------------------------------------------------------- ;;; Effective method classes. -(defmethod method-keyword-argument-lists - ((method effective-method) direct-methods) - (with-slots (message) method - (and (keyword-message-p message) - (mapcar (lambda (m) - (let ((type (sod-method-type m))) - (cons (c-function-keywords type) - (format nil "method for ~A on ~A (at ~A)" - message - (sod-method-class m) - (file-location m))))) - direct-methods)))) +(defmethod sod-message-keyword-argument-lists + ((message sod-message) (class sod-class) direct-methods state) + (and (keyword-message-p message) + (cons (cons (lambda (arg) + (let ((class (sod-message-class message))) + (info-with-location + message "Type `~A' declared in message ~ + definition in `~A' (here)" + (argument-type arg) class) + (report-inheritance-path state class))) + (c-function-keywords (sod-message-type message))) + (mapcar (lambda (method) + (cons (lambda (arg) + (let ((class (sod-method-class method))) + (info-with-location + method "Type `~A' declared in ~A direct ~ + method of `~A' (defined here)" + (argument-type arg) + (sod-method-description method) class) + (report-inheritance-path state class))) + (c-function-keywords (sod-method-type method)))) + direct-methods)))) + +(defmethod sod-message-check-methods + ((message sod-message) (class sod-class) direct-methods) + (compute-effective-method-keyword-arguments message class direct-methods)) (defmethod shared-initialize :after ((method effective-method) slot-names &key direct-methods) (declare (ignore slot-names)) - ;; Set the keyword argument list. - (with-slots (message keywords) method + ;; Set the keyword argument list. Blame the class as a whole for mismatch + ;; errors, because they're fundamentally a non-local problem about the + ;; class construction. + (with-slots ((class %class) message keywords) method (setf keywords - (merge-keyword-lists (method-keyword-argument-lists - method direct-methods))))) + (compute-effective-method-keyword-arguments message + class + direct-methods)))) (export '(basic-effective-method effective-method-around-methods effective-method-before-methods @@ -666,7 +683,8 @@ (codegen-push codegen) (ensure-var codegen "sod__obj" ilayout-type (make-convert-to-ilayout-inst class - head "me")))) + head "me")) + (deliver-call codegen :void "SOD__IGNORE" "sod__obj"))) (finish-entry (tail) (let* ((head (sod-class-chain-head tail)) (role (if parm-n :valist nil)) @@ -797,6 +815,14 @@ (*keyword-struct-disposition* :local)) (ensure-var codegen *sod-keywords* (c-type (struct tag))) (make-keyword-parser-function codegen method tag set keywords) + (emit-insts codegen + (mapcar (lambda (keyword) + (make-set-inst + (format nil "~A.~A__suppliedp" + *sod-keywords* + (argument-name keyword)) + 0)) + keywords)) (parse-keywords (lambda () (call :void name kw-addr ap-addr *null-pointer* 0)))