1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 22:41:06 -08:00

Add online-help support to describe types

* lisp/help-fns.el (describe-symbol-backends): Move to help-mode.el.
(describe-symbol): Improve the selection of default.

* lisp/help-mode.el: Require cl-lib.
(describe-symbol-backends): Move from help-fns.el.
(help-make-xrefs): Use it.

* lisp/emacs-lisp/cl-extra.el (describe-symbol-backends): Add entry
for types.
(cl--typedef-regexp): New const.
(find-function-regexp-alist): Add entry for types.
(cl-help-type, cl-type-definition): New buttons.
(cl-find-class): New function.
(cl-describe-type): New command.
(cl--describe-class, cl--describe-class-slot)
(cl--describe-class-slots): New functions, moved from eieio-opt.el.

* lisp/emacs-lisp/cl-generic.el (cl--generic-method-documentation)
(cl--generic-all-functions, cl--generic-specializers-apply-to-type-p):
New functions.  Moved from eieio-opt.el.
(cl--generic-class-parents): New function, extracted from
cl--generic-struct-specializers.
(cl--generic-struct-specializers): Use it.

* lisp/emacs-lisp/cl-macs.el (cl-defstruct): Use pcase-dolist.
Improve constructor's docstrings.
(cl-struct-unknown-slot): New error.
(cl-struct-slot-offset): Use it.

* lisp/emacs-lisp/cl-preloaded.el (cl-struct-define): Record the type
definition in current-load-list.

* lisp/emacs-lisp/eieio-core.el (eieio--known-slot-names): New var.
(eieio--add-new-slot): Set it.
(eieio-defclass-internal): Use new name for current-load-list.
(eieio-oref): Add compiler-macro to warn about unknown slots.
* lisp/emacs-lisp/eieio.el (defclass): Update eieio--known-slot-names
as compile-time as well.  Improve constructor docstrings.

* lisp/emacs-lisp/eieio-opt.el (eieio-help-class)
(eieio--help-print-slot, eieio-help-class-slots): Move to cl-extra.el.
(eieio-class-def): Remove button.
(eieio-help-constructor): Use new name for load-history element.
(eieio--specializers-apply-to-class-p, eieio-all-generic-functions)
(eieio-method-documentation): Move to cl-generic.el.
(eieio-display-method-list): Use new names.

* lisp/emacs-lisp/lisp-mode.el (lisp-imenu-generic-expression):
Add "define-linline".
(lisp-fdefs): Remove "defsubst".
(el-fdefs): Add "defsubst", "cl-defsubst", and "define-linline".

* lisp/emacs-lisp/macroexp.el (macroexp--warned): New var.
(macroexp--warn-and-return): Use it to avoid inf-loops.
Add `compile-only' argument.
This commit is contained in:
Stefan Monnier 2015-07-07 02:14:16 -04:00
parent 287bce9888
commit 59b5723c9b
11 changed files with 358 additions and 286 deletions

View file

@ -95,6 +95,7 @@
;; usually be simplified, or even completely skipped.
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'cl-macs)) ;For cl--find-class.
(eval-when-compile (require 'pcase))
(cl-defstruct (cl--generic-generalizer
@ -883,6 +884,55 @@ Can only be used from within the lexical body of a primary or around method."
(insert (substitute-command-keys ".\n"))))
(insert "\n" (or (nth 2 info) "Undocumented") "\n\n")))))))
(defun cl--generic-specializers-apply-to-type-p (specializers type)
"Return non-nil if a method with SPECIALIZERS applies to TYPE."
(let ((applies nil))
(dolist (specializer specializers)
(if (memq (car-safe specializer) '(subclass eieio--static))
(setq specializer (nth 1 specializer)))
;; Don't include the methods that are "too generic", such as those
;; applying to `eieio-default-superclass'.
(and (not (memq specializer '(t eieio-default-superclass)))
(or (equal type specializer)
(when (symbolp specializer)
(let ((sclass (cl--find-class specializer))
(tclass (cl--find-class type)))
(when (and sclass tclass)
(member specializer (cl--generic-class-parents tclass))))))
(setq applies t)))
applies))
(defun cl--generic-all-functions (&optional type)
"Return a list of all generic functions.
Optional TYPE argument returns only those functions that contain
methods for TYPE."
(let ((l nil))
(mapatoms
(lambda (symbol)
(let ((generic (and (fboundp symbol) (cl--generic symbol))))
(and generic
(catch 'found
(if (null type) (throw 'found t))
(dolist (method (cl--generic-method-table generic))
(if (cl--generic-specializers-apply-to-type-p
(cl--generic-method-specializers method) type)
(throw 'found t))))
(push symbol l)))))
l))
(defun cl--generic-method-documentation (function type)
"Return info for all methods of FUNCTION (a symbol) applicable to TYPE.
The value returned is a list of elements of the form
\(QUALIFIERS ARGS DOC)."
(let ((generic (cl--generic function))
(docs ()))
(when generic
(dolist (method (cl--generic-method-table generic))
(when (cl--generic-specializers-apply-to-type-p
(cl--generic-method-specializers method) type)
(push (cl--generic-method-info method) docs))))
docs))
;;; Support for (head <val>) specializers.
;; For both the `eql' and the `head' specializers, the dispatch
@ -958,19 +1008,22 @@ Can only be used from within the lexical body of a primary or around method."
(if (eq (symbol-function tag) :quick-object-witness-check)
tag))))
(defun cl--generic-class-parents (class)
(let ((parents ())
(classes (list class)))
;; BFS precedence. FIXME: Use a topological sort.
(while (let ((class (pop classes)))
(cl-pushnew (cl--class-name class) parents)
(setq classes
(append classes
(cl--class-parents class)))))
(nreverse parents)))
(defun cl--generic-struct-specializers (tag)
(and (symbolp tag) (boundp tag)
(let ((class (symbol-value tag)))
(when (cl-typep class 'cl-structure-class)
(let ((types ())
(classes (list class)))
;; BFS precedence.
(while (let ((class (pop classes)))
(push (cl--class-name class) types)
(setq classes
(append classes
(cl--class-parents class)))))
(nreverse types))))))
(cl--generic-class-parents class)))))
(defconst cl--generic-struct-generalizer
(cl-generic-make-generalizer