aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-05-07 01:03:49 -0300
committerStefan Monnier2011-05-07 01:03:49 -0300
commitd1dc2cc2ce985d92e1d1309344eb49f7e3b29312 (patch)
treeed54cb83c1e6d312810470ce77acb7789720f36c
parent4d3fcc8e6025592929f95ac1e36b9313ffa6d4f0 (diff)
downloademacs-d1dc2cc2ce985d92e1d1309344eb49f7e3b29312.tar.gz
emacs-d1dc2cc2ce985d92e1d1309344eb49f7e3b29312.zip
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
-rw-r--r--lisp/ChangeLog11
-rw-r--r--lisp/emacs-lisp/bytecomp.el1
-rw-r--r--lisp/emacs-lisp/eieio.el75
3 files changed, 54 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 026d5b78bbe..3cf8e13614d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,12 @@
12011-05-07 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Make bytecomp.el understand that defmethod defines funs (bug#8631).
4 * emacs-lisp/eieio.el (eieio--defalias, eieio--defgeneric-init-form):
5 New functions.
6 (defgeneric, eieio--defmethod): Use them.
7 (eieio-defgeneric): Remove.
8 (defmethod): Call defgeneric in a way visible to the byte-compiler.
9
12011-05-07 Glenn Morris <rgm@gnu.org> 102011-05-07 Glenn Morris <rgm@gnu.org>
2 11
3 * calendar/timeclock.el (timeclock-log-data): Remove unused local. 12 * calendar/timeclock.el (timeclock-log-data): Remove unused local.
@@ -17,7 +26,7 @@
172011-05-06 Stefan Monnier <monnier@iro.umontreal.ca> 262011-05-06 Stefan Monnier <monnier@iro.umontreal.ca>
18 27
19 * lpr.el (print-region-1): Echo lpr-program's output, so error messages 28 * lpr.el (print-region-1): Echo lpr-program's output, so error messages
20 and warnings are not silently discarded (e.g. use "-d" instead of "-P"). 29 and warnings are not silently discarded (e.g. use -d instead of -P).
21 30
222011-05-06 Glenn Morris <rgm@gnu.org> 312011-05-06 Glenn Morris <rgm@gnu.org>
23 32
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 4c28d816f60..6ca8eed8ac6 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -4173,6 +4173,7 @@ binding slots have been popped."
4173 4173
4174;; Compile normally, but deal with warnings for the function being defined. 4174;; Compile normally, but deal with warnings for the function being defined.
4175(put 'defalias 'byte-hunk-handler 'byte-compile-file-form-defalias) 4175(put 'defalias 'byte-hunk-handler 'byte-compile-file-form-defalias)
4176;; Used for eieio--defalias as well.
4176(defun byte-compile-file-form-defalias (form) 4177(defun byte-compile-file-form-defalias (form)
4177 (if (and (consp (cdr form)) (consp (nth 1 form)) 4178 (if (and (consp (cdr form)) (consp (nth 1 form))
4178 (eq (car (nth 1 form)) 'quote) 4179 (eq (car (nth 1 form)) 'quote)
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 268698e4128..d71213bfac8 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -420,6 +420,7 @@ It creates an autoload function for CNAME's constructor."
420 (load-library (car (cdr (symbol-function cname)))))) 420 (load-library (car (cdr (symbol-function cname))))))
421 421
422(defun eieio-defclass (cname superclasses slots options-and-doc) 422(defun eieio-defclass (cname superclasses slots options-and-doc)
423 ;; FIXME: Most of this should be moved to the `defclass' macro.
423 "Define CNAME as a new subclass of SUPERCLASSES. 424 "Define CNAME as a new subclass of SUPERCLASSES.
424SLOTS are the slots residing in that class definition, and options or 425SLOTS are the slots residing in that class definition, and options or
425documentation OPTIONS-AND-DOC is the toplevel documentation for this class. 426documentation OPTIONS-AND-DOC is the toplevel documentation for this class.
@@ -1139,6 +1140,17 @@ a string."
1139 1140
1140;;; CLOS methods and generics 1141;;; CLOS methods and generics
1141;; 1142;;
1143
1144(put 'eieio--defalias 'byte-hunk-handler
1145 #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
1146(defun eieio--defalias (name body)
1147 "Like `defalias', but with less side-effects.
1148More specifically, it has no side-effects at all when the new function
1149definition is the same (`eq') as the old one."
1150 (unless (and (fboundp name)
1151 (eq (symbol-function name) body))
1152 (defalias name body)))
1153
1142(defmacro defgeneric (method args &optional doc-string) 1154(defmacro defgeneric (method args &optional doc-string)
1143 "Create a generic function METHOD. 1155 "Create a generic function METHOD.
1144DOC-STRING is the base documentation for this class. A generic 1156DOC-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
1147`defgeneric' for you. With this implementation the ARGS are 1159`defgeneric' for you. With this implementation the ARGS are
1148currently ignored. You can use `defgeneric' to apply specialized 1160currently ignored. You can use `defgeneric' to apply specialized
1149top level documentation to a method." 1161top level documentation to a method."
1150 `(eieio-defgeneric (quote ,method) ,doc-string)) 1162 `(eieio--defalias ',method
1163 (eieio--defgeneric-init-form ',method ,doc-string)))
1164
1165(defun eieio--defgeneric-init-form (method doc-string)
1166 "Form to use for the initial definition of a generic."
1167 (cond
1168 ((or (not (fboundp method))
1169 (eq 'autoload (car-safe (symbol-function method))))
1170 ;; Make sure the method tables are installed.
1171 (eieiomt-install method)
1172 ;; Construct the actual body of this function.
1173 (eieio-defgeneric-form method doc-string))
1174 ((generic-p method) (symbol-function method)) ;Leave it as-is.
1175 (t (error "You cannot create a generic/method over an existing symbol: %s"
1176 method))))
1151 1177
1152(defun eieio-defgeneric-form (method doc-string) 1178(defun eieio-defgeneric-form (method doc-string)
1153 "The lambda form that would be used as the function defined on METHOD. 1179 "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."
1237 (cdr entry) 1263 (cdr entry)
1238 )))) 1264 ))))
1239 1265
1240(defun eieio-defgeneric (method doc-string)
1241 "Engine part to `defgeneric' macro defining METHOD with DOC-STRING."
1242 (if (and (fboundp method) (not (generic-p method))
1243 (or (byte-code-function-p (symbol-function method))
1244 (not (eq 'autoload (car (symbol-function method)))))
1245 )
1246 (error "You cannot create a generic/method over an existing symbol: %s"
1247 method))
1248 ;; Don't do this over and over.
1249 (unless (fboundp 'method)
1250 ;; This defun tells emacs where the first definition of this
1251 ;; method is defined.
1252 `(defun ,method nil)
1253 ;; Make sure the method tables are installed.
1254 (eieiomt-install method)
1255 ;; Apply the actual body of this function.
1256 (fset method (eieio-defgeneric-form method doc-string))
1257 ;; Return the method
1258 'method))
1259
1260(defun eieio-unbind-method-implementations (method) 1266(defun eieio-unbind-method-implementations (method)
1261 "Make the generic method METHOD have no implementations. 1267 "Make the generic method METHOD have no implementations.
1262It will leave the original generic function in place, 1268It will leave the original generic function in place,
@@ -1292,12 +1298,17 @@ Summary:
1292 (let* ((key (if (keywordp (car args)) (pop args))) 1298 (let* ((key (if (keywordp (car args)) (pop args)))
1293 (params (car args)) 1299 (params (car args))
1294 (arg1 (car params)) 1300 (arg1 (car params))
1295 (class (if (consp arg1) (nth 1 arg1)))) 1301 (args (if (consp arg1)
1296 `(eieio--defmethod ',method ',key ',class 1302 (cons (car arg1) (cdr params))
1297 (lambda ,(if (consp arg1) 1303 params))
1298 (cons (car arg1) (cdr params)) 1304 (class (if (consp arg1) (nth 1 arg1)))
1299 params) 1305 (code `(lambda ,args ,@(cdr args))))
1300 ,@(cdr args))))) 1306 `(progn
1307 ;; Make sure there is a generic and the byte-compiler sees it.
1308 (defgeneric ,method ,args
1309 ,(or (documentation code)
1310 (format "Generically created method `%s'." method)))
1311 (eieio--defmethod ',method ',key ',class ',code))))
1301 1312
1302(defun eieio--defmethod (method kind argclass code) 1313(defun eieio--defmethod (method kind argclass code)
1303 "Work part of the `defmethod' macro defining METHOD with ARGS." 1314 "Work part of the `defmethod' macro defining METHOD with ARGS."
@@ -1317,11 +1328,11 @@ Summary:
1317 method-static) 1328 method-static)
1318 ;; Primary key 1329 ;; Primary key
1319 (t method-primary)))) 1330 (t method-primary))))
1320 ;; make sure there is a generic 1331 ;; Make sure there is a generic (when called from defclass).
1321 (eieio-defgeneric 1332 (eieio--defalias
1322 method 1333 method (eieio--defgeneric-init-form
1323 (or (documentation code) 1334 method (or (documentation code)
1324 (format "Generically created method `%s'." method))) 1335 (format "Generically created method `%s'." method))))
1325 ;; create symbol for property to bind to. If the first arg is of 1336 ;; create symbol for property to bind to. If the first arg is of
1326 ;; the form (varname vartype) and `vartype' is a class, then 1337 ;; the form (varname vartype) and `vartype' is a class, then
1327 ;; that class will be the type symbol. If not, then it will fall 1338 ;; that class will be the type symbol. If not, then it will fall