aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-01-26 11:43:06 -0500
committerStefan Monnier2015-01-26 11:43:06 -0500
commita9a3d429e6e53e2be0b20e84f9809dba1d03e52d (patch)
tree7a524468a14403d10d8a2eace08b803110447b7a
parent4cdde9196fb4fafb00b0c51b908fd605274147bd (diff)
downloademacs-a9a3d429e6e53e2be0b20e84f9809dba1d03e52d.tar.gz
emacs-a9a3d429e6e53e2be0b20e84f9809dba1d03e52d.zip
* lisp/emacs-lisp/cl-generic.el (cl--generic-method): New struct.
(cl--generic): The method-table is now a (list-of cl--generic-method). (cl--generic-member-method): New function. (cl-generic-define-method): Use it. (cl--generic-build-combined-method, cl--generic-cache-miss): Adapt to new method-table. (cl--generic-no-next-method-function): Add `method' argument. (cl-generic-call-method): Adapt to new method representation. (cl--generic-cnm-sample, cl--generic-nnm-sample): Adjust. (cl-find-method, cl-method-qualifiers): New functions. (cl--generic-method-info): Adapt to new method representation. Return a string for the qualifiers. (cl--generic-describe): * lisp/emacs-lisp/eieio-opt.el (eieio-help-class): Adjust accordingly. (eieio-all-generic-functions, eieio-method-documentation): Adjust to new method representation. * lisp/emacs-lisp/eieio-compat.el (eieio--defmethod): Use cl-find-method. * test/automated/cl-generic-tests.el: Try and make sure cl-lib is not required at run-time.
-rw-r--r--lisp/ChangeLog22
-rw-r--r--lisp/emacs-lisp/cl-generic.el158
-rw-r--r--lisp/emacs-lisp/eieio-compat.el9
-rw-r--r--lisp/emacs-lisp/eieio-opt.el18
-rw-r--r--test/ChangeLog5
-rw-r--r--test/automated/cl-generic-tests.el4
6 files changed, 133 insertions, 83 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 0bdf4e275fa..ff352a25eea 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,27 @@
12015-01-26 Stefan Monnier <monnier@iro.umontreal.ca> 12015-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3
4 * emacs-lisp/cl-generic.el (cl--generic-method): New struct.
5 (cl--generic): The method-table is now a (list-of cl--generic-method).
6 (cl--generic-member-method): New function.
7 (cl-generic-define-method): Use it.
8 (cl--generic-build-combined-method, cl--generic-cache-miss):
9 Adapt to new method-table.
10 (cl--generic-no-next-method-function): Add `method' argument.
11 (cl-generic-call-method): Adapt to new method representation.
12 (cl--generic-cnm-sample, cl--generic-nnm-sample): Adjust.
13 (cl-find-method, cl-method-qualifiers): New functions.
14 (cl--generic-method-info): Adapt to new method representation.
15 Return a string for the qualifiers.
16 (cl--generic-describe):
17 * emacs-lisp/eieio-opt.el (eieio-help-class): Adjust accordingly.
18 (eieio-all-generic-functions, eieio-method-documentation):
19 Adjust to new method representation.
20
21 * emacs-lisp/eieio-compat.el (eieio--defmethod): Use cl-find-method.
22
232015-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
24
3 * emacs-lisp/cl-generic.el: Add a method-combination hook. 25 * emacs-lisp/cl-generic.el: Add a method-combination hook.
4 (cl-generic-method-combination-function): New var. 26 (cl-generic-method-combination-function): New var.
5 (cl--generic-lambda): Remove `with-cnm' arg. 27 (cl--generic-lambda): Remove `with-cnm' arg.
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 4245959c8a4..1bb70963a57 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -33,10 +33,6 @@
33;; code generation. Given how rarely method-combinations are used, 33;; code generation. Given how rarely method-combinations are used,
34;; I just provided a cl-generic-method-combination-function, which 34;; I just provided a cl-generic-method-combination-function, which
35;; people can use if they are really desperate for such functionality. 35;; people can use if they are really desperate for such functionality.
36;; - Method and generic function objects: CLOS defines methods as objects
37;; (same for generic functions), whereas we don't offer such an abstraction.
38;; - `no-next-method' should receive the "calling method" object, but since we
39;; don't have such a thing, we pass nil instead.
40;; - In defgeneric we don't support the options: 36;; - In defgeneric we don't support the options:
41;; declare, :method-combination, :generic-function-class, :method-class, 37;; declare, :method-combination, :generic-function-class, :method-class,
42;; :method. 38;; :method.
@@ -50,6 +46,8 @@
50;; eieio-core adds dispatch on: 46;; eieio-core adds dispatch on:
51;; - class of eieio objects 47;; - class of eieio objects
52;; - actual class argument, using the syntax (subclass <class>). 48;; - actual class argument, using the syntax (subclass <class>).
49;; - cl-generic-method-combination-function (i.s.o define-method-combination).
50;; - cl-generic-call-method (which replaces make-method and call-method).
53 51
54;; Efficiency considerations: overall, I've made an effort to make this fairly 52;; Efficiency considerations: overall, I've made an effort to make this fairly
55;; efficient for the expected case (e.g. no constant redefinition of methods). 53;; efficient for the expected case (e.g. no constant redefinition of methods).
@@ -103,6 +101,18 @@ that for all other (PRIORITY . TAGCODE) where PRIORITY ≤ N, then
103 "Function to get the list of types that a given \"tag\" matches. 101 "Function to get the list of types that a given \"tag\" matches.
104They should be sorted from most specific to least specific.") 102They should be sorted from most specific to least specific.")
105 103
104(cl-defstruct (cl--generic-method
105 (:constructor nil)
106 (:constructor cl--generic-method-make
107 (specializers qualifiers uses-cnm function))
108 (:predicate nil))
109 (specializers nil :read-only t :type list)
110 (qualifiers nil :read-only t :type (list-of atom))
111 ;; USES-CNM is a boolean indicating if FUNCTION expects an extra argument
112 ;; holding the next-method.
113 (uses-cnm nil :read-only t :type boolean)
114 (function nil :read-only t :type function))
115
106(cl-defstruct (cl--generic 116(cl-defstruct (cl--generic
107 (:constructor nil) 117 (:constructor nil)
108 (:constructor cl--generic-make 118 (:constructor cl--generic-make
@@ -116,12 +126,7 @@ They should be sorted from most specific to least specific.")
116 ;; decide in which order to sort them. 126 ;; decide in which order to sort them.
117 ;; The most important dispatch is last in the list (and the least is first). 127 ;; The most important dispatch is last in the list (and the least is first).
118 (dispatches nil :type (list-of (cons natnum (list-of tagcode)))) 128 (dispatches nil :type (list-of (cons natnum (list-of tagcode))))
119 ;; `method-table' is a list of 129 (method-table nil :type (list-of cl--generic-method)))
120 ;; ((SPECIALIZERS . QUALIFIERS) USES-CNM . FUNCTION), where
121 ;; USES-CNM is a boolean indicating if FUNCTION calls `cl-call-next-method'
122 ;; (and hence expects an extra argument holding the next-method).
123 (method-table nil :type (list-of (cons (cons (list-of type) (list-of atom))
124 (cons boolean function)))))
125 130
126(defmacro cl--generic (name) 131(defmacro cl--generic (name)
127 `(get ,name 'cl--generic)) 132 `(get ,name 'cl--generic))
@@ -344,15 +349,25 @@ which case this method will be invoked when the argument is `eql' to VAL.
344 (cl-generic-define-method ',name ',qualifiers ',args 349 (cl-generic-define-method ',name ',qualifiers ',args
345 ,uses-cnm ,fun))))) 350 ,uses-cnm ,fun)))))
346 351
352(defun cl--generic-member-method (specializers qualifiers methods)
353 (while
354 (and methods
355 (let ((m (car methods)))
356 (not (and (equal (cl--generic-method-specializers m) specializers)
357 (equal (cl--generic-method-qualifiers m) qualifiers)))))
358 (setq methods (cdr methods))
359 methods))
360
347;;;###autoload 361;;;###autoload
348(defun cl-generic-define-method (name qualifiers args uses-cnm function) 362(defun cl-generic-define-method (name qualifiers args uses-cnm function)
349 (let* ((generic (cl-generic-ensure-function name)) 363 (let* ((generic (cl-generic-ensure-function name))
350 (mandatory (cl--generic-mandatory-args args)) 364 (mandatory (cl--generic-mandatory-args args))
351 (specializers 365 (specializers
352 (mapcar (lambda (arg) (if (consp arg) (cadr arg) t)) mandatory)) 366 (mapcar (lambda (arg) (if (consp arg) (cadr arg) t)) mandatory))
353 (key (cons specializers qualifiers)) 367 (method (cl--generic-method-make
368 specializers qualifiers uses-cnm function))
354 (mt (cl--generic-method-table generic)) 369 (mt (cl--generic-method-table generic))
355 (me (assoc key mt)) 370 (me (cl--generic-member-method specializers qualifiers mt))
356 (dispatches (cl--generic-dispatches generic)) 371 (dispatches (cl--generic-dispatches generic))
357 (i 0)) 372 (i 0))
358 (dolist (specializer specializers) 373 (dolist (specializer specializers)
@@ -367,9 +382,8 @@ which case this method will be invoked when the argument is `eql' to VAL.
367 (nreverse (sort (cons tagcode (cdr x)) 382 (nreverse (sort (cons tagcode (cdr x))
368 #'car-less-than-car)))) 383 #'car-less-than-car))))
369 (setq i (1+ i)))) 384 (setq i (1+ i))))
370 (if me (setcdr me (cons uses-cnm function)) 385 (if me (setcar me method)
371 (setf (cl--generic-method-table generic) 386 (setf (cl--generic-method-table generic) (cons method mt)))
372 (cons `(,key ,uses-cnm . ,function) mt)))
373 (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers)) 387 (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers))
374 current-load-list :test #'equal) 388 current-load-list :test #'equal)
375 (let ((gfun (cl--generic-make-function generic)) 389 (let ((gfun (cl--generic-make-function generic))
@@ -459,47 +473,40 @@ for all those different tags in the method-cache.")
459 (gethash (cons generic-name methods) 473 (gethash (cons generic-name methods)
460 cl--generic-combined-method-memoization) 474 cl--generic-combined-method-memoization)
461 (let ((mets-by-qual ())) 475 (let ((mets-by-qual ()))
462 (dolist (qm methods) 476 (dolist (method methods)
463 (let* ((qualifiers (cdar qm)) 477 (let* ((qualifiers (cl--generic-method-qualifiers method))
464 (x (assoc qualifiers mets-by-qual))) 478 (x (assoc qualifiers mets-by-qual)))
465 ;; FIXME: sadly, alist-get only uses `assq' and we need `assoc'. 479 ;; FIXME: sadly, alist-get only uses `assq' and we need `assoc'.
466 ;;(push (cdr qm) (alist-get qualifiers mets-by-qual))) 480 ;;(push (cdr qm) (alist-get qualifiers mets-by-qual)))
467 (if x 481 (if x
468 (push (cdr qm) (cdr x)) 482 (push method (cdr x))
469 (push (list qualifiers (cdr qm)) mets-by-qual)))) 483 (push (list qualifiers method) mets-by-qual))))
470 (funcall cl-generic-method-combination-function 484 (funcall cl-generic-method-combination-function
471 generic-name mets-by-qual)))) 485 generic-name mets-by-qual))))
472 486
473(defun cl--generic-no-next-method-function (generic) 487(defun cl--generic-no-next-method-function (generic method)
474 (lambda (&rest args) 488 (lambda (&rest args)
475 ;; FIXME: CLOS passes as second arg the "calling method". 489 (apply #'cl-no-next-method generic method args)))
476 ;; We don't currently have "method objects" like CLOS
477 ;; does so we can't really do it the CLOS way.
478 ;; The closest would be to pass the lambda corresponding
479 ;; to the method, or maybe the ((SPECIALIZERS
480 ;; . QUALIFIER) USE-CNM . FUNCTION) entry from the method
481 ;; table, but the caller wouldn't be able to do much with
482 ;; it anyway. So we pass nil for now.
483 (apply #'cl-no-next-method generic nil args)))
484 490
485(defun cl-generic-call-method (generic-name method &optional fun) 491(defun cl-generic-call-method (generic-name method &optional fun)
486 "Return a function that calls METHOD. 492 "Return a function that calls METHOD.
487FUN is the function that should be called when METHOD calls 493FUN is the function that should be called when METHOD calls
488`call-next-method'." 494`call-next-method'."
489 (pcase method 495 (if (not (cl--generic-method-uses-cnm method))
490 (`(nil . ,method) method) 496 (cl--generic-method-function method)
491 (`(,_uses-cnm . ,method) 497 (let ((met-fun (cl--generic-method-function method))
492 (let ((next (or fun (cl--generic-no-next-method-function generic-name)))) 498 (next (or fun (cl--generic-no-next-method-function
493 (lambda (&rest args) 499 generic-name method))))
494 (apply method 500 (lambda (&rest args)
495 ;; FIXME: This sucks: passing just `next' would 501 (apply met-fun
496 ;; be a lot more efficient than the lambda+apply 502 ;; FIXME: This sucks: passing just `next' would
497 ;; quasi-η, but we need this to implement the 503 ;; be a lot more efficient than the lambda+apply
498 ;; "if call-next-method is called with no 504 ;; quasi-η, but we need this to implement the
499 ;; arguments, then use the previous arguments". 505 ;; "if call-next-method is called with no
500 (lambda (&rest cnm-args) 506 ;; arguments, then use the previous arguments".
501 (apply next (or cnm-args args))) 507 (lambda (&rest cnm-args)
502 args)))))) 508 (apply next (or cnm-args args)))
509 args)))))
503 510
504(defun cl--generic-standard-method-combination (generic-name mets-by-qual) 511(defun cl--generic-standard-method-combination (generic-name mets-by-qual)
505 (dolist (x mets-by-qual) 512 (dolist (x mets-by-qual)
@@ -533,10 +540,10 @@ FUN is the function that should be called when METHOD calls
533 (setq fun (cl-generic-call-method generic-name method fun))) 540 (setq fun (cl-generic-call-method generic-name method fun)))
534 fun)))) 541 fun))))
535 542
536(defconst cl--generic-nnm-sample (cl--generic-no-next-method-function 'dummy)) 543(defconst cl--generic-nnm-sample (cl--generic-no-next-method-function t t))
537(defconst cl--generic-cnm-sample 544(defconst cl--generic-cnm-sample
538 (funcall (cl--generic-build-combined-method 545 (funcall (cl--generic-build-combined-method
539 nil `(((specializer . nil) t . ,#'identity))))) 546 nil (list (cl--generic-method-make () () t #'identity)))))
540 547
541(defun cl--generic-isnot-nnm-p (cnm) 548(defun cl--generic-isnot-nnm-p (cnm)
542 "Return non-nil if CNM is the function that calls `cl-no-next-method'." 549 "Return non-nil if CNM is the function that calls `cl-no-next-method'."
@@ -567,11 +574,13 @@ FUN is the function that should be called when METHOD calls
567(defun cl--generic-cache-miss (generic dispatch-arg dispatches-left tags) 574(defun cl--generic-cache-miss (generic dispatch-arg dispatches-left tags)
568 (let ((types (apply #'append (mapcar cl-generic-tag-types-function tags))) 575 (let ((types (apply #'append (mapcar cl-generic-tag-types-function tags)))
569 (methods '())) 576 (methods '()))
570 (dolist (method-desc (cl--generic-method-table generic)) 577 (dolist (method (cl--generic-method-table generic))
571 (let* ((specializer (or (nth dispatch-arg (caar method-desc)) t)) 578 (let* ((specializer (or (nth dispatch-arg
579 (cl--generic-method-specializers method))
580 t))
572 (m (member specializer types))) 581 (m (member specializer types)))
573 (when m 582 (when m
574 (push (cons (length m) method-desc) methods)))) 583 (push (cons (length m) method) methods))))
575 ;; Sort the methods, most specific first. 584 ;; Sort the methods, most specific first.
576 ;; It would be tempting to sort them once and for all in the method-table 585 ;; It would be tempting to sort them once and for all in the method-table
577 ;; rather than here, but the order might depend on the actual argument 586 ;; rather than here, but the order might depend on the actual argument
@@ -614,6 +623,14 @@ Can only be used from within the lexical body of a primary or around method."
614 (declare (obsolete "make sure there's always a next method, or catch `cl-no-next-method' instead" "25.1")) 623 (declare (obsolete "make sure there's always a next method, or catch `cl-no-next-method' instead" "25.1"))
615 (error "cl-next-method-p only allowed inside primary and around methods")) 624 (error "cl-next-method-p only allowed inside primary and around methods"))
616 625
626;;;###autoload
627(defun cl-find-method (generic qualifiers specializers)
628 (car (cl--generic-member-method
629 specializers qualifiers
630 (cl--generic-method-table (cl--generic generic)))))
631
632(defalias 'cl-method-qualifiers 'cl--generic-method-qualifiers)
633
617;;; Add support for describe-function 634;;; Add support for describe-function
618 635
619(defun cl--generic-search-method (met-name) 636(defun cl--generic-search-method (met-name)
@@ -638,22 +655,30 @@ Can only be used from within the lexical body of a primary or around method."
638 `(cl-defmethod . ,#'cl--generic-search-method))) 655 `(cl-defmethod . ,#'cl--generic-search-method)))
639 656
640(defun cl--generic-method-info (method) 657(defun cl--generic-method-info (method)
641 (pcase-let ((`((,specializers . ,qualifier) ,uses-cnm . ,function) method)) 658 (let* ((specializers (cl--generic-method-specializers method))
642 (let* ((args (help-function-arglist function 'names)) 659 (qualifiers (cl--generic-method-qualifiers method))
643 (docstring (documentation function)) 660 (uses-cnm (cl--generic-method-uses-cnm method))
644 (doconly (if docstring 661 (function (cl--generic-method-function method))
645 (let ((split (help-split-fundoc docstring nil))) 662 (args (help-function-arglist function 'names))
646 (if split (cdr split) docstring)))) 663 (docstring (documentation function))
647 (combined-args ())) 664 (qual-string
648 (if uses-cnm (setq args (cdr args))) 665 (if (null qualifiers) ""
649 (dolist (specializer specializers) 666 (cl-assert (consp qualifiers))
650 (let ((arg (if (eq '&rest (car args)) 667 (let ((s (prin1-to-string qualifiers)))
651 (intern (format "arg%d" (length combined-args))) 668 (concat (substring s 1 -1) " "))))
652 (pop args)))) 669 (doconly (if docstring
653 (push (if (eq specializer t) arg (list arg specializer)) 670 (let ((split (help-split-fundoc docstring nil)))
654 combined-args))) 671 (if split (cdr split) docstring))))
655 (setq combined-args (append (nreverse combined-args) args)) 672 (combined-args ()))
656 (list qualifier combined-args doconly)))) 673 (if uses-cnm (setq args (cdr args)))
674 (dolist (specializer specializers)
675 (let ((arg (if (eq '&rest (car args))
676 (intern (format "arg%d" (length combined-args)))
677 (pop args))))
678 (push (if (eq specializer t) arg (list arg specializer))
679 combined-args)))
680 (setq combined-args (append (nreverse combined-args) args))
681 (list qual-string combined-args doconly)))
657 682
658(add-hook 'help-fns-describe-function-functions #'cl--generic-describe) 683(add-hook 'help-fns-describe-function-functions #'cl--generic-describe)
659(defun cl--generic-describe (function) 684(defun cl--generic-describe (function)
@@ -667,8 +692,9 @@ Can only be used from within the lexical body of a primary or around method."
667 (dolist (method (cl--generic-method-table generic)) 692 (dolist (method (cl--generic-method-table generic))
668 (let* ((info (cl--generic-method-info method))) 693 (let* ((info (cl--generic-method-info method)))
669 ;; FIXME: Add hyperlinks for the types as well. 694 ;; FIXME: Add hyperlinks for the types as well.
670 (insert (format "%S %S" (nth 0 info) (nth 1 info))) 695 (insert (format "%s%S" (nth 0 info) (nth 1 info)))
671 (let* ((met-name (cons function (caar method))) 696 (let* ((met-name (cons function
697 (cl--generic-method-specializers method)))
672 (file (find-lisp-object-file-name met-name 'cl-defmethod))) 698 (file (find-lisp-object-file-name met-name 'cl-defmethod)))
673 (when file 699 (when file
674 (insert " in `") 700 (insert " in `")
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
index 30bb5cee994..fcca99d79d5 100644
--- a/lisp/emacs-lisp/eieio-compat.el
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -203,11 +203,10 @@ Summary:
203 ;; or :after, make sure there's a matching dummy primary. 203 ;; or :after, make sure there's a matching dummy primary.
204 (when (and (memq kind '(:before :after)) 204 (when (and (memq kind '(:before :after))
205 ;; FIXME: Use `cl-find-method'? 205 ;; FIXME: Use `cl-find-method'?
206 (not (assoc (cons (mapcar (lambda (arg) 206 (not (cl-find-method method ()
207 (if (consp arg) (nth 1 arg) t)) 207 (mapcar (lambda (arg)
208 specializers) 208 (if (consp arg) (nth 1 arg) t))
209 nil) 209 specializers))))
210 (cl--generic-method-table (cl--generic method)))))
211 (cl-generic-define-method method () specializers t 210 (cl-generic-define-method method () specializers t
212 (lambda (cnm &rest args) 211 (lambda (cnm &rest args)
213 (if (cl--generic-isnot-nnm-p cnm) 212 (if (cl--generic-isnot-nnm-p cnm)
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index a131b02ee16..8d40edf5624 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -129,9 +129,9 @@ If CLASS is actually an object, then also display current values of that object.
129 (insert "`") 129 (insert "`")
130 (help-insert-xref-button (symbol-name generic) 'help-function generic) 130 (help-insert-xref-button (symbol-name generic) 'help-function generic)
131 (insert "'") 131 (insert "'")
132 (pcase-dolist (`(,qualifier ,args ,doc) 132 (pcase-dolist (`(,qualifiers ,args ,doc)
133 (eieio-method-documentation generic class)) 133 (eieio-method-documentation generic class))
134 (insert (format " %S %S\n" qualifier args) 134 (insert (format " %s%S\n" qualifiers args)
135 (or doc ""))) 135 (or doc "")))
136 (insert "\n\n"))))) 136 (insert "\n\n")))))
137 137
@@ -325,10 +325,9 @@ methods for CLASS."
325 (and generic 325 (and generic
326 (catch 'found 326 (catch 'found
327 (if (null class) (throw 'found t)) 327 (if (null class) (throw 'found t))
328 (pcase-dolist (`((,specializers . ,_qualifier) . ,_) 328 (dolist (method (cl--generic-method-table generic))
329 (cl--generic-method-table generic))
330 (if (eieio--specializers-apply-to-class-p 329 (if (eieio--specializers-apply-to-class-p
331 specializers class) 330 (cl--generic-method-specializers method) class)
332 (throw 'found t)))) 331 (throw 'found t))))
333 (push symbol l))))) 332 (push symbol l)))))
334 l)) 333 l))
@@ -336,15 +335,14 @@ methods for CLASS."
336(defun eieio-method-documentation (generic class) 335(defun eieio-method-documentation (generic class)
337 "Return info for all methods of GENERIC applicable to CLASS. 336 "Return info for all methods of GENERIC applicable to CLASS.
338The value returned is a list of elements of the form 337The value returned is a list of elements of the form
339\(QUALIFIER ARGS DOC)." 338\(QUALIFIERS ARGS DOC)."
340 (let ((generic (cl--generic generic)) 339 (let ((generic (cl--generic generic))
341 (docs ())) 340 (docs ()))
342 (when generic 341 (when generic
343 (dolist (method (cl--generic-method-table generic)) 342 (dolist (method (cl--generic-method-table generic))
344 (pcase-let ((`((,specializers . ,_qualifier) . ,_) method)) 343 (when (eieio--specializers-apply-to-class-p
345 (when (eieio--specializers-apply-to-class-p 344 (cl--generic-method-specializers method) class)
346 specializers class) 345 (push (cl--generic-method-info method) docs))))
347 (push (cl--generic-method-info method) docs)))))
348 docs)) 346 docs))
349 347
350;;; METHOD STATS 348;;; METHOD STATS
diff --git a/test/ChangeLog b/test/ChangeLog
index 9a31da45416..61ab8b6595a 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,5 +1,10 @@
12015-01-26 Stefan Monnier <monnier@iro.umontreal.ca> 12015-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * automated/cl-generic-tests.el: Try and make sure cl-lib is not
4 required at run-time.
5
62015-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
7
3 * automated/cl-generic-tests.el (cl-generic-test-11-next-method-p): 8 * automated/cl-generic-tests.el (cl-generic-test-11-next-method-p):
4 New test. 9 New test.
5 10
diff --git a/test/automated/cl-generic-tests.el b/test/automated/cl-generic-tests.el
index 5b3a9fdc2a1..5194802fa00 100644
--- a/test/automated/cl-generic-tests.el
+++ b/test/automated/cl-generic-tests.el
@@ -23,8 +23,8 @@
23 23
24;;; Code: 24;;; Code:
25 25
26(require 'ert) 26(eval-when-compile (require 'ert)) ;Don't indirectly require cl-lib at run-time.
27(require 'cl-lib) 27(require 'cl-generic)
28 28
29(cl-defgeneric cl--generic-1 (x y)) 29(cl-defgeneric cl--generic-1 (x y))
30(cl-defgeneric (setf cl--generic-1) (v y z) "My generic doc.") 30(cl-defgeneric (setf cl--generic-1) (v y z) "My generic doc.")