0.pre7.38:
[sbcl.git] / src / pcl / combin.lisp
index e61f22f..a28a1e4 100644 (file)
@@ -22,9 +22,6 @@
 ;;;; specification.
 
 (in-package "SB-PCL")
-
-(sb-int:file-comment
-  "$Header$")
 \f
 (defun get-method-function (method &optional method-alist wrappers)
   (let ((fn (cadr (assoc method method-alist))))
@@ -78,7 +75,7 @@
                  (eq (car method) ':early-method)
                  (method-p method))
              (if method-alist-p
-                 't
+                 t
                  (multiple-value-bind (mf fmf)
                      (if (listp method)
                          (early-method-function method)
                                   method-alist-p wrappers-p)))
                          (cdr form))
                   'fast-method-call
-                  't)
+                  t)
           (fast-method-call
            '.fast-call-method-list.)
           (t
                                         method-alist-p wrappers-p)))
                                (cdr form))
                         'fast-method-call
-                        't)))
+                        t)))
           (values `(dolist (emf ,gensym nil)
                      ,(make-emf-call metatypes applyp 'emf type))
                   (list gensym))))
     (let* ((*rebound-effective-method-gensyms*
            *global-effective-method-gensyms*)
           (name (if (early-gf-p generic-function)
-                    (early-gf-name generic-function)
+                    (!early-gf-name generic-function)
                     (generic-function-name generic-function)))
           (arg-info (cons nreq applyp))
           (effective-method-lambda (expand-effective-method-function
        (primary ())
        (after ())
        (around ()))
-    (dolist (m applicable-methods)
-      (let ((qualifiers (if (listp m)
-                           (early-method-qualifiers m)
-                           (method-qualifiers m))))
-       (cond ((member ':before qualifiers)  (push m before))
-             ((member ':after  qualifiers)  (push m after))
-             ((member ':around  qualifiers) (push m around))
-             (t
-              (push m primary)))))
+    (flet ((lose (method why)
+             (invalid-method-error
+              method
+              "The method ~S ~A.~%~
+               Standard method combination requires all methods to have one~%~
+               of the single qualifiers :AROUND, :BEFORE and :AFTER or to~%~
+               have no qualifier at all."
+              method why)))
+      (dolist (m applicable-methods)
+        (let ((qualifiers (if (listp m)
+                            (early-method-qualifiers m)
+                            (method-qualifiers m))))
+          (cond
+            ((null qualifiers) (push m primary))
+            ((cdr qualifiers)
+              (lose m "has more than one qualifier"))
+            ((eq (car qualifiers) :around)
+              (push m around))
+            ((eq (car qualifiers) :before)
+              (push m before))
+            ((eq (car qualifiers) :after)
+              (push m after))
+            (t
+              (lose m "has an illegal qualifier"))))))
     (setq before  (reverse before)
          after   (reverse after)
          primary (reverse primary)
                                  (make-method ,main-effective-method)))
                 main-effective-method))))))
 \f
-;;;; the STANDARD method combination type. This is coded by hand (rather than
-;;;; with define-method-combination) for bootstrapping and efficiency reasons.
-;;;; Note that the definition of the find-method-combination-method appears in
-;;;; the file defcombin.lisp. This is because EQL methods can't appear in the
+;;;; the STANDARD method combination type. This is coded by hand
+;;;; (rather than with DEFINE-METHOD-COMBINATION) for bootstrapping
+;;;; and efficiency reasons. Note that the definition of the
+;;;; FIND-METHOD-COMBINATION-METHOD appears in the file
+;;;; defcombin.lisp. This is because EQL methods can't appear in the
 ;;;; bootstrap.
 ;;;;
-;;;; The defclass for the METHOD-COMBINATION and STANDARD-METHOD-COMBINATION
-;;;; classes has to appear here for this reason. This code must conform to
-;;;; the code in the file defcombin.lisp, look there for more details.
+;;;; The DEFCLASS for the METHOD-COMBINATION and
+;;;; STANDARD-METHOD-COMBINATION classes has to appear here for this
+;;;; reason. This code must conform to the code in the file
+;;;; defcombin.lisp, look there for more details.
 
 (defun compute-effective-method (generic-function combin applicable-methods)
   (standard-compute-effective-method generic-function
                                     combin
                                     applicable-methods))
 
-(defvar *invalid-method-error*
-       #'(lambda (&rest args)
-           (declare (ignore args))
-           (error
-             "INVALID-METHOD-ERROR was called outside the dynamic scope~%~
-              of a method combination function (inside the body of~%~
-              DEFINE-METHOD-COMBINATION or a method on the generic~%~
-              function COMPUTE-EFFECTIVE-METHOD).")))
-
-(defvar *method-combination-error*
-       #'(lambda (&rest args)
-           (declare (ignore args))
-           (error
-             "METHOD-COMBINATION-ERROR was called outside the dynamic scope~%~
-              of a method combination function (inside the body of~%~
-              DEFINE-METHOD-COMBINATION or a method on the generic~%~
-              function COMPUTE-EFFECTIVE-METHOD).")))
-
-;(defmethod compute-effective-method :around   ;issue with magic
-;         ((generic-function generic-function)     ;generic functions
-;          (method-combination method-combination)
-;          applicable-methods)
-;  (declare (ignore applicable-methods))
-;  (flet ((real-invalid-method-error (method format-string &rest args)
-;         (declare (ignore method))
-;         (apply #'error format-string args))
-;       (real-method-combination-error (format-string &rest args)
-;         (apply #'error format-string args)))
-;    (let ((*invalid-method-error* #'real-invalid-method-error)
-;        (*method-combination-error* #'real-method-combination-error))
-;      (call-next-method))))
-
-(defun invalid-method-error (&rest args)
-  (declare (arglist method format-string &rest format-arguments))
-  (apply *invalid-method-error* args))
-
-(defun method-combination-error (&rest args)
-  (declare (arglist format-string &rest format-arguments))
-  (apply *method-combination-error* args))
+(defun invalid-method-error (method format-control &rest format-arguments)
+  (error "~@<invalid method error for ~2I~_~S ~I~_method: ~2I~_~?~:>"
+        method
+        format-control
+        format-arguments))
 
-;This definition now appears in defcombin.lisp.
-;
-;(defmethod find-method-combination ((generic-function generic-function)
-;                                   (type (eql 'standard))
-;                                   options)
-;  (when options
-;    (method-combination-error
-;      "The method combination type STANDARD accepts no options."))
-;  *standard-method-combination*)
+(defun method-combination-error (format-control &rest format-arguments)
+  (error "~@<method combination error in CLOS dispatch: ~2I~_~?~:>"
+        format-control
+        format-arguments))