Commit 21c54786 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

Replace *-function vars with generic functions in cl-generic.

* lisp/emacs-lisp/cl-generic.el (cl--generic-generalizer): New struct.
(cl-generic-tagcode-function, cl-generic-tag-types-function): Remove.
(cl--generic-t-generalizer): New const.
(cl--generic-make-method): Rename from `cl--generic-method-make'.
(cl--generic-make): Change calling convention.
(cl--generic): Add `options' field.
(cl-generic-function-options): New function.
(cl-defgeneric): Rewrite handling of options.  Add support for :method
options and allow the use of a default body.
(cl-generic-define): Save options in the corresponding new field.
(cl-defmethod): Fix ordering of qualifiers.
(cl-generic-define-method): Use cl-generic-generalizers.
(cl--generic-get-dispatcher): Change calling convention, and change
calling convention of the returned function as well so as to take the
list of methods separately from the generic function object, so that it
can receive the original generic function object.
(cl--generic-make-next-function): New function, extracted from
cl--generic-make-function.
(cl--generic-make-function): Use it.
(cl-generic-method-combination-function): Remove.
(cl--generic-cyclic-definition): New error.
(cl-generic-call-method): Take a generic function object rather than
its name.
(cl-method-qualifiers): New alias.
(cl--generic-build-combined-method): Use cl-generic-combine-methods,
don't segregate by qualifiers here any more.
(cl--generic-standard-method-combination): Segregate by qualifiers
here instead.  Add support for the `:extra' qualifier.
(cl--generic-cache-miss): Move earlier, adjust to new calling convention.
(cl-generic-generalizers, cl-generic-combine-methods):
New generic functions.
(cl-no-next-method, cl-no-applicable-method, cl-no-primary-method):
Use the new "default method in defgeneric" functionality, change
calling convention to receive a generic function object.
(cl--generic-head-used): New var.
(cl--generic-head-generalizer, cl--generic-eql-generalizer)
(cl--generic-struct-generalizer, cl--generic-typeof-generalizer):
New consts.
* lisp/emacs-lisp/eieio-core.el (eieio--generic-generalizer)
(eieio--generic-subclass-generalizer): New consts.
(cl-generic-generalizers): New methods.
* lisp/emacs-lisp/eieio-compat.el (eieio--generic-static-symbol-generalizer)
(eieio--generic-static-object-generalizer): New consts.
(cl-generic-generalizers) <(head eieio--static)>: New method.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
Unfold closures like lambdas.
parent 9f1f6c8b
2015-03-05 Stefan Monnier <monnier@iro.umontreal.ca>
Replace *-function vars with generic functions in cl-generic.
* emacs-lisp/cl-generic.el (cl--generic-generalizer): New struct.
(cl-generic-tagcode-function, cl-generic-tag-types-function): Remove.
(cl--generic-t-generalizer): New const.
(cl--generic-make-method): Rename from `cl--generic-method-make'.
(cl--generic-make): Change calling convention.
(cl--generic): Add `options' field.
(cl-generic-function-options): New function.
(cl-defgeneric): Rewrite handling of options. Add support for :method
options and allow the use of a default body.
(cl-generic-define): Save options in the corresponding new field.
(cl-defmethod): Fix ordering of qualifiers.
(cl-generic-define-method): Use cl-generic-generalizers.
(cl--generic-get-dispatcher): Change calling convention, and change
calling convention of the returned function as well so as to take the
list of methods separately from the generic function object, so that it
can receive the original generic function object.
(cl--generic-make-next-function): New function, extracted from
cl--generic-make-function.
(cl--generic-make-function): Use it.
(cl-generic-method-combination-function): Remove.
(cl--generic-cyclic-definition): New error.
(cl-generic-call-method): Take a generic function object rather than
its name.
(cl-method-qualifiers): New alias.
(cl--generic-build-combined-method): Use cl-generic-combine-methods,
don't segregate by qualifiers here any more.
(cl--generic-standard-method-combination): Segregate by qualifiers
here instead. Add support for the `:extra' qualifier.
(cl--generic-cache-miss): Move earlier, adjust to new calling convention.
(cl-generic-generalizers, cl-generic-combine-methods):
New generic functions.
(cl-no-next-method, cl-no-applicable-method, cl-no-primary-method):
Use the new "default method in defgeneric" functionality, change
calling convention to receive a generic function object.
(cl--generic-head-used): New var.
(cl--generic-head-generalizer, cl--generic-eql-generalizer)
(cl--generic-struct-generalizer, cl--generic-typeof-generalizer):
New consts.
* emacs-lisp/eieio-core.el (eieio--generic-generalizer)
(eieio--generic-subclass-generalizer): New consts.
(cl-generic-generalizers): New methods.
* emacs-lisp/eieio-compat.el (eieio--generic-static-symbol-generalizer)
(eieio--generic-static-object-generalizer): New consts.
(cl-generic-generalizers) <(head eieio--static)>: New method.
* emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
Unfold closures like lambdas.
2015-03-04 Filipp Gunbin <fgunbin@fastmail.fm>
 
