diff options
| author | Stefan Monnier | 2011-05-07 01:03:49 -0300 |
|---|---|---|
| committer | Stefan Monnier | 2011-05-07 01:03:49 -0300 |
| commit | d1dc2cc2ce985d92e1d1309344eb49f7e3b29312 (patch) | |
| tree | ed54cb83c1e6d312810470ce77acb7789720f36c | |
| parent | 4d3fcc8e6025592929f95ac1e36b9313ffa6d4f0 (diff) | |
| download | emacs-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/ChangeLog | 11 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 1 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio.el | 75 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-05-07 Glenn Morris <rgm@gnu.org> | 10 | 2011-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 @@ | |||
| 17 | 2011-05-06 Stefan Monnier <monnier@iro.umontreal.ca> | 26 | 2011-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 | ||
| 22 | 2011-05-06 Glenn Morris <rgm@gnu.org> | 31 | 2011-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. |
| 424 | SLOTS are the slots residing in that class definition, and options or | 425 | SLOTS are the slots residing in that class definition, and options or |
| 425 | documentation OPTIONS-AND-DOC is the toplevel documentation for this class. | 426 | documentation 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. | ||
| 1148 | More specifically, it has no side-effects at all when the new function | ||
| 1149 | definition 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. |
| 1144 | DOC-STRING is the base documentation for this class. A generic | 1156 | 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 | |||
| 1147 | `defgeneric' for you. With this implementation the ARGS are | 1159 | `defgeneric' for you. With this implementation the ARGS are |
| 1148 | currently ignored. You can use `defgeneric' to apply specialized | 1160 | currently ignored. You can use `defgeneric' to apply specialized |
| 1149 | top level documentation to a method." | 1161 | top 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. |
| 1262 | It will leave the original generic function in place, | 1268 | It 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 |