oclosure.el (accessor): New type

* lisp/emacs-lisp/oclosure.el (accessor): New (OClosure) type.
(oclosure-define): Mark the accessor functions
as being of type `accessor`.
(oclosure--accessor-cl-print, oclosure--accessor-docstring): New functions.

* src/doc.c (store_function_docstring): Improve message and fix check.
* lisp/simple.el (function-docstring) <accessor>: New method.
* lisp/emacs-lisp/cl-print.el (cl-print-object) <accessor>: New method.
This commit is contained in:
Stefan Monnier 2021-12-22 10:06:17 -05:00
parent 230617c90c
commit f44ee8cd53
5 changed files with 45 additions and 8 deletions

View file

@ -229,6 +229,10 @@ into a button whose action shows the function's disassembly.")
;; FIXME: η-reduce!
(advice--cl-print-object object stream))
(cl-defmethod cl-print-object ((object accessor) stream)
;; FIXME: η-reduce!
(oclosure--accessor-cl-print object stream))
(cl-defmethod cl-print-object ((object cl-structure-object) stream)
(if (and cl-print--depth (natnump print-level)
(> cl-print--depth print-level))

View file

@ -210,7 +210,7 @@ This function is modeled after `minibuffer-complete-and-exit'."
(if doexit (exit-minibuffer))))
(defun crm--choose-completion-string (choice buffer base-position
&rest ignored)
&rest _)
"Completion string chooser for `completing-read-multiple'.
This is called from `choose-completion-string-functions'.
It replaces the string that is currently being completed, without

View file

@ -38,6 +38,8 @@
;; simply has an additional `docstring' slot.
;; - commands: this could be a subtype of documented functions, which simply
;; has an additional `interactive-form' slot.
;; - auto-generate docstrings for slot accessors instead of storing them
;; in the accessor itself?
;;; Code:
@ -55,6 +57,11 @@
;; store-conversion is indispensable, so if we want to avoid store-conversion
;; we'd have to disallow such capture.
;; FIXME:
;; - Snarf-documentation leaves bogus fixnums in place in`create-file-buffer'.
;; - `oclosure-cl-defun', `oclosure-cl-defsubst', `oclosure-defsubst', `oclosure-define-inline'?
;; - Use accessor in cl-defstruct
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'subr-x)) ;For `named-let'.
@ -186,12 +193,13 @@
(when (gethash slot it)
(error "Duplicate slot name: %S" slot))
(setf (gethash slot it) i)
;; Always use a double hyphen: if the user wants to
;; make it public, it can do so with an alias.
`(defun ,(intern (format "%S--%S" name slot)) (oclosure)
,(format "Return slot `%S' of OClosure, of type `%S'."
slot name)
(oclosure-get oclosure ,i))))
;; Always use a double hyphen: if users wants to
;; make it public, they can do so with an alias.
;; FIXME: Use a copier!
`(defalias ',(intern (format "%S--%S" name slot))
(oclosure-lambda accessor ((type ',name) (slot ',slot))
(oclosure)
(oclosure-get oclosure ,i)))))
slotdescs))
,@(oclosure--defstruct-make-copiers copiers slots name))))
@ -315,5 +323,22 @@
(and (eq :type (car-safe first-var))
(cdr first-var))))))
(oclosure-define accessor
"OClosure to access the field of an object."
type slot)
(defun oclosure--accessor-cl-print (object stream)
(princ "#f(accessor " stream)
(prin1 (accessor--type object) stream)
(princ "." stream)
(prin1 (accessor--slot object) stream)
(princ ")" stream))
(defun oclosure--accessor-docstring (f)
(format "Access slot \"%S\" of OBJ of type `%S'.
\(fn OBJ)"
(accessor--slot f) (accessor--type f)))
(provide 'oclosure)
;;; oclosure.el ends here

View file

@ -2348,6 +2348,10 @@ FUNCTION is expected to be a function value rather than, say, a mere symbol."
doc)))
(_ (signal 'invalid-function (list function))))))
(cl-defmethod function-docstring ((function accessor))
;; FIXME: η-reduce!
(oclosure--accessor-docstring function))
(cl-defgeneric interactive-form (cmd &optional original-name)
"Return the interactive form of CMD or nil if none.
If CMD is not a command, the return value is nil.

View file

@ -469,11 +469,15 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset)
/* Don't overwrite a non-docstring value placed there,
* such as is used in FCRs. */
&& (FIXNUMP (AREF (fun, COMPILED_DOC_STRING))
|| STRINGP (AREF (fun, COMPILED_DOC_STRING))
|| CONSP (AREF (fun, COMPILED_DOC_STRING))))
ASET (fun, COMPILED_DOC_STRING, make_fixnum (offset));
else
{
AUTO_STRING (format, "No docstring slot for %s");
AUTO_STRING (format,
(PVSIZE (fun) > COMPILED_DOC_STRING
? "Docstring slot busy for %s"
: "No docstring slot for %s"));
CALLN (Fmessage, format,
(SYMBOLP (obj)
? SYMBOL_NAME (obj)