1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-29 11:02:01 +00:00

Make bytecomp.el understand that defmethod defines functions.

* lisp/emacs-lisp/eieio.el (eieio--defalias, eieio--defgeneric-init-form):
New functions.
(defgeneric, eieio--defmethod): Use them.
(eieio-defgeneric): Remove.
(defmethod): Call defgeneric in a way visible to the byte-compiler.

Fixes: debbugs:8631
This commit is contained in:
Stefan Monnier 2011-05-07 01:03:49 -03:00
parent 4d3fcc8e60
commit d1dc2cc2ce
3 changed files with 54 additions and 33 deletions

View File

@ -1,3 +1,12 @@
2011-05-07 Stefan Monnier <monnier@iro.umontreal.ca>
Make bytecomp.el understand that defmethod defines funs (bug#8631).
* emacs-lisp/eieio.el (eieio--defalias, eieio--defgeneric-init-form):
New functions.
(defgeneric, eieio--defmethod): Use them.
(eieio-defgeneric): Remove.
(defmethod): Call defgeneric in a way visible to the byte-compiler.
2011-05-07 Glenn Morris <rgm@gnu.org>
* calendar/timeclock.el (timeclock-log-data): Remove unused local.
@ -17,7 +26,7 @@
2011-05-06 Stefan Monnier <monnier@iro.umontreal.ca>
* lpr.el (print-region-1): Echo lpr-program's output, so error messages
and warnings are not silently discarded (e.g. use "-d" instead of "-P").
and warnings are not silently discarded (e.g. use -d instead of -P).
2011-05-06 Glenn Morris <rgm@gnu.org>

View File

@ -4173,6 +4173,7 @@ binding slots have been popped."
;; Compile normally, but deal with warnings for the function being defined.
(put 'defalias 'byte-hunk-handler 'byte-compile-file-form-defalias)
;; Used for eieio--defalias as well.
(defun byte-compile-file-form-defalias (form)
(if (and (consp (cdr form)) (consp (nth 1 form))
(eq (car (nth 1 form)) 'quote)

View File

@ -420,6 +420,7 @@ It creates an autoload function for CNAME's constructor."
(load-library (car (cdr (symbol-function cname))))))
(defun eieio-defclass (cname superclasses slots options-and-doc)
;; FIXME: Most of this should be moved to the `defclass' macro.
"Define CNAME as a new subclass of SUPERCLASSES.
SLOTS are the slots residing in that class definition, and options or
documentation OPTIONS-AND-DOC is the toplevel documentation for this class.
@ -1139,6 +1140,17 @@ a string."
;;; CLOS methods and generics
;;
(put 'eieio--defalias 'byte-hunk-handler
#'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
(defun eieio--defalias (name body)
"Like `defalias', but with less side-effects.
More specifically, it has no side-effects at all when the new function
definition is the same (`eq') as the old one."
(unless (and (fboundp name)
(eq (symbol-function name) body))
(defalias name body)))
(defmacro defgeneric (method args &optional doc-string)
"Create a generic function METHOD.
DOC-STRING is the base documentation for this class. A generic
@ -1147,7 +1159,21 @@ is appropriate to use. Uses `defmethod' to create methods, and calls
`defgeneric' for you. With this implementation the ARGS are
currently ignored. You can use `defgeneric' to apply specialized
top level documentation to a method."
`(eieio-defgeneric (quote ,method) ,doc-string))
`(eieio--defalias ',method
(eieio--defgeneric-init-form ',method ,doc-string)))
(defun eieio--defgeneric-init-form (method doc-string)
"Form to use for the initial definition of a generic."
(cond
((or (not (fboundp method))
(eq 'autoload (car-safe (symbol-function method))))
;; Make sure the method tables are installed.
(eieiomt-install method)
;; Construct the actual body of this function.
(eieio-defgeneric-form method doc-string))
((generic-p method) (symbol-function method)) ;Leave it as-is.
(t (error "You cannot create a generic/method over an existing symbol: %s"
method))))
(defun eieio-defgeneric-form (method doc-string)
"The lambda form that would be used as the function defined on METHOD.
@ -1237,26 +1263,6 @@ IMPL is the symbol holding the method implementation."
(cdr entry)
))))
(defun eieio-defgeneric (method doc-string)
"Engine part to `defgeneric' macro defining METHOD with DOC-STRING."
(if (and (fboundp method) (not (generic-p method))
(or (byte-code-function-p (symbol-function method))
(not (eq 'autoload (car (symbol-function method)))))
)
(error "You cannot create a generic/method over an existing symbol: %s"
method))
;; Don't do this over and over.
(unless (fboundp 'method)
;; This defun tells emacs where the first definition of this
;; method is defined.
`(defun ,method nil)
;; Make sure the method tables are installed.
(eieiomt-install method)
;; Apply the actual body of this function.
(fset method (eieio-defgeneric-form method doc-string))
;; Return the method
'method))
(defun eieio-unbind-method-implementations (method)
"Make the generic method METHOD have no implementations.
It will leave the original generic function in place,
@ -1292,12 +1298,17 @@ Summary:
(let* ((key (if (keywordp (car args)) (pop args)))
(params (car args))
(arg1 (car params))
(class (if (consp arg1) (nth 1 arg1))))
`(eieio--defmethod ',method ',key ',class
(lambda ,(if (consp arg1)
(cons (car arg1) (cdr params))
params)
,@(cdr args)))))
(args (if (consp arg1)
(cons (car arg1) (cdr params))
params))
(class (if (consp arg1) (nth 1 arg1)))
(code `(lambda ,args ,@(cdr args))))
`(progn
;; Make sure there is a generic and the byte-compiler sees it.
(defgeneric ,method ,args
,(or (documentation code)
(format "Generically created method `%s'." method)))
(eieio--defmethod ',method ',key ',class ',code))))
(defun eieio--defmethod (method kind argclass code)
"Work part of the `defmethod' macro defining METHOD with ARGS."
@ -1317,11 +1328,11 @@ Summary:
method-static)
;; Primary key
(t method-primary))))
;; make sure there is a generic
(eieio-defgeneric
method
(or (documentation code)
(format "Generically created method `%s'." method)))
;; Make sure there is a generic (when called from defclass).
(eieio--defalias
method (eieio--defgeneric-init-form
method (or (documentation code)
(format "Generically created method `%s'." method))))
;; create symbol for property to bind to. If the first arg is of
;; the form (varname vartype) and `vartype' is a class, then
;; that class will be the type symbol. If not, then it will fall