* autorevert.el (auto-revert-notify-add-watch):
......@@ -142,8 +192,8 @@
2015-03-03 Eli Zaretskii <eliz@gnu.org>
 
* frame.el (frame-notice-user-settings): Refresh the value of
frame parameters after calling tty-handle-reverse-video. Call
face-set-after-frame-default with the actual parameters, to avoid
frame parameters after calling tty-handle-reverse-video.
Call face-set-after-frame-default with the actual parameters, to avoid
resetting colors back to unspecified.
(set-background-color, set-foreground-color): Pass the foreground
and background colors to face-set-after-frame-default. (Bug#19802)
......@@ -176,8 +226,8 @@
 
2015-03-03 Eli Zaretskii <eliz@gnu.org>
 
* textmodes/artist.el (artist-ellipse-compute-fill-info): Use
mapcar, not mapc, to create the other half of fill-info.
* textmodes/artist.el (artist-ellipse-compute-fill-info):
Use mapcar, not mapc, to create the other half of fill-info.
(Bug#19763)
 
2015-03-03 Nicolas Petton <nicolas@petton.fr>
......@@ -323,8 +373,8 @@
 
Handle "#" operator properly inside macro. Fix coding bug.
 
* progmodes/cc-mode.el (c-neutralize-syntax-in-and-mark-CPP): On
finding a "#" which looks like the start of a macro, check it
* progmodes/cc-mode.el (c-neutralize-syntax-in-and-mark-CPP):
On finding a "#" which looks like the start of a macro, check it
isn't already inside a macro.
 
* progmodes/cc-engine.el (c-state-safe-place): Don't record a new
......@@ -364,15 +414,15 @@
 
2015-02-25 Oleh Krehel <ohwoeowho@gmail.com>
 
* emacs-lisp/check-declare.el (check-declare-warn): Use
compilation-style warnings.
* emacs-lisp/check-declare.el (check-declare-warn):
Use compilation-style warnings.
(check-declare-files): Make sure that
`check-declare-warning-buffer' is in `compilation-mode'.
 
2015-02-25 Oleh Krehel <ohwoeowho@gmail.com>
 
* emacs-lisp/check-declare.el (check-declare-ext-errors): New
defcustom.
* emacs-lisp/check-declare.el (check-declare-ext-errors):
New defcustom.
(check-declare): New defgroup.
(check-declare-verify): When `check-declare-ext-errors' is
non-nil, warn about an unfound function, instead of saying
......@@ -380,8 +430,8 @@
 
2015-02-25 Tassilo Horn <tsdh@gnu.org>
 
* textmodes/reftex-vars.el (reftex-include-file-commands): Call
reftex-set-dirty on changes.
* textmodes/reftex-vars.el (reftex-include-file-commands):
Call reftex-set-dirty on changes.
 
2015-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
 
......
......@@ -390,7 +390,7 @@
(and (nth 1 form)
(not for-effect)
form))
((eq 'lambda (car-safe fn))
((memq (car-safe fn) '(lambda closure))
(let ((newform (byte-compile-unfold-lambda form)))
(if (eq newform form)
;; Some error occurred, avoid infinite recursion
......
This diff is collapsed.
......@@ -124,30 +124,38 @@ Summary:
(defgeneric ,method ,args)
(eieio--defmethod ',method ',key ',class #',code))))
(add-function :before-until cl-generic-tagcode-function
#'eieio--generic-static-tagcode)
(defun eieio--generic-static-tagcode (type name)
(and (eq 'eieio--static (car-safe type))
`(40 . (cond
((symbolp ,name) (eieio--class-v ,name))
((vectorp ,name) (aref ,name 0))))))
(add-function :around cl-generic-tag-types-function
#'eieio--generic-static-tag-types)
(defun eieio--generic-static-tag-types (orig-fun tag)
(cond
((or (eieio--class-p tag)
(and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag))))
(let ((superclasses (funcall orig-fun tag))
(types ()))
;; Interleave: (subclass <foo>) (eieio--static <foo>) <subclass <bar>) ..
(dolist (superclass superclasses)
(push superclass types)
(push `(eieio--static
,(if (consp superclass) (cadr superclass) superclass))
types))
(nreverse types)))
(t (funcall orig-fun tag))))
(defconst eieio--generic-static-symbol-generalizer
(cl-generic-make-generalizer
;; Give it a slightly higher priority than `subclass' so that the
;; interleaved list comes before subclass's non-interleaved list.
61 (lambda (name) `(and (symbolp ,name) (eieio--class-v ,name)))
(lambda (tag)
(when (eieio--class-p tag)
(let ((superclasses (eieio--generic-subclass-specializers tag))
(specializers ()))
(dolist (superclass superclasses)
(push superclass specializers)
(push `(eieio--static ,(cadr superclass)) specializers))
(nreverse specializers))))))
(defconst eieio--generic-static-object-generalizer
(cl-generic-make-generalizer
;; Give it a slightly higher priority than `class' so that the
;; interleaved list comes before the class's non-interleaved list.
51 #'cl--generic-struct-tag
(lambda (tag)
(and (symbolp tag) (boundp tag) (setq tag (symbol-value tag))
(eieio--class-p tag)
(let ((superclasses (eieio--class-precedence-list tag))
(specializers ()))
(dolist (superclass superclasses)
(setq superclass (eieio--class-symbol superclass))
(push superclass specializers)
(push `(eieio--static ,superclass) specializers))
(nreverse specializers))))))
(cl-defmethod cl-generic-generalizers ((_specializer (head eieio--static)))
(list eieio--generic-static-symbol-generalizer
eieio--generic-static-object-generalizer))
;;;###autoload
(defun eieio--defgeneric-init-form (method doc-string)
......
......@@ -1203,25 +1203,26 @@ method invocation orders of the involved classes."
;;;; General support to dispatch based on the type of the argument.
(add-function :before-until cl-generic-tagcode-function
#'eieio--generic-tagcode)
(defun eieio--generic-tagcode (type name)
(defconst eieio--generic-generalizer
(cl-generic-make-generalizer
;; Use the exact same tagcode as for cl-struct, so that methods
;; that dispatch on both kinds of objects get to share this
;; part of the dispatch code.
50 #'cl--generic-struct-tag
(lambda (tag)
(and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag))
(mapcar #'eieio--class-symbol
(eieio--class-precedence-list (symbol-value tag)))))))
(cl-defmethod cl-generic-generalizers :extra "class" (specializer)
;; CLHS says:
;; A class must be defined before it can be used as a parameter
;; specializer in a defmethod form.
;; So we can ignore types that are not known to denote classes.
(and (eieio--class-p (eieio--class-object type))
;; Use the exact same code as for cl-struct, so that methods
;; that dispatch on both kinds of objects get to share this
;; part of the dispatch code.
`(50 . ,(cl--generic-struct-tag name))))
(add-function :before-until cl-generic-tag-types-function
#'eieio--generic-tag-types)
(defun eieio--generic-tag-types (tag)
(and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag))
(mapcar #'eieio--class-symbol
(eieio--class-precedence-list (symbol-value tag)))))
(or
(and (eieio--class-p (eieio--class-object specializer))
(list eieio--generic-generalizer))
(cl-call-next-method)))
;;;; Dispatch for arguments which are classes.
......@@ -1231,23 +1232,22 @@ method invocation orders of the involved classes."
;; would not make much sense (e.g. to which argument should it apply?).
;; Instead, we add a new "subclass" specializer.
(add-function :before-until cl-generic-tagcode-function
#'eieio--generic-subclass-tagcode)
(defun eieio--generic-subclass-tagcode (type name)
(when (eq 'subclass (car-safe type))
`(60 . (and (symbolp ,name) (eieio--class-v ,name)))))
(add-function :before-until cl-generic-tag-types-function
#'eieio--generic-subclass-tag-types)
(defun eieio--generic-subclass-tag-types (tag)
(defun eieio--generic-subclass-specializers (tag)
(when (eieio--class-p tag)
(mapcar (lambda (class)
`(subclass
,(if (symbolp class) class (eieio--class-symbol class))))
`(subclass ,(eieio--class-symbol class)))
(eieio--class-precedence-list tag))))
(defconst eieio--generic-subclass-generalizer
(cl-generic-make-generalizer
60 (lambda (name) `(and (symbolp ,name) (eieio--class-v ,name)))
#'eieio--generic-subclass-specializers))
(cl-defmethod cl-generic-generalizers ((_specializer (head subclass)))
(list eieio--generic-subclass-generalizer))
;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "5b04c9a8fff2bd3f3d3ac54aba0f65b7")
;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "25a66814a400e7dea16bf0f3bfe245ed")
;;; Generated autoloads from eieio-compat.el
(autoload 'eieio--defalias "eieio-compat" "\
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment