From 5f7dd959c2ebe03caa316a83d52a6d6bba10f9c3 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 14 May 2022 04:06:32 +0200 Subject: [PATCH] Improve the *Help* output for compiler macros and the like * doc/lispref/functions.texi (Advice and Byte Code): New node. * lisp/help-fns.el (help-fns--compiler-macro): Also output data on other byte compilation things, and link to the manual (bug#23264). --- doc/lispref/elisp.texi | 1 + doc/lispref/functions.texi | 33 +++++++++++++++++++++++++++++++++ lisp/help-fns.el | 26 ++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index 426bb6d0176..968a2790e21 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -592,6 +592,7 @@ Advising Emacs Lisp Functions * Advising Named Functions:: Advising named functions. * Advice Combinators:: Ways to compose advice. * Porting Old Advice:: Adapting code using the old defadvice. +* Advice and Byte Code:: Not all functions can be advised. Macros diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 55bbf8fd5a2..df50a627aa3 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -1717,6 +1717,7 @@ ways to do it. The added function is also called a piece of @emph{advice}. * Advising Named Functions:: Advising named functions. * Advice Combinators:: Ways to compose advice. * Porting Old Advice:: Adapting code using the old defadvice. +* Advice and Byte Code:: Not all functions can be advised. @end menu @node Core Advising Primitives @@ -2138,6 +2139,38 @@ changing @code{ad-return-value}, whereas new @code{:after} advice cannot, so when porting such old @code{after} advice, you'll need to turn it into new @code{:around} or @code{:filter-return} advice instead. +@c This is its own node because we link to it from *Help* buffers. +@node Advice and Byte Code +@subsection Advice and Byte Code +@cindex compiler macros, advising +@cindex @code{byte-compile}, advising +@cindex @code{byte-optimizer}, advising + + Not all functions can be reliably advised. The byte compiler may +choose to replace a call to a function with a sequence of instructions +that doesn't include the function call to the function you were +interested in altering. + +This usually happens due to one of the three following mechanisms: + +@table @dfn +@item @code{byte-compile} properties +If function @var{symbol} has a @code{byte-compile} property, that +property will be used instead of @var{symbol}'s definition. +@xref{Compilation Functions}. + +@item @code{byte-optimize} properties +If function @var{symbol} has a @code{byte-compile} property, the byte +compiler may rewrite the function arguments, or decide to use a +different function altogether. + +@item compiler macros +Compiler macros are defined using a special @code{declare} form. This +tells the compiler to use the defined @dfn{expander} as an +optimization function, and it can return a new expression to use +instead of the function call. @xref{Declare Form}. +@end table + @node Obsolete Functions @section Declaring Functions Obsolete @cindex obsolete functions diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 927a4f0d2c4..d5f6a7b0bec 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -614,9 +614,18 @@ the C sources, too." menus)) (defun help-fns--compiler-macro (function) - (let ((handler (function-get function 'compiler-macro))) + (pcase-dolist (`(,type . ,handler) + (list (cons "compiler macro" + (function-get function 'compiler-macro)) + (cons "`byte-compile' property" + (function-get function 'byte-compile)) + (cons "byte-code optimizer" + (function-get function 'byte-optimizer)))) (when handler - (insert " This function has a compiler macro") + (if (bolp) + (insert " This function has a ") + (insert " and a ")) + (insert type) (if (symbolp handler) (progn (insert (format-message " `%s'" handler)) @@ -631,8 +640,17 @@ the C sources, too." (save-excursion (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) - (help-xref-button 1 'help-function-cmacro function lib))))) - (insert ".\n")))) + (help-xref-button 1 'help-function-cmacro function lib))))))) + (unless (bolp) + (insert ". See " + (buttonize "the manual" + (lambda (_) (info "(elisp)Advice and Byte Code"))) + " for details.\n") + (save-restriction + (let ((fill-prefix " ")) + (narrow-to-region (line-beginning-position -1) (point)) + (fill-region (point-min) (point-max))) + (goto-char (point-max))))) (defun help-fns--signature (function doc real-def real-function buffer) "Insert usage at point and return docstring. With highlighting." -- 2.39.2