chiark / gitweb /
src/: Check that methods are compatible during class finalization.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 9 Jul 2018 11:53:52 +0000 (12:53 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 9 Jul 2018 12:09:58 +0000 (13:09 +0100)
This is the payoff from the previous refactoring.  Check, specifically,
that the keyword argument types among the applicable methods are
compatible.  Otherwise we only find out about this during effective-
method computation, which happens during output, and it's too late to
stop the presses.

doc/SYMBOLS
doc/layout.tex
src/class-finalize-impl.lisp
src/method-impl.lisp
src/method-proto.lisp

index 95604ae4dd388356feaa91d391d6ad778881a44c..63e0abc71a715b57b25e3bdb385923b1f3a94911 100644 (file)
@@ -546,6 +546,7 @@ method-proto.lisp
   simple-method-body                            generic
   sod-message-applicable-methods                generic
   sod-message-argument-tail                     generic
+  sod-message-check-methods                     generic
   sod-message-effective-method-class            generic
   sod-message-keyword-argument-lists            generic
   sod-method-description                        generic
@@ -1517,6 +1518,8 @@ sod-message-applicable-methods
   sod-message sod-class
 sod-message-argument-tail
   basic-message
+sod-message-check-methods
+  sod-message sod-class t
 sod-message-class
   sod-message
 sod-message-combination
index ca31a9c3d19e54d0f6fa7c7593934e259726c401..95753b124bd5408ac8e93f547db7daff68eb67cd 100644 (file)
       \nlret @<list>}
 \end{describe}
 
+\begin{describe}{gf}
+    {sod-message-check-methods @<message> @<class> @<direct-methods>}
+\end{describe}
+
 \begin{describe}{gf}
     {sod-message-effective-method-class @<message> @> @<class>}
 \end{describe}
index 10d2b2ffdebc2d5b472da8b083025b1c0e7b708f..2978bd453680457917d7290d8ba4211e6c5cbbf6 100644 (file)
@@ -516,6 +516,15 @@ (defmethod check-sod-class ((class sod-class))
                                 has metaclass `~A'"
                                super supermeta))))))
 
+  ;; Check that all of the messages we can be sent have coherent collections
+  ;; of applicable methods.  This can go wrong, for example, if we inherit
+  ;; methods with differently typed keyword arguments.
+  (finalization-error (:mismatched-applicable-methods)
+    (dolist (super (sod-class-precedence-list class))
+      (dolist (message (sod-class-messages super))
+       (let ((methods (sod-message-applicable-methods message class)))
+         (sod-message-check-methods message class methods)))))
+
   ;; Check that an initializer is available for every slot in the class's
   ;; metaclass.  Skip this and trust the caller if the metaclass isn't
   ;; finalized yet: in that case, we must be bootstrapping, and we must hope
index 91c22bb2aeebb84b79c2a20460a64a5d07d0d9db..6c751a4dff360cfa53d6b3f5d53e06bd369a2403 100644 (file)
@@ -272,6 +272,9 @@ (defmethod sod-message-keyword-argument-lists
                             (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)
index 129843150363a31ca3cee485e393cb2252c059a9..5687802bad3a19e53ee265c84ab30515e04927a0 100644 (file)
@@ -95,6 +95,15 @@ (defun compute-effective-method-keyword-arguments
                                                             direct-methods
                                                             state))))
 
+(export 'sod-message-check-methods)
+(defgeneric sod-message-check-methods (message class direct-methods)
+  (:documentation
+   "Check that the applicable methods for a MESSAGE are compatible.
+
+   Specifically, given the DIRECT-METHODS applicable for the message when
+   received by an instance of CLASS, signal errors if the methods don't
+   match the MESSAGE or each other."))
+
 (export 'sod-message-effective-method-class)
 (defgeneric sod-message-effective-method-class (message)
   (:documentation