diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2015-01-18 12:24:43 -0500 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2015-01-18 12:24:43 -0500 |
commit | 2a61bd0096db23123734db439051c859e42b9606 (patch) | |
tree | 95bf8383ee904cf723e57d1560f86fc551fb139b /lisp/emacs-lisp/cl-generic.el | |
parent | 8ab85ee7ce9ad101583620e7ba3bee39cf3491ae (diff) | |
download | emacs-2a61bd0096db23123734db439051c859e42b9606.tar.gz |
EIEIO&cl-generic: Add obsolescence warnings and fix corner case
* lisp/emacs-lisp/cl-generic.el (cl-generic-define-method): Correctly handle
introduction of a new dispatch argument.
(cl--generic-cache-miss): Handle dispatch on an argument which was not
considered as dispatchable for this method.
(cl-defmethod): Warn when adding a method to an obsolete generic function.
(cl--generic-lambda): Make sure it works if cl-lib is not yet loaded.
* lisp/emacs-lisp/eieio-generic.el (eieio--defgeneric-init-form):
Use autoloadp.
* lisp/emacs-lisp/eieio.el (defclass): Add obsolescence warning for the
`newname' argument.
* test/automated/cl-generic-tests.el (cl-generic-test-10-weird): New test.
Rename other tests to preserve ordering.
Diffstat (limited to 'lisp/emacs-lisp/cl-generic.el')
-rw-r--r-- | lisp/emacs-lisp/cl-generic.el | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 819e2e92888..544f1fa140f 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -212,13 +212,13 @@ This macro can only be used within the lexical scope of a cl-generic method." (macroenv (cons `(cl-generic-current-method-specializers . ,(lambda () specializers)) macroexpand-all-environment))) + (require 'cl-lib) ;Needed to expand `cl-flet' and `cl-function'. (if (not with-cnm) (cons nil (macroexpand-all fun macroenv)) ;; First macroexpand away the cl-function stuff (e.g. &key and ;; destructuring args, `declare' and whatnot). (pcase (macroexpand fun macroenv) (`#'(lambda ,args . ,body) - (require 'cl-lib) ;Needed to expand `cl-flet'. (let* ((doc-string (and doc-string (stringp (car body)) (pop body))) (cnm (make-symbol "cl--cnm")) @@ -287,6 +287,13 @@ which case this method will be invoked when the argument is `eql' to VAL. (cadr name)))) (setq name setter) code)) + ,(and (get name 'byte-obsolete-info) + (or (not (fboundp 'byte-compile-warning-enabled-p)) + (byte-compile-warning-enabled-p 'obsolete)) + (let* ((obsolete (get name 'byte-obsolete-info))) + (macroexp--warn-and-return + (macroexp--obsolete-warning name obsolete "generic function") + nil))) (cl-generic-define-method ',name ',qualifiers ',args ,uses-cnm ,fun))))) @@ -308,13 +315,14 @@ which case this method will be invoked when the argument is `eql' to VAL. (dolist (specializer specializers) (let* ((tagcode (funcall cl-generic-tagcode-function specializer 'arg)) (x (assq i dispatches))) - (if (not x) - (setf (cl--generic-dispatches generic) - (setq dispatches (cons (list i tagcode) dispatches))) - (unless (member tagcode (cdr x)) - (setf (cdr x) - (nreverse (sort (cons tagcode (cdr x)) - #'car-less-than-car))))) + (unless x + (setq x (list i (funcall cl-generic-tagcode-function t 'arg))) + (setf (cl--generic-dispatches generic) + (setq dispatches (cons x dispatches)))) + (unless (member tagcode (cdr x)) + (setf (cdr x) + (nreverse (sort (cons tagcode (cdr x)) + #'car-less-than-car)))) (setq i (1+ i)))) (if me (setcdr me (cons uses-cnm function)) (setf (cl--generic-method-table generic) @@ -478,7 +486,8 @@ for all those different tags in the method-cache.") (let ((types (apply #'append (mapcar cl-generic-tag-types-function tags))) (methods '())) (dolist (method-desc (cl--generic-method-table generic)) - (let ((m (member (nth dispatch-arg (caar method-desc)) types))) + (let* ((specializer (or (nth dispatch-arg (caar method-desc)) t)) + (m (member specializer types))) (when m (push (cons (length m) method-desc) methods)))) ;; Sort the methods, most specific first. |