diff options
| author | Stefan Monnier | 2015-10-29 10:33:36 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-10-29 10:33:36 -0400 |
| commit | aa1c4ae271733cf7dc64918b570bab4034488fa1 (patch) | |
| tree | ae25c2ee8a08e885354de4a8793f871c7723168a /lisp | |
| parent | c0d866dd690ffef08894dbce573c636ab0b42665 (diff) | |
| download | emacs-aa1c4ae271733cf7dc64918b570bab4034488fa1.tar.gz emacs-aa1c4ae271733cf7dc64918b570bab4034488fa1.zip | |
* lisp/emacs-lisp/cl-generic.el: Accomodate future changes
(cl--generic-generalizer): Add `name' field.
(cl-generic-make-generalizer): Add corresponding `name' argument.
(cl-generic-define-generalizer): New macro.
(cl--generic-head-generalizer, cl--generic-eql-generalizer)
(cl--generic-struct-generalizer, cl--generic-typeof-generalizer)
(cl--generic-t-generalizer): Use it.
(cl-generic-ensure-function): Add `noerror' argument.
(cl-generic-define): Use it so we don't follow aliases.
(cl-generic-define-method): Preserve pre-existing ordering of methods.
(cl--generic-arg-specializer): New function.
(cl--generic-cache-miss): Use it.
(cl-generic-generalizers): Only fset a temporary definition
during bootstrap.
(cl--generic-struct-tag, cl--generic-struct-specializers):
Allow extra arguments.
* lisp/emacs-lisp/eieio-compat.el (eieio--generic-static-symbol-generalizer)
(eieio--generic-static-object-generalizer): Use cl-generic-define-generalizer.
(eieio--generic-static-symbol-specializers): Allow extra arguments.
* lisp/emacs-lisp/eieio-core.el (eieio--generic-generalizer)
(eieio--generic-subclass-generalizer): Use cl-generic-define-generalizer.
(eieio--generic-subclass-specializers): Allow extra arguments.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/cl-generic.el | 105 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio-compat.el | 42 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio-core.el | 30 |
3 files changed, 100 insertions, 77 deletions
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index dd01ebe9dd8..0d7ef5b2e61 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el | |||
| @@ -80,7 +80,7 @@ | |||
| 80 | 80 | ||
| 81 | ;; TODO: | 81 | ;; TODO: |
| 82 | ;; | 82 | ;; |
| 83 | ;; - A generic "filter" generalizer (e.g. could be used to cleanly adds methods | 83 | ;; - A generic "filter" generalizer (e.g. could be used to cleanly add methods |
| 84 | ;; to cl-generic-combine-methods with a specializer that says it applies only | 84 | ;; to cl-generic-combine-methods with a specializer that says it applies only |
| 85 | ;; when some particular qualifier is used). | 85 | ;; when some particular qualifier is used). |
| 86 | ;; - A way to dispatch on the context (e.g. the major-mode, some global | 86 | ;; - A way to dispatch on the context (e.g. the major-mode, some global |
| @@ -101,14 +101,33 @@ | |||
| 101 | (cl-defstruct (cl--generic-generalizer | 101 | (cl-defstruct (cl--generic-generalizer |
| 102 | (:constructor nil) | 102 | (:constructor nil) |
| 103 | (:constructor cl-generic-make-generalizer | 103 | (:constructor cl-generic-make-generalizer |
| 104 | (priority tagcode-function specializers-function))) | 104 | (name priority tagcode-function specializers-function))) |
| 105 | (name nil :type string) | ||
| 105 | (priority nil :type integer) | 106 | (priority nil :type integer) |
| 106 | tagcode-function | 107 | tagcode-function |
| 107 | specializers-function) | 108 | specializers-function) |
| 108 | 109 | ||
| 109 | (defconst cl--generic-t-generalizer | 110 | |
| 110 | (cl-generic-make-generalizer | 111 | (defmacro cl-generic-define-generalizer |
| 111 | 0 (lambda (_name) nil) (lambda (_tag) '(t)))) | 112 | (name priority tagcode-function specializers-function) |
| 113 | "Define a new kind of generalizer. | ||
| 114 | NAME is the name of the variable that will hold it. | ||
| 115 | PRIORITY defines which generalizer takes precedence. | ||
| 116 | The catch-all generalizer has priority 0. | ||
| 117 | Then `eql' generalizer has priority 100. | ||
| 118 | TAGCODE-FUNCTION takes as first argument a varname and should return | ||
| 119 | a chunk of code that computes the tag of the value held in that variable. | ||
| 120 | Further arguments are reserved for future use. | ||
| 121 | SPECIALIZERS-FUNCTION takes as first argument a tag value TAG | ||
| 122 | and should return a list of specializers that match TAG. | ||
| 123 | Further arguments are reserved for future use." | ||
| 124 | (declare (indent 1) (debug (symbolp body))) | ||
| 125 | `(defconst ,name | ||
| 126 | (cl-generic-make-generalizer | ||
| 127 | ',name ,priority ,tagcode-function ,specializers-function))) | ||
| 128 | |||
| 129 | (cl-generic-define-generalizer cl--generic-t-generalizer | ||
| 130 | 0 (lambda (_name &rest _) nil) (lambda (_tag &rest _) '(t))) | ||
| 112 | 131 | ||
| 113 | (cl-defstruct (cl--generic-method | 132 | (cl-defstruct (cl--generic-method |
| 114 | (:constructor nil) | 133 | (:constructor nil) |
| @@ -144,16 +163,18 @@ | |||
| 144 | (defmacro cl--generic (name) | 163 | (defmacro cl--generic (name) |
| 145 | `(get ,name 'cl--generic)) | 164 | `(get ,name 'cl--generic)) |
| 146 | 165 | ||
| 147 | (defun cl-generic-ensure-function (name) | 166 | (defun cl-generic-ensure-function (name &optional noerror) |
| 148 | (let (generic | 167 | (let (generic |
| 149 | (origname name)) | 168 | (origname name)) |
| 150 | (while (and (null (setq generic (cl--generic name))) | 169 | (while (and (null (setq generic (cl--generic name))) |
| 151 | (fboundp name) | 170 | (fboundp name) |
| 171 | (null noerror) | ||
| 152 | (symbolp (symbol-function name))) | 172 | (symbolp (symbol-function name))) |
| 153 | (setq name (symbol-function name))) | 173 | (setq name (symbol-function name))) |
| 154 | (unless (or (not (fboundp name)) | 174 | (unless (or (not (fboundp name)) |
| 155 | (autoloadp (symbol-function name)) | 175 | (autoloadp (symbol-function name)) |
| 156 | (and (functionp name) generic)) | 176 | (and (functionp name) generic) |
| 177 | noerror) | ||
| 157 | (error "%s is already defined as something else than a generic function" | 178 | (error "%s is already defined as something else than a generic function" |
| 158 | origname)) | 179 | origname)) |
| 159 | (if generic | 180 | (if generic |
| @@ -220,7 +241,7 @@ BODY, if present, is used as the body of a default method. | |||
| 220 | 241 | ||
| 221 | ;;;###autoload | 242 | ;;;###autoload |
| 222 | (defun cl-generic-define (name args options) | 243 | (defun cl-generic-define (name args options) |
| 223 | (pcase-let* ((generic (cl-generic-ensure-function name)) | 244 | (pcase-let* ((generic (cl-generic-ensure-function name 'noerror)) |
| 224 | (`(,spec-args . ,_) (cl--generic-split-args args)) | 245 | (`(,spec-args . ,_) (cl--generic-split-args args)) |
| 225 | (mandatory (mapcar #'car spec-args)) | 246 | (mandatory (mapcar #'car spec-args)) |
| 226 | (apo (assq :argument-precedence-order options))) | 247 | (apo (assq :argument-precedence-order options))) |
| @@ -418,8 +439,12 @@ which case this method will be invoked when the argument is `eql' to VAL. | |||
| 418 | (setq i (1+ i)))) | 439 | (setq i (1+ i)))) |
| 419 | ;; We used to (setcar me method), but that can cause false positives in | 440 | ;; We used to (setcar me method), but that can cause false positives in |
| 420 | ;; the hash-consing table of the method-builder (bug#20644). | 441 | ;; the hash-consing table of the method-builder (bug#20644). |
| 421 | ;; See the related FIXME in cl--generic-build-combined-method. | 442 | ;; See also the related FIXME in cl--generic-build-combined-method. |
| 422 | (setf (cl--generic-method-table generic) (cons method (delq (car me) mt))) | 443 | (setf (cl--generic-method-table generic) |
| 444 | (if (null me) | ||
| 445 | (cons method mt) | ||
| 446 | ;; Keep the ordering; important for methods with :extra qualifiers. | ||
| 447 | (mapcar (lambda (x) (if (eq x (car me)) method x)) mt))) | ||
| 423 | (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers)) | 448 | (cl-pushnew `(cl-defmethod . (,(cl--generic-name generic) . ,specializers)) |
| 424 | current-load-list :test #'equal) | 449 | current-load-list :test #'equal) |
| 425 | ;; FIXME: Try to avoid re-constructing a new function if the old one | 450 | ;; FIXME: Try to avoid re-constructing a new function if the old one |
| @@ -623,16 +648,19 @@ FUN is the function that should be called when METHOD calls | |||
| 623 | (setq fun (cl-generic-call-method generic method fun))) | 648 | (setq fun (cl-generic-call-method generic method fun))) |
| 624 | fun))))) | 649 | fun))))) |
| 625 | 650 | ||
| 651 | (defun cl--generic-arg-specializer (method dispatch-arg) | ||
| 652 | (or (if (integerp dispatch-arg) | ||
| 653 | (nth dispatch-arg | ||
| 654 | (cl--generic-method-specializers method)) | ||
| 655 | (cdr (assoc dispatch-arg | ||
| 656 | (cl--generic-method-specializers method)))) | ||
| 657 | t)) | ||
| 658 | |||
| 626 | (defun cl--generic-cache-miss (generic | 659 | (defun cl--generic-cache-miss (generic |
| 627 | dispatch-arg dispatches-left methods-left types) | 660 | dispatch-arg dispatches-left methods-left types) |
| 628 | (let ((methods '())) | 661 | (let ((methods '())) |
| 629 | (dolist (method methods-left) | 662 | (dolist (method methods-left) |
| 630 | (let* ((specializer (or (if (integerp dispatch-arg) | 663 | (let* ((specializer (cl--generic-arg-specializer method dispatch-arg)) |
| 631 | (nth dispatch-arg | ||
| 632 | (cl--generic-method-specializers method)) | ||
| 633 | (cdr (assoc dispatch-arg | ||
| 634 | (cl--generic-method-specializers method)))) | ||
| 635 | t)) | ||
| 636 | (m (member specializer types))) | 664 | (m (member specializer types))) |
| 637 | (when m | 665 | (when m |
| 638 | (push (cons (length m) method) methods)))) | 666 | (push (cons (length m) method) methods)))) |
| @@ -682,10 +710,12 @@ The METHODS list is sorted from most specific first to most generic last. | |||
| 682 | The function can use `cl-generic-call-method' to create functions that call those | 710 | The function can use `cl-generic-call-method' to create functions that call those |
| 683 | methods.") | 711 | methods.") |
| 684 | 712 | ||
| 685 | ;; Temporary definition to let the next defmethod succeed. | 713 | (unless (ignore-errors (cl-generic-generalizers t)) |
| 686 | (fset 'cl-generic-generalizers | 714 | ;; Temporary definition to let the next defmethod succeed. |
| 687 | (lambda (_specializer) (list cl--generic-t-generalizer))) | 715 | (fset 'cl-generic-generalizers |
| 688 | (fset 'cl-generic-combine-methods #'cl--generic-standard-method-combination) | 716 | (lambda (specializer) |
| 717 | (if (eq t specializer) (list cl--generic-t-generalizer)))) | ||
| 718 | (fset 'cl-generic-combine-methods #'cl--generic-standard-method-combination)) | ||
| 689 | 719 | ||
| 690 | (cl-defmethod cl-generic-generalizers (specializer) | 720 | (cl-defmethod cl-generic-generalizers (specializer) |
| 691 | "Support for the catch-all t specializer." | 721 | "Support for the catch-all t specializer." |
| @@ -940,10 +970,9 @@ The value returned is a list of elements of the form | |||
| 940 | 970 | ||
| 941 | (defvar cl--generic-head-used (make-hash-table :test #'eql)) | 971 | (defvar cl--generic-head-used (make-hash-table :test #'eql)) |
| 942 | 972 | ||
| 943 | (defconst cl--generic-head-generalizer | 973 | (cl-generic-define-generalizer cl--generic-head-generalizer |
| 944 | (cl-generic-make-generalizer | 974 | 80 (lambda (name &rest _) `(gethash (car-safe ,name) cl--generic-head-used)) |
| 945 | 80 (lambda (name) `(gethash (car-safe ,name) cl--generic-head-used)) | 975 | (lambda (tag &rest _) (if (eq (car-safe tag) 'head) (list tag)))) |
| 946 | (lambda (tag) (if (eq (car-safe tag) 'head) (list tag))))) | ||
| 947 | 976 | ||
| 948 | (cl-defmethod cl-generic-generalizers :extra "head" (specializer) | 977 | (cl-defmethod cl-generic-generalizers :extra "head" (specializer) |
| 949 | "Support for the `(head VAL)' specializers." | 978 | "Support for the `(head VAL)' specializers." |
| @@ -961,10 +990,9 @@ The value returned is a list of elements of the form | |||
| 961 | 990 | ||
| 962 | (defvar cl--generic-eql-used (make-hash-table :test #'eql)) | 991 | (defvar cl--generic-eql-used (make-hash-table :test #'eql)) |
| 963 | 992 | ||
| 964 | (defconst cl--generic-eql-generalizer | 993 | (cl-generic-define-generalizer cl--generic-eql-generalizer |
| 965 | (cl-generic-make-generalizer | 994 | 100 (lambda (name &rest _) `(gethash ,name cl--generic-eql-used)) |
| 966 | 100 (lambda (name) `(gethash ,name cl--generic-eql-used)) | 995 | (lambda (tag &rest _) (if (eq (car-safe tag) 'eql) (list tag)))) |
| 967 | (lambda (tag) (if (eq (car-safe tag) 'eql) (list tag))))) | ||
| 968 | 996 | ||
| 969 | (cl-defmethod cl-generic-generalizers ((specializer (head eql))) | 997 | (cl-defmethod cl-generic-generalizers ((specializer (head eql))) |
| 970 | "Support for the `(eql VAL)' specializers." | 998 | "Support for the `(eql VAL)' specializers." |
| @@ -976,7 +1004,7 @@ The value returned is a list of elements of the form | |||
| 976 | 1004 | ||
| 977 | ;;; Support for cl-defstructs specializers. | 1005 | ;;; Support for cl-defstructs specializers. |
| 978 | 1006 | ||
| 979 | (defun cl--generic-struct-tag (name) | 1007 | (defun cl--generic-struct-tag (name &rest _) |
| 980 | ;; It's tempting to use (and (vectorp ,name) (aref ,name 0)) | 1008 | ;; It's tempting to use (and (vectorp ,name) (aref ,name 0)) |
| 981 | ;; but that would suffer from some problems: | 1009 | ;; but that would suffer from some problems: |
| 982 | ;; - the vector may have size 0. | 1010 | ;; - the vector may have size 0. |
| @@ -1007,16 +1035,15 @@ The value returned is a list of elements of the form | |||
| 1007 | (cl--class-parents class))))) | 1035 | (cl--class-parents class))))) |
| 1008 | (nreverse parents))) | 1036 | (nreverse parents))) |
| 1009 | 1037 | ||
| 1010 | (defun cl--generic-struct-specializers (tag) | 1038 | (defun cl--generic-struct-specializers (tag &rest _) |
| 1011 | (and (symbolp tag) (boundp tag) | 1039 | (and (symbolp tag) (boundp tag) |
| 1012 | (let ((class (symbol-value tag))) | 1040 | (let ((class (symbol-value tag))) |
| 1013 | (when (cl-typep class 'cl-structure-class) | 1041 | (when (cl-typep class 'cl-structure-class) |
| 1014 | (cl--generic-class-parents class))))) | 1042 | (cl--generic-class-parents class))))) |
| 1015 | 1043 | ||
| 1016 | (defconst cl--generic-struct-generalizer | 1044 | (cl-generic-define-generalizer cl--generic-struct-generalizer |
| 1017 | (cl-generic-make-generalizer | 1045 | 50 #'cl--generic-struct-tag |
| 1018 | 50 #'cl--generic-struct-tag | 1046 | #'cl--generic-struct-specializers) |
| 1019 | #'cl--generic-struct-specializers)) | ||
| 1020 | 1047 | ||
| 1021 | (cl-defmethod cl-generic-generalizers :extra "cl-struct" (type) | 1048 | (cl-defmethod cl-generic-generalizers :extra "cl-struct" (type) |
| 1022 | "Support for dispatch on cl-struct types." | 1049 | "Support for dispatch on cl-struct types." |
| @@ -1056,11 +1083,11 @@ The value returned is a list of elements of the form | |||
| 1056 | (sequence) | 1083 | (sequence) |
| 1057 | (number))) | 1084 | (number))) |
| 1058 | 1085 | ||
| 1059 | (defconst cl--generic-typeof-generalizer | 1086 | (cl-generic-define-generalizer cl--generic-typeof-generalizer |
| 1060 | (cl-generic-make-generalizer | 1087 | ;; FIXME: We could also change `type-of' to return `null' for nil. |
| 1061 | ;; FIXME: We could also change `type-of' to return `null' for nil. | 1088 | 10 (lambda (name &rest _) `(if ,name (type-of ,name) 'null)) |
| 1062 | 10 (lambda (name) `(if ,name (type-of ,name) 'null)) | 1089 | (lambda (tag &rest _) |
| 1063 | (lambda (tag) (and (symbolp tag) (assq tag cl--generic-typeof-types))))) | 1090 | (and (symbolp tag) (assq tag cl--generic-typeof-types)))) |
| 1064 | 1091 | ||
| 1065 | (cl-defmethod cl-generic-generalizers :extra "typeof" (type) | 1092 | (cl-defmethod cl-generic-generalizers :extra "typeof" (type) |
| 1066 | "Support for dispatch on builtin types." | 1093 | "Support for dispatch on builtin types." |
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el index 386ff2f7449..638c475ef2b 100644 --- a/lisp/emacs-lisp/eieio-compat.el +++ b/lisp/emacs-lisp/eieio-compat.el | |||
| @@ -124,7 +124,7 @@ Summary: | |||
| 124 | (defgeneric ,method ,args) | 124 | (defgeneric ,method ,args) |
| 125 | (eieio--defmethod ',method ',key ',class #',code)))) | 125 | (eieio--defmethod ',method ',key ',class #',code)))) |
| 126 | 126 | ||
| 127 | (defun eieio--generic-static-symbol-specializers (tag) | 127 | (defun eieio--generic-static-symbol-specializers (tag &rest _) |
| 128 | (cl-assert (or (null tag) (eieio--class-p tag))) | 128 | (cl-assert (or (null tag) (eieio--class-p tag))) |
| 129 | (when (eieio--class-p tag) | 129 | (when (eieio--class-p tag) |
| 130 | (let ((superclasses (eieio--generic-subclass-specializers tag)) | 130 | (let ((superclasses (eieio--generic-subclass-specializers tag)) |
| @@ -134,27 +134,25 @@ Summary: | |||
| 134 | (push `(eieio--static ,(cadr superclass)) specializers)) | 134 | (push `(eieio--static ,(cadr superclass)) specializers)) |
| 135 | (nreverse specializers)))) | 135 | (nreverse specializers)))) |
| 136 | 136 | ||
| 137 | (defconst eieio--generic-static-symbol-generalizer | 137 | (cl-generic-define-generalizer eieio--generic-static-symbol-generalizer |
| 138 | (cl-generic-make-generalizer | 138 | ;; Give it a slightly higher priority than `subclass' so that the |
| 139 | ;; Give it a slightly higher priority than `subclass' so that the | 139 | ;; interleaved list comes before subclass's non-interleaved list. |
| 140 | ;; interleaved list comes before subclass's non-interleaved list. | 140 | 61 (lambda (name &rest _) `(and (symbolp ,name) (cl--find-class ,name))) |
| 141 | 61 (lambda (name) `(and (symbolp ,name) (cl--find-class ,name))) | 141 | #'eieio--generic-static-symbol-specializers) |
| 142 | #'eieio--generic-static-symbol-specializers)) | 142 | (cl-generic-define-generalizer eieio--generic-static-object-generalizer |
| 143 | (defconst eieio--generic-static-object-generalizer | 143 | ;; Give it a slightly higher priority than `class' so that the |
| 144 | (cl-generic-make-generalizer | 144 | ;; interleaved list comes before the class's non-interleaved list. |
| 145 | ;; Give it a slightly higher priority than `class' so that the | 145 | 51 #'cl--generic-struct-tag |
| 146 | ;; interleaved list comes before the class's non-interleaved list. | 146 | (lambda (tag _targets) |
| 147 | 51 #'cl--generic-struct-tag | 147 | (and (symbolp tag) (boundp tag) (setq tag (symbol-value tag)) |
| 148 | (lambda (tag) | 148 | (eieio--class-p tag) |
| 149 | (and (symbolp tag) (boundp tag) (setq tag (symbol-value tag)) | 149 | (let ((superclasses (eieio--class-precedence-list tag)) |
| 150 | (eieio--class-p tag) | 150 | (specializers ())) |
| 151 | (let ((superclasses (eieio--class-precedence-list tag)) | 151 | (dolist (superclass superclasses) |
| 152 | (specializers ())) | 152 | (setq superclass (eieio--class-name superclass)) |
| 153 | (dolist (superclass superclasses) | 153 | (push superclass specializers) |
| 154 | (setq superclass (eieio--class-name superclass)) | 154 | (push `(eieio--static ,superclass) specializers)) |
| 155 | (push superclass specializers) | 155 | (nreverse specializers))))) |
| 156 | (push `(eieio--static ,superclass) specializers)) | ||
| 157 | (nreverse specializers)))))) | ||
| 158 | 156 | ||
| 159 | (cl-defmethod cl-generic-generalizers ((_specializer (head eieio--static))) | 157 | (cl-defmethod cl-generic-generalizers ((_specializer (head eieio--static))) |
| 160 | (list eieio--generic-static-symbol-generalizer | 158 | (list eieio--generic-static-symbol-generalizer |
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index e3f7b11bb64..7011a30656b 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el | |||
| @@ -1059,16 +1059,15 @@ method invocation orders of the involved classes." | |||
| 1059 | 1059 | ||
| 1060 | ;;;; General support to dispatch based on the type of the argument. | 1060 | ;;;; General support to dispatch based on the type of the argument. |
| 1061 | 1061 | ||
| 1062 | (defconst eieio--generic-generalizer | 1062 | (cl-generic-define-generalizer eieio--generic-generalizer |
| 1063 | (cl-generic-make-generalizer | 1063 | ;; Use the exact same tagcode as for cl-struct, so that methods |
| 1064 | ;; Use the exact same tagcode as for cl-struct, so that methods | 1064 | ;; that dispatch on both kinds of objects get to share this |
| 1065 | ;; that dispatch on both kinds of objects get to share this | 1065 | ;; part of the dispatch code. |
| 1066 | ;; part of the dispatch code. | 1066 | 50 #'cl--generic-struct-tag |
| 1067 | 50 #'cl--generic-struct-tag | 1067 | (lambda (tag &rest _) |
| 1068 | (lambda (tag) | 1068 | (and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag)) |
| 1069 | (and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag)) | 1069 | (mapcar #'eieio--class-name |
| 1070 | (mapcar #'eieio--class-name | 1070 | (eieio--class-precedence-list (symbol-value tag)))))) |
| 1071 | (eieio--class-precedence-list (symbol-value tag))))))) | ||
| 1072 | 1071 | ||
| 1073 | (cl-defmethod cl-generic-generalizers :extra "class" (specializer) | 1072 | (cl-defmethod cl-generic-generalizers :extra "class" (specializer) |
| 1074 | ;; CLHS says: | 1073 | ;; CLHS says: |
| @@ -1088,22 +1087,21 @@ method invocation orders of the involved classes." | |||
| 1088 | ;; would not make much sense (e.g. to which argument should it apply?). | 1087 | ;; would not make much sense (e.g. to which argument should it apply?). |
| 1089 | ;; Instead, we add a new "subclass" specializer. | 1088 | ;; Instead, we add a new "subclass" specializer. |
| 1090 | 1089 | ||
| 1091 | (defun eieio--generic-subclass-specializers (tag) | 1090 | (defun eieio--generic-subclass-specializers (tag &rest _) |
| 1092 | (when (eieio--class-p tag) | 1091 | (when (eieio--class-p tag) |
| 1093 | (mapcar (lambda (class) | 1092 | (mapcar (lambda (class) |
| 1094 | `(subclass ,(eieio--class-name class))) | 1093 | `(subclass ,(eieio--class-name class))) |
| 1095 | (eieio--class-precedence-list tag)))) | 1094 | (eieio--class-precedence-list tag)))) |
| 1096 | 1095 | ||
| 1097 | (defconst eieio--generic-subclass-generalizer | 1096 | (cl-generic-define-generalizer eieio--generic-subclass-generalizer |
| 1098 | (cl-generic-make-generalizer | 1097 | 60 (lambda (name &rest _) `(and (symbolp ,name) (cl--find-class ,name))) |
| 1099 | 60 (lambda (name) `(and (symbolp ,name) (cl--find-class ,name))) | 1098 | #'eieio--generic-subclass-specializers) |
| 1100 | #'eieio--generic-subclass-specializers)) | ||
| 1101 | 1099 | ||
| 1102 | (cl-defmethod cl-generic-generalizers ((_specializer (head subclass))) | 1100 | (cl-defmethod cl-generic-generalizers ((_specializer (head subclass))) |
| 1103 | (list eieio--generic-subclass-generalizer)) | 1101 | (list eieio--generic-subclass-generalizer)) |
| 1104 | 1102 | ||
| 1105 | 1103 | ||
| 1106 | ;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "ea8c7f24ed47c6b71ac37cbdae1c9931") | 1104 | ;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "bd51800d7de6429a2c9a6a600ba2dc52") |
| 1107 | ;;; Generated autoloads from eieio-compat.el | 1105 | ;;; Generated autoloads from eieio-compat.el |
| 1108 | 1106 | ||
| 1109 | (autoload 'eieio--defalias "eieio-compat" "\ | 1107 | (autoload 'eieio--defalias "eieio-compat" "\ |