diff options
| author | Chong Yidong | 2009-10-11 02:19:27 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-10-11 02:19:27 +0000 |
| commit | 67868d2626adebe29ed8647484b1640de3896ae3 (patch) | |
| tree | 8a6b4f1aefe9d61778a872d6f72e35b9eddc83fb | |
| parent | 5feb0b73eb5d589faf5c961eac86e8dbef67b3ba (diff) | |
| download | emacs-67868d2626adebe29ed8647484b1640de3896ae3.tar.gz emacs-67868d2626adebe29ed8647484b1640de3896ae3.zip | |
* emacs-lisp/eieio.el: Avoid requiring cl at runtime.
(eieio-defclass): Apply deftype handler and setf-method properties
directly.
(eieio-add-new-slot): Avoid union function from cl library.
(eieio--typep): New function.
(eieio-perform-slot-validation): Use it.
| -rw-r--r-- | lisp/ChangeLog | 9 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio.el | 154 |
2 files changed, 113 insertions, 50 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 06eb7c9acb4..523431ede66 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2009-10-11 Chong Yidong <cyd@stupidchicken.com> | ||
| 2 | |||
| 3 | * emacs-lisp/eieio.el: Avoid requiring cl at runtime. | ||
| 4 | (eieio-defclass): Apply deftype handler and setf-method properties | ||
| 5 | directly. | ||
| 6 | (eieio-add-new-slot): Avoid union function from cl library. | ||
| 7 | (eieio--typep): New function. | ||
| 8 | (eieio-perform-slot-validation): Use it. | ||
| 9 | |||
| 1 | 2009-10-10 Karl Fogel <kfogel@red-bean.com> | 10 | 2009-10-10 Karl Fogel <kfogel@red-bean.com> |
| 2 | 11 | ||
| 3 | * bookmark.el: (bookmark-yank-word, bookmark-insert-current-bookmark): | 12 | * bookmark.el: (bookmark-yank-word, bookmark-insert-current-bookmark): |
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index d47973e61b9..b2d97074f9f 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el | |||
| @@ -40,8 +40,9 @@ | |||
| 40 | 40 | ||
| 41 | ;;; Code: | 41 | ;;; Code: |
| 42 | 42 | ||
| 43 | (require 'cl) | 43 | (eval-when-compile |
| 44 | (eval-when-compile (require 'eieio-comp)) | 44 | (require 'cl) |
| 45 | (require 'eieio-comp)) | ||
| 45 | 46 | ||
| 46 | (defvar eieio-version "1.2" | 47 | (defvar eieio-version "1.2" |
| 47 | "Current version of EIEIO.") | 48 | "Current version of EIEIO.") |
| @@ -538,11 +539,11 @@ See `defclass' for more information." | |||
| 538 | ;; "cl" uses this technique to specify symbols with specific typep | 539 | ;; "cl" uses this technique to specify symbols with specific typep |
| 539 | ;; test, so we can let typep have the CLOS documented behavior | 540 | ;; test, so we can let typep have the CLOS documented behavior |
| 540 | ;; while keeping our above predicate clean. | 541 | ;; while keeping our above predicate clean. |
| 541 | (eval `(deftype ,cname () | ||
| 542 | '(satisfies | ||
| 543 | ,(intern (concat (symbol-name cname) "-child-p"))))) | ||
| 544 | 542 | ||
| 545 | ) | 543 | ;; It would be cleaner to use `defsetf' here, but that requires cl |
| 544 | ;; at runtime. | ||
| 545 | (put cname 'cl-deftype-handler | ||
| 546 | (list 'lambda () `(list 'satisfies (quote ,csym))))) | ||
| 546 | 547 | ||
| 547 | ;; before adding new slots, lets add all the methods and classes | 548 | ;; before adding new slots, lets add all the methods and classes |
| 548 | ;; in from the parent class | 549 | ;; in from the parent class |
| @@ -657,17 +658,21 @@ See `defclass' for more information." | |||
| 657 | (list 'if (list 'slot-boundp 'this (list 'quote name)) | 658 | (list 'if (list 'slot-boundp 'this (list 'quote name)) |
| 658 | (list 'eieio-oref 'this (list 'quote name)) | 659 | (list 'eieio-oref 'this (list 'quote name)) |
| 659 | ;; Else - Some error? nil? | 660 | ;; Else - Some error? nil? |
| 660 | nil | 661 | nil))) |
| 661 | ))) | 662 | |
| 662 | ;; Thanks Pascal Bourguignon <pjb@informatimago.com> | 663 | ;; Provide a setf method. It would be cleaner to use |
| 663 | ;; For this complex macro. | 664 | ;; defsetf, but that would require CL at runtime. |
| 664 | (eval (macroexpand | 665 | (put acces 'setf-method |
| 665 | (list 'defsetf acces '(widget) '(store) | 666 | `(lambda (widget) |
| 666 | (list 'list ''eieio-oset 'widget | 667 | (let* ((--widget-sym-- (make-symbol "--widget--")) |
| 667 | (list 'quote (list 'quote name)) 'store)))) | 668 | (--store-sym-- (make-symbol "--store--"))) |
| 668 | ;;`(defsetf ,acces (widget) (store) (eieio-oset widget ',cname store)) | 669 | (list |
| 669 | ) | 670 | (list --widget-sym--) |
| 670 | ) | 671 | (list widget) |
| 672 | (list --store-sym--) | ||
| 673 | (list 'eieio-oset --widget-sym-- '',name --store-sym--) | ||
| 674 | (list 'getfoo --widget-sym--))))))) | ||
| 675 | |||
| 671 | ;; If a writer is defined, then create a generic method of that | 676 | ;; If a writer is defined, then create a generic method of that |
| 672 | ;; name whose purpose is to set the value of the slot. | 677 | ;; name whose purpose is to set the value of the slot. |
| 673 | (if writer | 678 | (if writer |
| @@ -895,15 +900,19 @@ if default value is nil." | |||
| 895 | ;; End original PLN | 900 | ;; End original PLN |
| 896 | 901 | ||
| 897 | ;; PLN Tue Jun 26 11:57:06 2007 : | 902 | ;; PLN Tue Jun 26 11:57:06 2007 : |
| 898 | ;; We do a non redundant combination of ancient | 903 | ;; Do a non redundant combination of ancient custom |
| 899 | ;; custom groups and new ones using the common lisp | 904 | ;; groups and new ones. |
| 900 | ;; `union' method. | ||
| 901 | (when custg | 905 | (when custg |
| 902 | (let ((where-groups | 906 | (let* ((groups |
| 903 | (nthcdr num (aref newc class-public-custom-group)))) | 907 | (nthcdr num (aref newc class-public-custom-group))) |
| 904 | (setcar where-groups | 908 | (list1 (car groups)) |
| 905 | (union (car where-groups) | 909 | (list2 (if (listp custg) custg (list custg)))) |
| 906 | (if (listp custg) custg (list custg)))))) | 910 | (if (< (length list1) (length list2)) |
| 911 | (setq list1 (prog1 list2 (setq list2 list1)))) | ||
| 912 | (dolist (elt list2) | ||
| 913 | (unless (memq elt list1) | ||
| 914 | (push elt list1))) | ||
| 915 | (setcar groups list1))) | ||
| 907 | ;; End PLN | 916 | ;; End PLN |
| 908 | 917 | ||
| 909 | ;; PLN Mon Jun 25 22:44:34 2007 : If a new cust is | 918 | ;; PLN Mon Jun 25 22:44:34 2007 : If a new cust is |
| @@ -990,16 +999,19 @@ if default value is nil." | |||
| 990 | (if (not (eq prot super-prot)) | 999 | (if (not (eq prot super-prot)) |
| 991 | (error "Child slot protection `%s' does not match inherited protection `%s' for `%s'" | 1000 | (error "Child slot protection `%s' does not match inherited protection `%s' for `%s'" |
| 992 | prot super-prot a))) | 1001 | prot super-prot a))) |
| 993 | ;; We do a non redundant combination of ancient | 1002 | ;; Do a non redundant combination of ancient custom groups |
| 994 | ;; custom groups and new ones using the common lisp | 1003 | ;; and new ones. |
| 995 | ;; `union' method. | ||
| 996 | (when custg | 1004 | (when custg |
| 997 | (let ((where-groups | 1005 | (let* ((groups |
| 998 | (nthcdr num (aref newc class-class-allocation-custom-group)))) | 1006 | (nthcdr num (aref newc class-class-allocation-custom-group))) |
| 999 | (setcar where-groups | 1007 | (list1 (car groups)) |
| 1000 | (union (car where-groups) | 1008 | (list2 (if (listp custg) custg (list custg)))) |
| 1001 | (if (listp custg) custg (list custg)))))) | 1009 | (if (< (length list1) (length list2)) |
| 1002 | ;; End PLN | 1010 | (setq list1 (prog1 list2 (setq list2 list1)))) |
| 1011 | (dolist (elt list2) | ||
| 1012 | (unless (memq elt list1) | ||
| 1013 | (push elt list1))) | ||
| 1014 | (setcar groups list1))) | ||
| 1003 | 1015 | ||
| 1004 | ;; PLN Sat Jun 30 17:24:42 2007 : when a new | 1016 | ;; PLN Sat Jun 30 17:24:42 2007 : when a new |
| 1005 | ;; doc is specified, simply replaces the old one. | 1017 | ;; doc is specified, simply replaces the old one. |
| @@ -1352,13 +1364,57 @@ Summary: | |||
| 1352 | method) | 1364 | method) |
| 1353 | 1365 | ||
| 1354 | ;;; Slot type validation | 1366 | ;;; Slot type validation |
| 1355 | ;; | 1367 | |
| 1368 | ;; This is a hideous hack for replacing `typep' from cl-macs, to avoid | ||
| 1369 | ;; requiring the CL library at run-time. It can be eliminated if/when | ||
| 1370 | ;; `typep' is merged into Emacs core. | ||
| 1371 | (defun eieio--typep (val type) | ||
| 1372 | (if (symbolp type) | ||
| 1373 | (cond ((get type 'cl-deftype-handler) | ||
| 1374 | (eieio--typep val (funcall (get type 'cl-deftype-handler)))) | ||
| 1375 | ((eq type t) t) | ||
| 1376 | ((eq type 'null) (null val)) | ||
| 1377 | ((eq type 'atom) (atom val)) | ||
| 1378 | ((eq type 'float) (and (numberp val) (not (integerp val)))) | ||
| 1379 | ((eq type 'real) (numberp val)) | ||
| 1380 | ((eq type 'fixnum) (integerp val)) | ||
| 1381 | ((memq type '(character string-char)) (characterp val)) | ||
| 1382 | (t | ||
| 1383 | (let* ((name (symbol-name type)) | ||
| 1384 | (namep (intern (concat name "p")))) | ||
| 1385 | (if (fboundp namep) | ||
| 1386 | (funcall `(lambda () (,namep val))) | ||
| 1387 | (funcall `(lambda () | ||
| 1388 | (,(intern (concat name "-p")) val))))))) | ||
| 1389 | (cond ((get (car type) 'cl-deftype-handler) | ||
| 1390 | (eieio--typep val (apply (get (car type) 'cl-deftype-handler) | ||
| 1391 | (cdr type)))) | ||
| 1392 | ((memq (car type) '(integer float real number)) | ||
| 1393 | (and (eieio--typep val (car type)) | ||
| 1394 | (or (memq (cadr type) '(* nil)) | ||
| 1395 | (if (consp (cadr type)) | ||
| 1396 | (> val (car (cadr type))) | ||
| 1397 | (>= val (cadr type)))) | ||
| 1398 | (or (memq (caddr type) '(* nil)) | ||
| 1399 | (if (consp (car (cddr type))) | ||
| 1400 | (< val (caar (cddr type))) | ||
| 1401 | (<= val (car (cddr type))))))) | ||
| 1402 | ((memq (car type) '(and or not)) | ||
| 1403 | (eval (cons (car type) | ||
| 1404 | (mapcar (lambda (x) | ||
| 1405 | `(eieio--typep (quote ,val) (quote ,x))) | ||
| 1406 | (cdr type))))) | ||
| 1407 | ((memq (car type) '(member member*)) | ||
| 1408 | (memql val (cdr type))) | ||
| 1409 | ((eq (car type) 'satisfies) | ||
| 1410 | (funcall `(lambda () (,(cadr type) val)))) | ||
| 1411 | (t (error "Bad type spec: %s" type))))) | ||
| 1412 | |||
| 1356 | (defun eieio-perform-slot-validation (spec value) | 1413 | (defun eieio-perform-slot-validation (spec value) |
| 1357 | "Return non-nil if SPEC does not match VALUE." | 1414 | "Return non-nil if SPEC does not match VALUE." |
| 1358 | ;; typep is in cl-macs | ||
| 1359 | (or (eq spec t) ; t always passes | 1415 | (or (eq spec t) ; t always passes |
| 1360 | (eq value eieio-unbound) ; unbound always passes | 1416 | (eq value eieio-unbound) ; unbound always passes |
| 1361 | (typep value spec))) | 1417 | (eieio--typep value spec))) |
| 1362 | 1418 | ||
| 1363 | (defun eieio-validate-slot-value (class slot-idx value slot) | 1419 | (defun eieio-validate-slot-value (class slot-idx value slot) |
| 1364 | "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid. | 1420 | "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid. |
| @@ -2383,15 +2439,17 @@ This is usually a symbol that starts with `:'." | |||
| 2383 | 2439 | ||
| 2384 | ;; The below setf method was written by Arnd Kohrs <kohrs@acm.org> | 2440 | ;; The below setf method was written by Arnd Kohrs <kohrs@acm.org> |
| 2385 | (define-setf-method oref (obj slot) | 2441 | (define-setf-method oref (obj slot) |
| 2386 | (let ((obj-temp (gensym)) | 2442 | (with-no-warnings |
| 2387 | (slot-temp (gensym)) | 2443 | (require 'cl) |
| 2388 | (store-temp (gensym))) | 2444 | (let ((obj-temp (gensym)) |
| 2389 | (list (list obj-temp slot-temp) | 2445 | (slot-temp (gensym)) |
| 2390 | (list obj `(quote ,slot)) | 2446 | (store-temp (gensym))) |
| 2391 | (list store-temp) | 2447 | (list (list obj-temp slot-temp) |
| 2392 | (list 'set-slot-value obj-temp slot-temp | 2448 | (list obj `(quote ,slot)) |
| 2393 | store-temp) | 2449 | (list store-temp) |
| 2394 | (list 'slot-value obj-temp slot-temp)))) | 2450 | (list 'set-slot-value obj-temp slot-temp |
| 2451 | store-temp) | ||
| 2452 | (list 'slot-value obj-temp slot-temp))))) | ||
| 2395 | 2453 | ||
| 2396 | 2454 | ||
| 2397 | ;;; | 2455 | ;;; |
| @@ -2768,9 +2826,5 @@ Optional argument NOESCAPE is passed to `prin1-to-string' when appropriate." | |||
| 2768 | 2826 | ||
| 2769 | (provide 'eieio) | 2827 | (provide 'eieio) |
| 2770 | 2828 | ||
| 2771 | ;; Local variables: | ||
| 2772 | ;; byte-compile-warnings: (not cl-functions) | ||
| 2773 | ;; End: | ||
| 2774 | |||
| 2775 | ;; arch-tag: c1aeab9c-2938-41a3-842b-1a38bd26e9f2 | 2829 | ;; arch-tag: c1aeab9c-2938-41a3-842b-1a38bd26e9f2 |
| 2776 | ;;; eieio ends here | 2830 | ;;; eieio ends here |