aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2025-04-06 23:39:40 -0400
committerStefan Monnier2025-04-07 00:06:52 -0400
commit71afa12941ebbd6fa2c010064de01db681985279 (patch)
tree6a2c7f8ce3098583585672117f63f3435a53c7c7
parent308a5ff0f8997a287a496993d92f92c6a8a0f393 (diff)
downloademacs-71afa12941ebbd6fa2c010064de01db681985279.tar.gz
emacs-71afa12941ebbd6fa2c010064de01db681985279.zip
eieio: Emit compilation warnings a bit more thoroughly
We used to warn about unknown slots only in `oref`: add the same check for `oset` and `slot-boundp`. Similarly, we warned about obsolete name args only when calling the constructors: add the same check to `make-instance`. * lisp/emacs-lisp/eieio-core.el (eieio--check-slot-name): New function extracted from the compiler-macro of `eieio-oref`. (eieio-oref, eieio-oset): Use it. * lisp/emacs-lisp/eieio.el (slot-boundp): Use it. (eieio--constructor-macro): Add category to warning. (make-instance): Add compiler-macro to warn about obsolete name.
-rw-r--r--lisp/emacs-lisp/eieio-core.el22
-rw-r--r--lisp/emacs-lisp/eieio.el17
2 files changed, 28 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index f95fd65fa5c..b3a8698e31d 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -740,18 +740,19 @@ Argument FN is the function calling this verifier."
740 740
741;;; Get/Set slots in an object. 741;;; Get/Set slots in an object.
742 742
743(eval-and-compile
744 (defun eieio--check-slot-name (exp _obj slot &rest _)
745 (pcase slot
746 ((and (or `',name (and name (pred keywordp)))
747 (guard (not (eieio--known-slot-name-p name))))
748 (macroexp-warn-and-return
749 (format-message "Unknown slot `%S'" name)
750 exp nil 'compile-only name))
751 (_ exp))))
752
743(defun eieio-oref (obj slot) 753(defun eieio-oref (obj slot)
744 "Return the value in OBJ at SLOT in the object vector." 754 "Return the value in OBJ at SLOT in the object vector."
745 (declare (compiler-macro 755 (declare (compiler-macro eieio--check-slot-name)
746 (lambda (exp)
747 (ignore obj)
748 (pcase slot
749 ((and (or `',name (and name (pred keywordp)))
750 (guard (not (eieio--known-slot-name-p name))))
751 (macroexp-warn-and-return
752 (format-message "Unknown slot `%S'" name)
753 exp nil 'compile-only name))
754 (_ exp))))
755 ;; FIXME: Make it a gv-expander such that the hash-table lookup is 756 ;; FIXME: Make it a gv-expander such that the hash-table lookup is
756 ;; only performed once when used in `push' and friends? 757 ;; only performed once when used in `push' and friends?
757 (gv-setter eieio-oset)) 758 (gv-setter eieio-oset))
@@ -822,6 +823,7 @@ Fills in CLASS's SLOT with its default value."
822(defun eieio-oset (obj slot value) 823(defun eieio-oset (obj slot value)
823 "Do the work for the macro `oset'. 824 "Do the work for the macro `oset'.
824Fills in OBJ's SLOT with VALUE." 825Fills in OBJ's SLOT with VALUE."
826 (declare (compiler-macro eieio--check-slot-name))
825 (cl-check-type slot symbol) 827 (cl-check-type slot symbol)
826 (cond 828 (cond
827 ((cl-typep obj '(or eieio-object cl-structure-object)) 829 ((cl-typep obj '(or eieio-object cl-structure-object))
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 424baafc503..2a80c5d7c3e 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -304,7 +304,7 @@ and reference them using the function `class-option'."
304 ;; but hide it so we don't trigger indefinitely. 304 ;; but hide it so we don't trigger indefinitely.
305 `(,(car whole) (identity ,(car slots)) 305 `(,(car whole) (identity ,(car slots))
306 ,@(cdr slots)) 306 ,@(cdr slots))
307 nil nil (car slots)))) 307 '(obsolete eieio-constructor-name-arg) nil (car slots))))
308 308
309;;; Get/Set slots in an object. 309;;; Get/Set slots in an object.
310;; 310;;
@@ -554,6 +554,7 @@ after they are created."
554Setting a slot's value makes it bound. Calling `slot-makeunbound' will 554Setting a slot's value makes it bound. Calling `slot-makeunbound' will
555make a slot unbound. 555make a slot unbound.
556OBJECT can be an instance or a class." 556OBJECT can be an instance or a class."
557 (declare (compiler-macro eieio--check-slot-name))
557 ;; Skip typechecking while retrieving this value. 558 ;; Skip typechecking while retrieving this value.
558 (let ((eieio-skip-typecheck t)) 559 (let ((eieio-skip-typecheck t))
559 ;; Return nil if the magic symbol is in there. 560 ;; Return nil if the magic symbol is in there.
@@ -700,6 +701,20 @@ for each slot. For example:
700 701
701 (make-instance \\='foo :slot1 value1 :slotN valueN)") 702 (make-instance \\='foo :slot1 value1 :slotN valueN)")
702 703
704(put 'make-instance 'compiler-macro
705 (lambda (whole class &rest slots)
706 (if (or (null slots) (keywordp (car slots))
707 ;; Detect the second pass!
708 (eq 'identity (car-safe (car slots))))
709 whole
710 (macroexp-warn-and-return
711 (format "Obsolete name arg %S to `make-instance'" (car slots))
712 ;; Keep the name arg, for backward compatibility,
713 ;; but hide it so we don't trigger indefinitely.
714 `(,(car whole) ,class (identity ,(car slots))
715 ,@(cdr slots))
716 '(obsolete eieio-constructor-name-arg) nil (car slots)))))
717
703(define-obsolete-function-alias 'constructor #'make-instance "25.1") 718(define-obsolete-function-alias 'constructor #'make-instance "25.1")
704 719
705(cl-defmethod make-instance 720(cl-defmethod make-instance