GNU bug report logs -
#8631
since lexical merge, byte compiler does not know defmethod defines a function
Previous Next
Reported by: Glenn Morris <rgm <at> gnu.org>
Date: Fri, 6 May 2011 17:50:03 UTC
Severity: normal
Found in version 24.0.50
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
Your message dated Sat, 07 May 2011 01:07:17 -0300
with message-id <jwvliyjyx3b.fsf-monnier+emacs <at> gnu.org>
and subject line Re: bug#8631: since lexical merge, byte compiler does not know defmethod defines a function
has caused the GNU bug report #8631,
regarding since lexical merge, byte compiler does not know defmethod defines a function
to be marked as done.
(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)
--
8631: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8631
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
Package: emacs
Version: 24.0.50
Since the lexical branch was merged (ie r103798), the byte compiler does
not understand that eieio's defmethod defines a function.
Eg:
emacs -Q -batch -f batch-byte-compile cedet/srecode/dictionary.el
In end of data:
dictionary.el:712:1:Warning: the following functions are not known to be
defined: srecode-dictionary-add-template-table,[...]
[Message part 3 (message/rfc822, inline)]
> Since the lexical branch was merged (ie r103798), the byte compiler does
> not understand that eieio's defmethod defines a function.
> Eg:
> emacs -Q -batch -f batch-byte-compile cedet/srecode/dictionary.el
> In end of data:
> dictionary.el:712:1:Warning: the following functions are not known to be
> defined: srecode-dictionary-add-template-table,[...]
Should be fixed now, thanks to the patch below,
Stefan
=== modified file 'lisp/emacs-lisp/bytecomp.el'
--- lisp/emacs-lisp/bytecomp.el 2011-04-15 12:30:15 +0000
+++ lisp/emacs-lisp/bytecomp.el 2011-05-07 03:24:05 +0000
@@ -4173,6 +4173,7 @@
;; 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)
=== modified file 'lisp/emacs-lisp/eieio.el'
--- lisp/emacs-lisp/eieio.el 2011-05-05 03:42:09 +0000
+++ lisp/emacs-lisp/eieio.el 2011-05-07 03:56:24 +0000
@@ -420,6 +420,7 @@
(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 @@
;;; 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 +1160,21 @@
`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 +1264,6 @@
(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 +1299,17 @@
(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)
+ (args (if (consp arg1)
(cons (car arg1) (cdr params))
- params)
- ,@(cdr args)))))
+ 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 +1329,11 @@
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
This bug report was last modified 14 years and 19 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.