comparison lisp/emacs-lisp/advice.el @ 8445:81f7b5d9b990

New handling of automatic advice activation that exploits modified built-in versions of `fset' and `defalias' which take care of this functionality directly: (ad-start-advice-on-load, ad-activate-on-definition) (ad-definition-hooks, ad-enable-definition-hooks, ad-defined-function) (ad-advised-definers, ad-advised-byte-compilers, byte-constant) (byte-constant-limit, byte-constant2, byte-fset) (ad-byte-code-fset-regexp): Variables deleted. (ad-activate-defined-function, ad-find-fset-in-byte-code) (ad-scan-byte-code-for-fsets, ad-advised-byte-code) (ad-recover-byte-code, ad-enable-definition-hooks) (ad-disable-definition-hooks): Functions deleted. (defun, defmacro, fset, defalias, define-function) (byte-compile-from-buffer, byte-compile-top-level): Removed `defadvice' for these functions. (ad-save-real-definitions): Removed saving of `byte-code'. (ad-activate-off): New dummy function. (ad-activate-on): New name for `ad-activate'. All calls changed. (ad-with-auto-activation-disabled): New macro prevents automatic advice activation. (ad-safe-fset): New function, used instead of `ad-real-fset'. (ad-compile-function): Disable automatic advice activation while compiling, because `byte-compile' uses `fset'. (ad-activate-on): Renamed from `ad-activate'. Avoid recursive calls. (ad-activate-on-top-level): New variable. (ad-start-advice, ad-stop-advice, ad-recover-normality): Modified to achieve de/activation of automatic advice activation by setting the definition of `ad-activate' to `ad-activate-on' or `ad-activate-off'. (ad-start-advice): Is now called unconditionally when Advice is loaded. Made compilation behavior of advised definitions customizable, since loading the byte-compiler takes some time and is not always worth the cost, e.g., if one only wants to make a few simple modifications: (ad-default-compilation-action): New variable which specifies whether to compile an advised definition in case the COMPILE argument to `ad-activate-on' or one of its friends was supplied as nil. (ad-preactivate-advice): Supply negative COMPILE argument to prevent compilation. (ad-should-compile): New function. (ad-activate-advised-definition): Use `ad-should-compile' to determine whether an advised definition should get compiled. (ad-activate-on, ad-update, ad-activate-regexp, ad-update-regexp) (ad-activate-all): Doc fixes. (ad-update): Leave handling of COMPILE up to `ad-activate-on'. Extracted construction of freeze-advices from `defadvice': (ad-make-freeze-definition): New function. (defadvice): Use `ad-make-freeze-definition' to construct frozen defs.
author Richard M. Stallman <rms@gnu.org>
date Thu, 04 Aug 1994 21:40:49 +0000
parents 829b83e91e8b
children a95ca44cec95
comparison
equal deleted inserted replaced
8444:841f2c8ae5bb 8445:81f7b5d9b990
2 2
3 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 4
5 ;; Author: Hans Chalupsky <hans@cs.buffalo.edu> 5 ;; Author: Hans Chalupsky <hans@cs.buffalo.edu>
6 ;; Created: 12 Dec 1992 6 ;; Created: 12 Dec 1992
7 ;; Version: advice.el,v 2.11 1994/02/24 22:51:43 hans Exp 7 ;; Version: advice.el,v 2.13 1994/08/03 23:27:05 hans Exp
8 ;; Keywords: extensions, lisp, tools 8 ;; Keywords: extensions, lisp, tools
9 9
10 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
11 11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
24 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 25
26 ;; LCD Archive Entry: 26 ;; LCD Archive Entry:
27 ;; advice|Hans Chalupsky|hans@cs.buffalo.edu| 27 ;; advice|Hans Chalupsky|hans@cs.buffalo.edu|
28 ;; Overloading mechanism for Emacs Lisp functions| 28 ;; Overloading mechanism for Emacs Lisp functions|
29 ;; 1994/02/24 22:51:43|2.11|~/packages/advice.el.Z| 29 ;; 1994/08/03 23:27:05|2.13|~/packages/advice.el.Z|
30 30
31 31
32 ;;; Commentary: 32 ;;; Commentary:
33 33
34 ;; NOTE: This documentation is slightly out of date. In particular, all the 34 ;; NOTE: This documentation is slightly out of date. In particular, all the
66 ;; - Allows the specification of a different argument list for the advised 66 ;; - Allows the specification of a different argument list for the advised
67 ;; version of a function. 67 ;; version of a function.
68 ;; - Advised functions can be byte-compiled either at file-compile time 68 ;; - Advised functions can be byte-compiled either at file-compile time
69 ;; (see preactivation) or activation time. 69 ;; (see preactivation) or activation time.
70 ;; - Separation of advice definition and activation 70 ;; - Separation of advice definition and activation
71 ;; - Provides generally accessible function definition (after) hooks 71 ;; - Forward advice is possible, that is
72 ;; - Forward advice is possible (an application of definition hooks), that is
73 ;; as yet undefined or autoload functions can be advised without having to 72 ;; as yet undefined or autoload functions can be advised without having to
74 ;; preload the file in which they are defined. 73 ;; preload the file in which they are defined.
75 ;; - Forward redefinition is possible because around advice can be used to 74 ;; - Forward redefinition is possible because around advice can be used to
76 ;; completely redefine a function. 75 ;; completely redefine a function.
77 ;; - A caching mechanism for advised definition provides for cheap deactivation 76 ;; - A caching mechanism for advised definition provides for cheap deactivation
81 ;; the advice mechanism. 80 ;; the advice mechanism.
82 ;; - En/disablement mechanism allows the use of different "views" of advised 81 ;; - En/disablement mechanism allows the use of different "views" of advised
83 ;; functions depending on what pieces of advice are currently en/disabled 82 ;; functions depending on what pieces of advice are currently en/disabled
84 ;; - Provides manipulation mechanisms for sets of advised functions via 83 ;; - Provides manipulation mechanisms for sets of advised functions via
85 ;; regular expressions that match advice names 84 ;; regular expressions that match advice names
86 ;; - Allows definition of load-hooks for arbitrary Emacs Lisp files without
87 ;; modification of these files
88 85
89 ;; @ How to get Advice for Emacs-18: 86 ;; @ How to get Advice for Emacs-18:
90 ;; ================================= 87 ;; =================================
91 ;; `advice18.el', a version of Advice that also works in Emacs-18 is available 88 ;; `advice18.el', a version of Advice that also works in Emacs-18 is available
92 ;; either via anonymous ftp from `ftp.cs.buffalo.edu (128.205.32.9)' with 89 ;; either via anonymous ftp from `ftp.cs.buffalo.edu (128.205.32.9)' with
112 ;; The latter three are actual headings which you can search for 109 ;; The latter three are actual headings which you can search for
113 ;; directly in case `outline-mode' doesn't work for you. 110 ;; directly in case `outline-mode' doesn't work for you.
114 111
115 ;; @ Restrictions: 112 ;; @ Restrictions:
116 ;; =============== 113 ;; ===============
117 ;; - This version of Advice only works for Emacs-19 or Lucid Emacs. 114 ;; - This version of Advice only works for Emacs 19.26 and later. It uses
115 ;; new versions of the built-in functions `fset/defalias' which are not
116 ;; yet available in Lucid Emacs, hence, it won't work there.
118 ;; - Advised functions/macros/subrs will only exhibit their advised behavior 117 ;; - Advised functions/macros/subrs will only exhibit their advised behavior
119 ;; when they are invoked via their function cell. This means that advice will 118 ;; when they are invoked via their function cell. This means that advice will
120 ;; not work for the following: 119 ;; not work for the following:
121 ;; + advised subrs that are called directly from other subrs or C-code 120 ;; + advised subrs that are called directly from other subrs or C-code
122 ;; + advised subrs that got replaced with their byte-code during 121 ;; + advised subrs that got replaced with their byte-code during
123 ;; byte-compilation (e.g., car) 122 ;; byte-compilation (e.g., car)
124 ;; + advised macros which were expanded during byte-compilation before 123 ;; + advised macros which were expanded during byte-compilation before
125 ;; their advice was activated. 124 ;; their advice was activated.
126 125
127 ;; @ Known bug:
128 ;; ============
129 ;; - Using automatic activation of (forward) advice will break the
130 ;; function `interactive-p' when it is used in the body of a `catch'
131 ;; (this problem will go away once automatic advice activation gets
132 ;; supported by built-in functions).
133
134 ;; @ Credits: 126 ;; @ Credits:
135 ;; ========== 127 ;; ==========
136 ;; This package is an extension and generalization of packages such as 128 ;; This package is an extension and generalization of packages such as
137 ;; insert-hooks.el written by Noah S. Friedman, and advise.el written by 129 ;; insert-hooks.el written by Noah S. Friedman, and advise.el written by
138 ;; Raul J. Acevedo. Some ideas used in here come from these packages, 130 ;; Raul J. Acevedo. Some ideas used in here come from these packages,
149 ;; @ Safety Rules and Emergency Exits: 141 ;; @ Safety Rules and Emergency Exits:
150 ;; =================================== 142 ;; ===================================
151 ;; Before we begin: CAUTION!! 143 ;; Before we begin: CAUTION!!
152 ;; Advice provides you with a lot of rope to hang yourself on very 144 ;; Advice provides you with a lot of rope to hang yourself on very
153 ;; easily accessible trees, so, here are a few important things you 145 ;; easily accessible trees, so, here are a few important things you
154 ;; should know: Once Advice has been started with `ad-start-advice' it 146 ;; should know: Once Advice has been started with `ad-start-advice'
155 ;; generates advised definitions of the `documentation' function, and, 147 ;; (which happens automatically when you load this file), it
156 ;; if definition hooks are enabled (e.g., for forward advice), also of 148 ;; generates an advised definition of the `documentation' function, and
157 ;; `defun', `defmacro' and `fset' (if you use Jamie Zawinski's (jwz) 149 ;; it will enable automatic advice activation when functions get defined.
158 ;; optimizing byte-compiler as standardly used in Emacs-19 and 150 ;; All of this can be undone at any time with `M-x ad-stop-advice'.
159 ;; Lucid Emacs-19 (Lemacs), then enabling definition hooks will also
160 ;; redefine the `byte-code' subr). All these changes can be undone at
161 ;; any time with `M-x ad-stop-advice'.
162 ;; 151 ;;
163 ;; If you experience any strange behavior/errors etc. that you attribute to 152 ;; If you experience any strange behavior/errors etc. that you attribute to
164 ;; Advice or to some ill-advised function do one of the following: 153 ;; Advice or to some ill-advised function do one of the following:
165 154
166 ;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what 155 ;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what
188 ;; I use it extensively and haven't run into any serious trouble in a long 177 ;; I use it extensively and haven't run into any serious trouble in a long
189 ;; time. Just wanted you to be warned. 178 ;; time. Just wanted you to be warned.
190 179
191 ;; @ Customization: 180 ;; @ Customization:
192 ;; ================ 181 ;; ================
193 ;; Part of the advice magic does not start until you call `ad-start-advice'
194 ;; which you can either do interactively, explicitly in your .emacs, or by
195 ;; putting
196 ;;
197 ;; (setq ad-start-advice-on-load t)
198 ;;
199 ;; into your .emacs which will automatically start advice when the file gets
200 ;; loaded.
201
202 ;; If you want to be able to forward advise functions, that is to advise them
203 ;; when they are not yet defined or defined as autoloads, then you should put
204 ;; the following into your .emacs
205 ;;
206 ;; (setq ad-activate-on-definition t)
207 ;;
208 ;; which will activate all advice at the time the function gets actually
209 ;; defined/loaded. The value of this variable will not have any effect until
210 ;; `ad-start-advice' gets executed.
211 182
212 ;; Look at the documentation of `ad-redefinition-action' for possible values 183 ;; Look at the documentation of `ad-redefinition-action' for possible values
213 ;; of this variable. Its default value is `warn' which will print a warning 184 ;; of this variable. Its default value is `warn' which will print a warning
214 ;; message when an already defined advised function gets redefined with a 185 ;; message when an already defined advised function gets redefined with a
215 ;; new original definition and de/activated. 186 ;; new original definition and de/activated.
187
188 ;; Look at the documentation of `ad-default-compilation-action' for possible
189 ;; values of this variable. Its default value is `maybe' which will compile
190 ;; advised definitions during activation in case the byte-compiler is already
191 ;; loaded. Otherwise, it will leave them uncompiled.
216 192
217 ;; @ Motivation: 193 ;; @ Motivation:
218 ;; ============= 194 ;; =============
219 ;; Before I go on explaining how advice works, here are four simple examples 195 ;; Before I go on explaining how advice works, here are four simple examples
220 ;; how this package can be used. The first three are very useful, the last one 196 ;; how this package can be used. The first three are very useful, the last one
573 ;; redefined with the advised definition. This also means that undefined 549 ;; redefined with the advised definition. This also means that undefined
574 ;; functions cannot get activated even though they might be already advised. 550 ;; functions cannot get activated even though they might be already advised.
575 551
576 ;; The advised definition will get compiled either if `ad-activate' was called 552 ;; The advised definition will get compiled either if `ad-activate' was called
577 ;; interactively with a prefix argument, or called explicitly with its second 553 ;; interactively with a prefix argument, or called explicitly with its second
578 ;; argument as t, or, if this was a case of forward advice if the original 554 ;; argument as t, or, if `ad-default-compilation-action' justifies it according
579 ;; definition of the function was compiled. If the advised definition was 555 ;; to the current system state. If the advised definition was
580 ;; constructed during "preactivation" (see below) then that definition will 556 ;; constructed during "preactivation" (see below) then that definition will
581 ;; be already compiled because it was constructed during byte-compilation of 557 ;; be already compiled because it was constructed during byte-compilation of
582 ;; the file that contained the `defadvice' with the `preactivate' flag. 558 ;; the file that contained the `defadvice' with the `preactivate' flag.
583 559
584 ;; `ad-deactivate' can be used to back-define an advised function to its 560 ;; `ad-deactivate' can be used to back-define an advised function to its
689 665
690 ;; A certain piece of advice is considered a match if its name contains a 666 ;; A certain piece of advice is considered a match if its name contains a
691 ;; match for the regular expression. To enable ange-ftp again we would use 667 ;; match for the regular expression. To enable ange-ftp again we would use
692 ;; `ad-enable-regexp' and then activate or update again. 668 ;; `ad-enable-regexp' and then activate or update again.
693 669
694 ;; @@ Forward advice, function definition hooks: 670 ;; @@ Forward advice, automatic advice activation:
695 ;; ============================================= 671 ;; ===============================================
696 ;; Because most Emacs Lisp packages are loaded on demand via an autoload 672 ;; Because most Emacs Lisp packages are loaded on demand via an autoload
697 ;; mechanism it is essential to be able to "forward advise" functions. 673 ;; mechanism it is essential to be able to "forward advise" functions.
698 ;; Otherwise, proper advice definition and activation would make it necessary 674 ;; Otherwise, proper advice definition and activation would make it necessary
699 ;; to preload every file that defines a certain function before it can be 675 ;; to preload every file that defines a certain function before it can be
700 ;; advised, which would partly defeat the purpose of the advice mechanism. 676 ;; advised, which would partly defeat the purpose of the advice mechanism.
704 ;; information for a possibly undefined function. 680 ;; information for a possibly undefined function.
705 681
706 ;; Advice implements forward advice mainly via the following: 1) Separation 682 ;; Advice implements forward advice mainly via the following: 1) Separation
707 ;; of advice definition and activation that makes it possible to accumulate 683 ;; of advice definition and activation that makes it possible to accumulate
708 ;; advice information without having the original function already defined, 684 ;; advice information without having the original function already defined,
709 ;; 2) special versions of the function defining functions `defun', `defmacro' 685 ;; 2) special versions of the built-in functions `fset/defalias' which check
710 ;; and `fset' that check for advice information whenever they define a 686 ;; for advice information whenever they define a function. If advice
711 ;; function. If advice information was found and forward advice is enabled 687 ;; information was found then the advice will immediately get activated when
712 ;; then the advice will immediately get activated when the function gets 688 ;; the function gets defined.
713 ;; defined. 689
714 690 ;; Automatic advice activation means, that whenever a function gets defined
715 ;; @@@ Enabling forward advice:
716 ;; ============================
717 ;; Forward advice is enabled by setting `ad-activate-on-definition' to t
718 ;; and then calling `ad-start-advice' which can either be done interactively,
719 ;; directly with `(ad-start-advice)' in your .emacs, or by setting
720 ;; `ad-start-advice-on-load' to t before advice gets loaded. For example,
721 ;; putting the following into your .emacs will enable forward advice:
722 ;;
723 ;; (setq ad-start-advice-on-load t)
724 ;; (setq ad-activate-on-definition t)
725 ;;
726 ;; "Activation on definition" means, that whenever a function gets defined
727 ;; with either `defun', `defmacro', `fset' or by loading a byte-compiled 691 ;; with either `defun', `defmacro', `fset' or by loading a byte-compiled
728 ;; file, and the function has some advice-info stored with it then that 692 ;; file, and the function has some advice-info stored with it then that
729 ;; advice will get activated right away. 693 ;; advice will get activated right away.
730 694
731 ;; If jwz's byte-compiler is used then `ad-use-jwz-byte-compiler' should 695 ;; @@@ Enabling automatic advice activation:
732 ;; be t in order to make forward advice work with functions defined in 696 ;; =========================================
733 ;; compiled files generated by that compiler. In v19s which use this 697 ;; Automatic advice activation is enabled by default. It can be disabled by
734 ;; compiler the value of this variable will be correct automatically. 698 ;; doint `M-x ad-stop-advice' and enabled again with `M-x ad-start-advice'.
735 ;; If you use a v18 Emacs in conjunction with jwz's compiler and you want
736 ;; to use forward advice then you should check its value after loading
737 ;; advice. If it is nil set it explicitly with
738 ;;
739 ;; (setq ad-use-jwz-byte-compiler t)
740 ;;
741 ;; along with `ad-activate-on-definition' before you start advice (see above).
742
743 ;; IMPORTANT: A v18 Emacs + jwz's compiler + forward advice means performance
744 ;; tradeoffs which are described below.
745
746 ;; @@@ Forward advice with compiled files generated by jwz's byte-compiler:
747 ;; ========================================================================
748 ;; The v18 byte-compiler only uses `defun/defmacro' to define compiled
749 ;; functions, hence, providing advised versions of these functions was
750 ;; sufficient to achieve forward advice. With the advent of Jamie Zawinski's
751 ;; optimizing byte-compiler which is now standardly used in Emacs-19 and
752 ;; Lemacs things became more complicated. jwz's compiler defines functions
753 ;; in hunks of byte-code without explicit usage of `defun/defmacro'. To
754 ;; still provide forward advice even in this scenario, advice defines an
755 ;; advised version of the `byte-code' subr that scans its arguments for
756 ;; function definitions during the loading of compiled files. While this is
757 ;; no problem in a v19 Emacs, because it uses a new datatype for compiled
758 ;; code objects and the `byte-code' subr is only rarely used at all, it
759 ;; presents a major problem in a v18 Emacs because there calls to
760 ;; `byte-code' are the only means of executing compiled code (every body of
761 ;; a compiled function contains a call to `byte-code'). Because the advised
762 ;; `byte-code' has to perform some extra checks every call to a compiled
763 ;; function becomes more expensive.
764
765 ;; Enabling forward advice leads to performance degradation in the following
766 ;; situations:
767 ;; - A v18 Emacs is used and the value of `ad-use-jwz-byte-compiler' is t
768 ;; (either because jwz's byte-compiler is used instead of the standard v18
769 ;; compiler, or some compiled files generated by jwz's compiler are used).
770 ;; - A v19 Emacs is used with some old-style v18 compiled files.
771 ;; Some performance experiments I conducted showed that function call intensive
772 ;; code (such as the highly recursive byte-compiler itself) slows down by a
773 ;; factor of 1.8. Function call intensive code that runs while a file gets
774 ;; loaded can slow down by a factor of 6! For the v19 scenario this performance
775 ;; lossage would only apply to code that was loaded from old v18 compiled
776 ;; files.
777
778 ;; MORAL: If you use a v18 Emacs in conjunction with jwz's byte-compiler you
779 ;; should think twice whether you really need forward advice. There are some
780 ;; alternatives to forward advice described below that might give you what
781 ;; you need without the loss of performance (that performance loss probably
782 ;; outweighs by far any performance gain due to the optimizing nature of jwz's
783 ;; compiler).
784
785 ;; @@@ Alternatives to automatic activation of forward advice:
786 ;; ===========================================================
787 ;; If you use a v18 Emacs in conjunction with jwz's compiler, or you simply
788 ;; don't trust the automatic activation mechanism of forward advice, then
789 ;; you can use some of the following alternatives to get around that:
790 ;; - Preload the file that contains the definition of the function that you
791 ;; want to advice. Inelegant and wasteful, but it works.
792 ;; - If the package that contains the definition of the function you want to
793 ;; advise has any mode hooks, and the advised function is only used once such
794 ;; a mode has been entered, then you can activate the advice in the mode
795 ;; hook. Just put a form like `(ad-activate 'my-advised-fn t)' into the
796 ;; hook definition. The caching mechanism will reuse advised definitions,
797 ;; so calling that mode hook over and over again will not construct
798 ;; advised definitions over and over again, so you won't loose any
799 ;; performance.
800 ;; - If your Emacs comes with file load hooks (such as v19's
801 ;; `after-load-alist' mechanism), then you can put the activation form
802 ;; into that, for example, add `("myfile" (ad-activate 'my-advised-fn t))'
803 ;; to it to activate the advice right ater "myfile" got loaded.
804
805 ;; @@@ Function definition hooks:
806 ;; ==============================
807 ;; Automatic activation of forward advice is implemented as an application
808 ;; of a more general function definition hook mechanism. After a function
809 ;; gets re/defined with `defun/defmacro/fset' or via a hunk of byte-code
810 ;; during the loading of a byte-compiled file, and function definition hooks
811 ;; are enabled, then all hook functions stored in `ad-definition-hooks' are
812 ;; run with the variable `ad-defined-function' bound to the name of the
813 ;; currently defined function.
814
815 ;; Function definition hooks can be enabled with
816 ;;
817 ;; (setq ad-enable-definition-hooks t)
818 ;;
819 ;; before advice gets started with `ad-start-advice'. Setting
820 ;; `ad-activate-on-definition' to t automatically enables definition hooks
821 ;; regardless of the value of `ad-enable-definition-hooks'.
822
823 ;; @@@ Wish list:
824 ;; ==============
825 ;; - The implementation of definition hooks for v19 compiled files would be
826 ;; safer if jwz's byte-compiler used something like `byte-code-tl' instead
827 ;; of `byte-code' to execute hunks of function defining byte-code at the
828 ;; top level of compiled files.
829 ;; - Definition hooks should be implemented directly as part of the C-code
830 ;; that implements `fset', because then Advice wouldn't have to use all
831 ;; these dirty hacks to achieve this functionality.
832 699
833 ;; @@ Caching of advised definitions: 700 ;; @@ Caching of advised definitions:
834 ;; ================================== 701 ;; ==================================
835 ;; After an advised definition got constructed it gets cached as part of the 702 ;; After an advised definition got constructed it gets cached as part of the
836 ;; advised function's advice-info so it can be reused, for example, after an 703 ;; advised function's advice-info so it can be reused, for example, after an
1952 (provide 'advice-preload) 1819 (provide 'advice-preload)
1953 ;; During a normal load this is a noop: 1820 ;; During a normal load this is a noop:
1954 (require 'advice-preload "advice.el") 1821 (require 'advice-preload "advice.el")
1955 1822
1956 1823
1957 ;; @@ Variable definitions:
1958 ;; ========================
1959
1960 (defconst ad-version "2.11")
1961
1962 (defmacro ad-lemacs-p () 1824 (defmacro ad-lemacs-p ()
1963 ;;Expands into Non-nil constant if we run Lucid's version of Emacs-19. 1825 ;;Expands into Non-nil constant if we run Lucid's version of Emacs-19.
1964 ;;Unselected conditional code will be optimized away during compilation. 1826 ;;Unselected conditional code will be optimized away during compilation.
1965 (string-match "Lucid" emacs-version)) 1827 (string-match "Lucid" emacs-version))
1966 1828
1967 ;;;###autoload 1829
1968 (defvar ad-start-advice-on-load t 1830 ;; @@ Variable definitions:
1969 "*Non-nil will start Advice magic when this file gets loaded. 1831 ;; ========================
1970 Also see function `ad-start-advice'.") 1832
1971 1833 (defconst ad-version "2.13")
1972 ;;;###autoload
1973 (defvar ad-activate-on-definition nil
1974 "*Non-nil means automatic advice activation at function definition.
1975 Set this variable to t if you want to enable forward advice (which is
1976 automatic advice activation of a previously undefined function at the
1977 point the function gets defined/loaded/autoloaded). The value of this
1978 variable takes effect only during the execution of `ad-start-advice'.
1979 If non-nil it will enable definition hooks regardless of the value
1980 of `ad-enable-definition-hooks'.")
1981 1834
1982 ;;;###autoload 1835 ;;;###autoload
1983 (defvar ad-redefinition-action 'warn 1836 (defvar ad-redefinition-action 'warn
1984 "*Defines what to do with redefinitions during de/activation. 1837 "*Defines what to do with redefinitions during Advice de/activation.
1985 Redefinition occurs if a previously activated function that already has an 1838 Redefinition occurs if a previously activated function that already has an
1986 original definition associated with it gets redefined and then de/activated. 1839 original definition associated with it gets redefined and then de/activated.
1987 In such a case we can either accept the current definition as the new 1840 In such a case we can either accept the current definition as the new
1988 original definition, discard the current definition and replace it with the 1841 original definition, discard the current definition and replace it with the
1989 old original, or keep it and raise an error. The values `accept', `discard', 1842 old original, or keep it and raise an error. The values `accept', `discard',
1990 `error' or `warn' govern what will be done. `warn' is just like `accept' but 1843 `error' or `warn' govern what will be done. `warn' is just like `accept' but
1991 it additionally prints a warning message. All other values will be 1844 it additionally prints a warning message. All other values will be
1992 interpreted as `error'.") 1845 interpreted as `error'.")
1993 1846
1994 ;;;###autoload 1847 ;;;###autoload
1995 (defvar ad-definition-hooks nil 1848 (defvar ad-default-compilation-action 'maybe
1996 "*List of hooks to be run after a function definition. 1849 "*Defines whether to compile advised definitions during activation.
1997 The variable `ad-defined-function' will be bound to the name of 1850 A value of `always' will result in unconditional compilation, `never' will
1998 the currently defined function when the hook function is run.") 1851 always avoid compilation, `maybe' will compile if the byte-compiler is already
1999 1852 loaded, and `like-original' will compile if the original definition of the
2000 ;;;###autoload 1853 advised function is compiled or a built-in function. Every other value will
2001 (defvar ad-enable-definition-hooks nil 1854 be interpreted as `maybe'. This variable will only be considered if the
2002 "*Non-nil will enable hooks to be run on function definition. 1855 COMPILE argument of `ad-activate' was supplied as nil.")
2003 Setting this variable is a noop unless the value of
2004 `ad-activate-on-definition' (which see) is nil.")
2005 1856
2006 1857
2007 ;; @@ Some utilities: 1858 ;; @@ Some utilities:
2008 ;; ================== 1859 ;; ==================
2009 1860
2098 (defun ad-save-real-definitions () 1949 (defun ad-save-real-definitions ()
2099 ;; Macro expansion will hardcode the values of the various byte-compiler 1950 ;; Macro expansion will hardcode the values of the various byte-compiler
2100 ;; properties into the compiled version of this function such that the 1951 ;; properties into the compiled version of this function such that the
2101 ;; proper values will be available at runtime without loading the compiler: 1952 ;; proper values will be available at runtime without loading the compiler:
2102 (ad-save-real-definition fset) 1953 (ad-save-real-definition fset)
2103 (ad-save-real-definition documentation) 1954 (ad-save-real-definition documentation))
2104 (ad-save-real-definition byte-code)
2105 (put 'ad-real-byte-code 'byte-compile nil))
2106 1955
2107 (ad-save-real-definitions) 1956 (ad-save-real-definitions)
2108 1957
2109 1958
2110 ;; @@ Advice info access fns: 1959 ;; @@ Advice info access fns:
2261 (if (ad-advice-enabled advice) 2110 (if (ad-advice-enabled advice)
2262 (setq enabled-advices (cons advice enabled-advices)))) 2111 (setq enabled-advices (cons advice enabled-advices))))
2263 (reverse enabled-advices))) 2112 (reverse enabled-advices)))
2264 2113
2265 2114
2115 ;; @@ Dealing with automatic advice activation via `fset/defalias':
2116 ;; ================================================================
2117
2118 ;; Since Emacs 19.26 the built-in versions of `fset' and `defalias'
2119 ;; take care of automatic advice activation, hence, we don't have to
2120 ;; hack it anymore by advising `fset/defun/defmacro/byte-code/etc'.
2121
2122 ;; The functionality of the new `fset' is as follows:
2123 ;;
2124 ;; fset(sym,newdef)
2125 ;; assign NEWDEF to SYM
2126 ;; if (get SYM 'ad-advice-info)
2127 ;; ad-activate(SYM, nil)
2128 ;; return (symbol-function SYM)
2129 ;;
2130 ;; Whether advised definitions created by automatic activations will be
2131 ;; compiled depends on the value of `ad-default-compilation-action'.
2132
2133 ;; Since calling `ad-activate' in the built-in definition of `fset' can
2134 ;; create major disasters we have to be a bit careful. One precaution is
2135 ;; to provide a dummy definition for `ad-activate' which can be used to
2136 ;; turn off automatic advice activation (e.g., when `ad-stop-advice' or
2137 ;; `ad-recover-normality' are called). Another is to avoid recursive calls
2138 ;; to `ad-activate-on' by using `ad-with-auto-activation-disabled' where
2139 ;; appropriate, especially in a safe version of `fset'.
2140
2141 ;; For now define `ad-activate' to the dummy definition:
2142 (defun ad-activate (function &optional compile)
2143 "Automatic advice activation is disabled. `ad-start-advice' enables it."
2144 nil)
2145
2146 ;; This is just a copy of the above:
2147 (defun ad-activate-off (function &optional compile)
2148 "Automatic advice activation is disabled. `ad-start-advice' enables it."
2149 nil)
2150
2151 ;; This will be t for top-level calls to `ad-activate-on':
2152 (defvar ad-activate-on-top-level t)
2153
2154 (defmacro ad-with-auto-activation-disabled (&rest body)
2155 (` (let ((ad-activate-on-top-level nil))
2156 (,@ body))))
2157
2158 (defun ad-safe-fset (symbol definition)
2159 ;; A safe `fset' which will never call `ad-activate' recursively.
2160 (ad-with-auto-activation-disabled
2161 (ad-real-fset symbol definition)))
2162
2163
2266 ;; @@ Access functions for original definitions: 2164 ;; @@ Access functions for original definitions:
2267 ;; ============================================ 2165 ;; ============================================
2268 ;; The advice-info of an advised function contains its `origname' which is 2166 ;; The advice-info of an advised function contains its `origname' which is
2269 ;; a symbol that is fbound to the original definition available at the first 2167 ;; a symbol that is fbound to the original definition available at the first
2270 ;; proper activation of the function after a legal re/definition. If the 2168 ;; proper activation of the function after a legal re/definition. If the
2280 (` (let ((origname (ad-get-advice-info-field (, function) 'origname))) 2178 (` (let ((origname (ad-get-advice-info-field (, function) 'origname)))
2281 (if (fboundp origname) 2179 (if (fboundp origname)
2282 (symbol-function origname))))) 2180 (symbol-function origname)))))
2283 2181
2284 (defmacro ad-set-orig-definition (function definition) 2182 (defmacro ad-set-orig-definition (function definition)
2285 (` (ad-real-fset 2183 (` (ad-safe-fset
2286 (ad-get-advice-info-field function 'origname) (, definition)))) 2184 (ad-get-advice-info-field function 'origname) (, definition))))
2287 2185
2288 (defmacro ad-clear-orig-definition (function) 2186 (defmacro ad-clear-orig-definition (function)
2289 (` (fmakunbound (ad-get-advice-info-field (, function) 'origname)))) 2187 (` (fmakunbound (ad-get-advice-info-field (, function) 'origname))))
2290 2188
2596 2494
2597 ;; Emacs/Lemacs cross-compatibility 2495 ;; Emacs/Lemacs cross-compatibility
2598 ;; (compiled-function-p is an obsolete function in Emacs): 2496 ;; (compiled-function-p is an obsolete function in Emacs):
2599 (if (and (not (fboundp 'byte-code-function-p)) 2497 (if (and (not (fboundp 'byte-code-function-p))
2600 (fboundp 'compiled-function-p)) 2498 (fboundp 'compiled-function-p))
2601 (ad-real-fset 'byte-code-function-p 'compiled-function-p)) 2499 (ad-safe-fset 'byte-code-function-p 'compiled-function-p))
2602 2500
2603 (defmacro ad-compiled-p (definition) 2501 (defmacro ad-compiled-p (definition)
2604 ;;"non-nil if DEFINITION is a compiled byte-code object." 2502 ;;"non-nil if DEFINITION is a compiled byte-code object."
2605 (` (or (byte-code-function-p (, definition)) 2503 (` (or (byte-code-function-p (, definition))
2606 (and (ad-macro-p (, definition)) 2504 (and (ad-macro-p (, definition))
2775 2673
2776 (defun ad-compile-function (function) 2674 (defun ad-compile-function (function)
2777 "Byte-compiles FUNCTION (or macro) if it is not yet compiled." 2675 "Byte-compiles FUNCTION (or macro) if it is not yet compiled."
2778 (interactive "aByte-compile function: ") 2676 (interactive "aByte-compile function: ")
2779 (if (ad-is-compilable function) 2677 (if (ad-is-compilable function)
2780 (byte-compile function))) 2678 ;; Need to turn off auto-activation
2679 ;; because `byte-compile' uses `fset':
2680 (ad-with-auto-activation-disabled
2681 (byte-compile function))))
2781 2682
2782 2683
2783 ;; @@ Constructing advised definitions: 2684 ;; @@ Constructing advised definitions:
2784 ;; ==================================== 2685 ;; ====================================
2785 ;; 2686 ;;
3467 (unwind-protect 3368 (unwind-protect
3468 (progn 3369 (progn
3469 (ad-add-advice function advice class position) 3370 (ad-add-advice function advice class position)
3470 (ad-enable-advice function class (ad-advice-name advice)) 3371 (ad-enable-advice function class (ad-advice-name advice))
3471 (ad-clear-cache function) 3372 (ad-clear-cache function)
3472 (ad-activate function nil) 3373 (ad-activate-on function -1)
3473 (if (and (ad-is-active function) 3374 (if (and (ad-is-active function)
3474 (ad-get-cache-definition function)) 3375 (ad-get-cache-definition function))
3475 (list (ad-get-cache-definition function) 3376 (list (ad-get-cache-definition function)
3476 (ad-get-cache-id function)))) 3377 (ad-get-cache-id function))))
3477 (ad-set-advice-info function old-advice-info) 3378 (ad-set-advice-info function old-advice-info)
3478 ;; Don't `fset' function to nil if it was previously unbound: 3379 ;; Don't `fset' function to nil if it was previously unbound:
3479 (if function-defined-p 3380 (if function-defined-p
3480 (ad-real-fset function old-definition) 3381 (ad-safe-fset function old-definition)
3481 (fmakunbound function))))) 3382 (fmakunbound function)))))
3383
3384
3385 ;; @@ Freezing:
3386 ;; ============
3387 ;; Freezing transforms a `defadvice' into a redefining `defun/defmacro'
3388 ;; for the advised function without keeping any advice information. This
3389 ;; feature was jwz's idea: It generates a dumpable function definition
3390 ;; whose documentation can be written to the DOC file, and the generated
3391 ;; code does not need any Advice runtime support. Of course, frozen advices
3392 ;; cannot be undone.
3393
3394 ;; Freezing only considers the advice of the particular `defadvice', other
3395 ;; already existing advices for the same function will be ignored. To ensure
3396 ;; proper interaction when an already advised function gets redefined with
3397 ;; a frozen advice, frozen advices always use the actual original definition
3398 ;; of the function, i.e., they are always at the core of the onion. E.g., if
3399 ;; an already advised function gets redefined with a frozen advice and then
3400 ;; unadvised, the frozen advice remains as the new definition of the function.
3401
3402 ;; While multiple freeze advices for a single function or freeze-advising
3403 ;; of an already advised function are possible, they are better avoided,
3404 ;; because definition/compile/load ordering is relevant, and it becomes
3405 ;; incomprehensible pretty quickly.
3406
3407 (defun ad-make-freeze-definition (function advice class position)
3408 (if (not (ad-has-proper-definition function))
3409 (error
3410 "ad-make-freeze-definition: `%s' is not yet defined"
3411 function))
3412 (let* ((name (ad-advice-name advice))
3413 ;; With a unique origname we can have multiple freeze advices
3414 ;; for the same function, each overloading the previous one:
3415 (unique-origname
3416 (intern (format "%s-%s-%s" (ad-make-origname function) class name)))
3417 (orig-definition
3418 ;; If FUNCTION is already advised, we'll use its current origdef
3419 ;; as the original definition of the frozen advice:
3420 (or (ad-get-orig-definition function)
3421 (symbol-function function)))
3422 (old-advice-info
3423 (if (ad-is-advised function)
3424 (ad-copy-advice-info function)))
3425 (real-docstring-fn
3426 (symbol-function 'ad-make-advised-definition-docstring))
3427 (real-origname-fn
3428 (symbol-function 'ad-make-origname))
3429 (frozen-definition
3430 (unwind-protect
3431 (progn
3432 ;; Make sure we construct a proper docstring:
3433 (ad-safe-fset 'ad-make-advised-definition-docstring
3434 'ad-make-freeze-docstring)
3435 ;; Make sure `unique-origname' is used as the origname:
3436 (ad-safe-fset 'ad-make-origname '(lambda (x) unique-origname))
3437 ;; No we reset all current advice information to nil and
3438 ;; generate an advised definition that's solely determined
3439 ;; by ADVICE and the current origdef of FUNCTION:
3440 (ad-set-advice-info function nil)
3441 (ad-add-advice function advice class position)
3442 ;; The following will provide proper real docstrings as
3443 ;; well as a definition that will make the compiler happy:
3444 (ad-set-orig-definition function orig-definition)
3445 (ad-make-advised-definition function))
3446 ;; Restore the old advice state:
3447 (ad-set-advice-info function old-advice-info)
3448 ;; Restore functions:
3449 (ad-safe-fset
3450 'ad-make-advised-definition-docstring real-docstring-fn)
3451 (ad-safe-fset 'ad-make-origname real-origname-fn))))
3452 (if frozen-definition
3453 (let* ((macro-p (ad-macro-p frozen-definition))
3454 (body (cdr (if macro-p
3455 (ad-lambdafy frozen-definition)
3456 frozen-definition))))
3457 (` (progn
3458 (if (not (fboundp '(, unique-origname)))
3459 (fset '(, unique-origname)
3460 ;; avoid infinite recursion in case the function
3461 ;; we want to freeze is already advised:
3462 (or (ad-get-orig-definition '(, function))
3463 (symbol-function '(, function)))))
3464 ((, (if macro-p 'defmacro 'defun))
3465 (, function)
3466 (,@ body))))))))
3467
3468
3469 ;; @@ Activation and definition handling:
3470 ;; ======================================
3471
3472 (defun ad-should-compile (function compile)
3473 ;;"Returns non-nil if the advised FUNCTION should be compiled.
3474 ;;If COMPILE is non-nil and not a negative number then it returns t.
3475 ;;If COMPILE is a negative number then it returns nil.
3476 ;;If COMPILE is nil then the result depends on the value of
3477 ;;`ad-default-compilation-action' (which see)."
3478 (if (integerp compile)
3479 (>= compile 0)
3480 (if compile
3481 compile
3482 (cond ((eq ad-default-compilation-action 'never)
3483 nil)
3484 ((eq ad-default-compilation-action 'always)
3485 t)
3486 ((eq ad-default-compilation-action 'like-original)
3487 (or (ad-subr-p (ad-get-orig-definition function))
3488 (ad-compiled-p (ad-get-orig-definition function))))
3489 ;; everything else means `maybe':
3490 (t (featurep 'byte-compile))))))
3482 3491
3483 (defun ad-activate-advised-definition (function compile) 3492 (defun ad-activate-advised-definition (function compile)
3484 ;;"Redefines FUNCTION with its advised definition from cache or scratch. 3493 ;;"Redefines FUNCTION with its advised definition from cache or scratch.
3485 ;;If COMPILE is true the resulting FUNCTION will be compiled. The current 3494 ;;The resulting FUNCTION will be compiled if `ad-should-compile' returns t.
3486 ;;definition and its cache-id will be put into the cache." 3495 ;;The current definition and its cache-id will be put into the cache."
3487 (let ((verified-cached-definition 3496 (let ((verified-cached-definition
3488 (if (ad-verify-cache-id function) 3497 (if (ad-verify-cache-id function)
3489 (ad-get-cache-definition function)))) 3498 (ad-get-cache-definition function))))
3490 (ad-real-fset function 3499 (ad-safe-fset function
3491 (or verified-cached-definition 3500 (or verified-cached-definition
3492 (ad-make-advised-definition function))) 3501 (ad-make-advised-definition function)))
3493 (if compile (ad-compile-function function)) 3502 (if (ad-should-compile function compile)
3503 (ad-compile-function function))
3494 (if verified-cached-definition 3504 (if verified-cached-definition
3495 (if (not (eq verified-cached-definition (symbol-function function))) 3505 (if (not (eq verified-cached-definition (symbol-function function)))
3496 ;; we must have compiled, cache the compiled definition: 3506 ;; we must have compiled, cache the compiled definition:
3497 (ad-set-cache 3507 (ad-set-cache
3498 function (symbol-function function) (ad-get-cache-id function))) 3508 function (symbol-function function) (ad-get-cache-id function)))
3526 ;; we have a redefinition: 3536 ;; we have a redefinition:
3527 (if (not (memq ad-redefinition-action '(accept discard warn))) 3537 (if (not (memq ad-redefinition-action '(accept discard warn)))
3528 (error "ad-handle-definition (see its doc): `%s' %s" 3538 (error "ad-handle-definition (see its doc): `%s' %s"
3529 function "illegally redefined") 3539 function "illegally redefined")
3530 (if (eq ad-redefinition-action 'discard) 3540 (if (eq ad-redefinition-action 'discard)
3531 (ad-real-fset function original-definition) 3541 (ad-safe-fset function original-definition)
3532 (ad-set-orig-definition function current-definition) 3542 (ad-set-orig-definition function current-definition)
3533 (if (eq ad-redefinition-action 'warn) 3543 (if (eq ad-redefinition-action 'warn)
3534 (message "ad-handle-definition: `%s' got redefined" 3544 (message "ad-handle-definition: `%s' got redefined"
3535 function)))) 3545 function))))
3536 ;; either advised def or correct original is in place: 3546 ;; either advised def or correct original is in place:
3545 3555
3546 3556
3547 ;; @@ The top-level advice interface: 3557 ;; @@ The top-level advice interface:
3548 ;; ================================== 3558 ;; ==================================
3549 3559
3550 (defun ad-activate (function &optional compile) 3560 (defun ad-activate-on (function &optional compile)
3551 "Activates all the advice information of an advised FUNCTION. 3561 "Activates all the advice information of an advised FUNCTION.
3552 If FUNCTION has a proper original definition then an advised 3562 If FUNCTION has a proper original definition then an advised
3553 definition will be generated from FUNCTION's advice info and the 3563 definition will be generated from FUNCTION's advice info and the
3554 definition of FUNCTION will be replaced with it. If a previously 3564 definition of FUNCTION will be replaced with it. If a previously
3555 cached advised definition was available, it will be used. With an 3565 cached advised definition was available, it will be used.
3556 argument (COMPILE is non-nil) the resulting function (or a compilable 3566 The optional COMPILE argument determines whether the resulting function
3557 cached definition) will also be compiled. Activation of an advised 3567 or a compilable cached definition will be compiled. If it is negative
3558 function that has an advice info but no actual pieces of advice is 3568 no compilation will be performed, if it is positive or otherwise non-nil
3559 equivalent to a call to `ad-unadvise'. Activation of an advised 3569 the resulting function will be compiled, if it is nil the behavior depends
3560 function that has actual pieces of advice but none of them are enabled 3570 on the value of `ad-default-compilation-action' (which see).
3561 is equivalent to a call to `ad-deactivate'. The current advised 3571 Activation of an advised function that has an advice info but no actual
3572 pieces of advice is equivalent to a call to `ad-unadvise'. Activation of
3573 an advised function that has actual pieces of advice but none of them are
3574 enabled is equivalent to a call to `ad-deactivate'. The current advised
3562 definition will always be cached for later usage." 3575 definition will always be cached for later usage."
3563 (interactive 3576 (interactive
3564 (list (ad-read-advised-function "Activate advice of: ") 3577 (list (ad-read-advised-function "Activate advice of: ")
3565 current-prefix-arg)) 3578 current-prefix-arg))
3566 (if (not (ad-is-advised function)) 3579 (if ad-activate-on-top-level
3567 (error "ad-activate: `%s' is not advised" function) 3580 ;; avoid recursive calls to `ad-activate-on':
3568 (ad-handle-definition function) 3581 (ad-with-auto-activation-disabled
3569 ;; Just return for forward advised and not yet defined functions: 3582 (if (not (ad-is-advised function))
3570 (if (ad-get-orig-definition function) 3583 (error "ad-activate: `%s' is not advised" function)
3571 (if (not (ad-has-any-advice function)) 3584 (ad-handle-definition function)
3572 (ad-unadvise function) 3585 ;; Just return for forward advised and not yet defined functions:
3573 ;; Otherwise activate the advice: 3586 (if (ad-get-orig-definition function)
3574 (cond ((ad-has-redefining-advice function) 3587 (if (not (ad-has-any-advice function))
3575 (ad-activate-advised-definition function compile) 3588 (ad-unadvise function)
3576 (ad-set-advice-info-field function 'active t) 3589 ;; Otherwise activate the advice:
3577 (eval (ad-make-hook-form function 'activation)) 3590 (cond ((ad-has-redefining-advice function)
3578 function) 3591 (ad-activate-advised-definition function compile)
3579 ;; Here we are if we have all disabled advices: 3592 (ad-set-advice-info-field function 'active t)
3580 (t (ad-deactivate function))))))) 3593 (eval (ad-make-hook-form function 'activation))
3594 function)
3595 ;; Here we are if we have all disabled advices:
3596 (t (ad-deactivate function)))))))))
3581 3597
3582 (defun ad-deactivate (function) 3598 (defun ad-deactivate (function)
3583 "Deactivates the advice of an actively advised FUNCTION. 3599 "Deactivates the advice of an actively advised FUNCTION.
3584 If FUNCTION has a proper original definition, then the current 3600 If FUNCTION has a proper original definition, then the current
3585 definition of FUNCTION will be replaced with it. All the advice 3601 definition of FUNCTION will be replaced with it. All the advice
3592 (cond ((ad-is-active function) 3608 (cond ((ad-is-active function)
3593 (ad-handle-definition function) 3609 (ad-handle-definition function)
3594 (if (not (ad-get-orig-definition function)) 3610 (if (not (ad-get-orig-definition function))
3595 (error "ad-deactivate: `%s' has no original definition" 3611 (error "ad-deactivate: `%s' has no original definition"
3596 function) 3612 function)
3597 (ad-real-fset function (ad-get-orig-definition function)) 3613 (ad-safe-fset function (ad-get-orig-definition function))
3598 (ad-set-advice-info-field function 'active nil) 3614 (ad-set-advice-info-field function 'active nil)
3599 (eval (ad-make-hook-form function 'deactivation)) 3615 (eval (ad-make-hook-form function 'deactivation))
3600 function))))) 3616 function)))))
3601 3617
3602 (defun ad-update (function &optional compile) 3618 (defun ad-update (function &optional compile)
3603 "Update the advised definition of FUNCTION if its advice is active. 3619 "Update the advised definition of FUNCTION if its advice is active.
3604 With a prefix argument or if the current definition is compiled compile the 3620 See `ad-activate-on' for documentation on the optional COMPILE argument."
3605 resulting advised definition."
3606 (interactive 3621 (interactive
3607 (list (ad-read-advised-function 3622 (list (ad-read-advised-function
3608 "Update advised definition of: " 'ad-is-active))) 3623 "Update advised definition of: " 'ad-is-active)))
3609 (if (ad-is-active function) 3624 (if (ad-is-active function)
3610 (ad-activate 3625 (ad-activate-on function compile)))
3611 function (or compile (ad-compiled-p (symbol-function function))))))
3612 3626
3613 (defun ad-unadvise (function) 3627 (defun ad-unadvise (function)
3614 "Deactivates FUNCTION and then removes all its advice information. 3628 "Deactivates FUNCTION and then removes all its advice information.
3615 If FUNCTION was not advised this will be a noop." 3629 If FUNCTION was not advised this will be a noop."
3616 (interactive 3630 (interactive
3632 (interactive 3646 (interactive
3633 (list (intern 3647 (list (intern
3634 (completing-read "Recover advised function: " obarray nil t)))) 3648 (completing-read "Recover advised function: " obarray nil t))))
3635 (cond ((ad-is-advised function) 3649 (cond ((ad-is-advised function)
3636 (cond ((ad-get-orig-definition function) 3650 (cond ((ad-get-orig-definition function)
3637 (ad-real-fset function (ad-get-orig-definition function)) 3651 (ad-safe-fset function (ad-get-orig-definition function))
3638 (ad-clear-orig-definition function))) 3652 (ad-clear-orig-definition function)))
3639 (ad-set-advice-info function nil) 3653 (ad-set-advice-info function nil)
3640 (ad-pop-advised-function function)))) 3654 (ad-pop-advised-function function))))
3641 3655
3642 (defun ad-activate-regexp (regexp &optional compile) 3656 (defun ad-activate-regexp (regexp &optional compile)
3643 "Activates functions with an advice name containing a REGEXP match. 3657 "Activates functions with an advice name containing a REGEXP match.
3644 With prefix argument compiles resulting advised definitions." 3658 See `ad-activate-on' for documentation on the optional COMPILE argument."
3645 (interactive 3659 (interactive
3646 (list (ad-read-regexp "Activate via advice regexp: ") 3660 (list (ad-read-regexp "Activate via advice regexp: ")
3647 current-prefix-arg)) 3661 current-prefix-arg))
3648 (ad-do-advised-functions (function) 3662 (ad-do-advised-functions (function)
3649 (if (ad-find-some-advice function 'any regexp) 3663 (if (ad-find-some-advice function 'any regexp)
3650 (ad-activate function compile)))) 3664 (ad-activate-on function compile))))
3651 3665
3652 (defun ad-deactivate-regexp (regexp) 3666 (defun ad-deactivate-regexp (regexp)
3653 "Deactivates functions with an advice name containing REGEXP match." 3667 "Deactivates functions with an advice name containing REGEXP match."
3654 (interactive 3668 (interactive
3655 (list (ad-read-regexp "Deactivate via advice regexp: "))) 3669 (list (ad-read-regexp "Deactivate via advice regexp: ")))
3657 (if (ad-find-some-advice function 'any regexp) 3671 (if (ad-find-some-advice function 'any regexp)
3658 (ad-deactivate function)))) 3672 (ad-deactivate function))))
3659 3673
3660 (defun ad-update-regexp (regexp &optional compile) 3674 (defun ad-update-regexp (regexp &optional compile)
3661 "Updates functions with an advice name containing a REGEXP match. 3675 "Updates functions with an advice name containing a REGEXP match.
3662 With prefix argument compiles resulting advised definitions." 3676 See `ad-activate-on' for documentation on the optional COMPILE argument."
3663 (interactive 3677 (interactive
3664 (list (ad-read-regexp "Update via advice regexp: ") 3678 (list (ad-read-regexp "Update via advice regexp: ")
3665 current-prefix-arg)) 3679 current-prefix-arg))
3666 (ad-do-advised-functions (function) 3680 (ad-do-advised-functions (function)
3667 (if (ad-find-some-advice function 'any regexp) 3681 (if (ad-find-some-advice function 'any regexp)
3668 (ad-update function compile)))) 3682 (ad-update function compile))))
3669 3683
3670 (defun ad-activate-all (&optional compile) 3684 (defun ad-activate-all (&optional compile)
3671 "Activates all currently advised functions. 3685 "Activates all currently advised functions.
3672 With prefix argument compiles resulting advised definitions." 3686 See `ad-activate-on' for documentation on the optional COMPILE argument."
3673 (interactive "P") 3687 (interactive "P")
3674 (ad-do-advised-functions (function) 3688 (ad-do-advised-functions (function)
3675 (ad-activate function))) 3689 (ad-activate-on function compile)))
3676 3690
3677 (defun ad-deactivate-all () 3691 (defun ad-deactivate-all ()
3678 "Deactivates all currently advised functions." 3692 "Deactivates all currently advised functions."
3679 (interactive) 3693 (interactive)
3680 (ad-do-advised-functions (function) 3694 (ad-do-advised-functions (function)
3749 time. This generates a compiled advised definition according to the current 3763 time. This generates a compiled advised definition according to the current
3750 advice state that will be used during activation if appropriate. Only use 3764 advice state that will be used during activation if appropriate. Only use
3751 this if the `defadvice' gets actually compiled. 3765 this if the `defadvice' gets actually compiled.
3752 3766
3753 `freeze': Expands the `defadvice' into a redefining `defun/defmacro' according 3767 `freeze': Expands the `defadvice' into a redefining `defun/defmacro' according
3754 to the current advice state. No other advice information will be saved. 3768 to this particular single advice. No other advice information will be saved.
3755 Frozen advices cannot be undone, they behave like a hard redefinition of 3769 Frozen advices cannot be undone, they behave like a hard redefinition of
3756 the advised function. `freeze' implies `activate' and `preactivate'. The 3770 the advised function. `freeze' implies `activate' and `preactivate'. The
3757 documentation of the advised function can be dumped onto the `DOC' file 3771 documentation of the advised function can be dumped onto the `DOC' file
3758 during preloading. 3772 during preloading.
3759 3773
3789 name (memq 'protect flags) 3803 name (memq 'protect flags)
3790 (not (memq 'disable flags)) 3804 (not (memq 'disable flags))
3791 (` (advice lambda (, arglist) (,@ body))))) 3805 (` (advice lambda (, arglist) (,@ body)))))
3792 (preactivation (if (memq 'preactivate flags) 3806 (preactivation (if (memq 'preactivate flags)
3793 (ad-preactivate-advice 3807 (ad-preactivate-advice
3794 function advice class position))) 3808 function advice class position))))
3795 unique-origname
3796 (redefinition
3797 (if (memq 'freeze flags)
3798 (ad-with-originals (ad-make-advised-definition-docstring
3799 ad-make-origname)
3800 ;; Make sure we construct the actual docstring:
3801 (fset 'ad-make-advised-definition-docstring
3802 'ad-make-freeze-docstring)
3803 ;; With a unique origname we can have multiple freeze advices
3804 ;; for the same function, each overloading the previous one:
3805 (setq unique-origname
3806 (intern (format "%s-%s-%s"
3807 (ad-make-origname function) class name)))
3808 (fset 'ad-make-origname '(lambda (x) unique-origname))
3809 (if (not (ad-has-proper-definition function))
3810 (error
3811 "defadvice: `freeze' needs proper definition of `%s'"
3812 function))
3813 (ad-preactivate-advice function advice class position)))))
3814 ;; Now for the things to be done at evaluation time: 3809 ;; Now for the things to be done at evaluation time:
3815 (if redefinition 3810 (if (memq 'freeze flags)
3816 ;; jwz's idea: Freeze the advised definition into a dumpable 3811 ;; jwz's idea: Freeze the advised definition into a dumpable
3817 ;; defun/defmacro whose docs can be written to the DOC file: 3812 ;; defun/defmacro whose docs can be written to the DOC file:
3818 (let* ((macro-p (ad-macro-p (car redefinition))) 3813 (ad-make-freeze-definition function advice class position)
3819 (body (cdr (if macro-p
3820 (ad-lambdafy (car redefinition))
3821 (car redefinition)))))
3822 (` (progn
3823 (if (not (fboundp '(, unique-origname)))
3824 (fset '(, unique-origname) (symbol-function '(, function))))
3825 ((, (if macro-p 'defmacro 'defun))
3826 (, function)
3827 (,@ body)))))
3828 ;; the normal case: 3814 ;; the normal case:
3829 (` (progn 3815 (` (progn
3830 (ad-add-advice '(, function) '(, advice) '(, class) '(, position)) 3816 (ad-add-advice '(, function) '(, advice) '(, class) '(, position))
3831 (,@ (if preactivation 3817 (,@ (if preactivation
3832 (` ((ad-set-cache 3818 (` ((ad-set-cache
3839 (car preactivation))))))) 3825 (car preactivation)))))))
3840 (t (` (function 3826 (t (` (function
3841 (, (car preactivation))))))) 3827 (, (car preactivation)))))))
3842 '(, (car (cdr preactivation)))))))) 3828 '(, (car (cdr preactivation))))))))
3843 (,@ (if (memq 'activate flags) 3829 (,@ (if (memq 'activate flags)
3844 (` ((ad-activate '(, function) 3830 (` ((ad-activate-on '(, function)
3845 (, (if (memq 'compile flags) t))))))) 3831 (, (if (memq 'compile flags) t)))))))
3846 '(, function)))))) 3832 '(, function))))))
3847 3833
3848 3834
3849 ;; @@ Tools: 3835 ;; @@ Tools:
3850 ;; ========= 3836 ;; =========
3872 (setq index -1) 3858 (setq index -1)
3873 (mapcar 3859 (mapcar
3874 (function 3860 (function
3875 (lambda (function) 3861 (lambda (function)
3876 (setq index (1+ index)) 3862 (setq index (1+ index))
3877 (` (ad-real-fset 3863 (` (ad-safe-fset
3878 '(, function) 3864 '(, function)
3879 (or (ad-get-orig-definition '(, function)) 3865 (or (ad-get-orig-definition '(, function))
3880 (, (car (nth index current-bindings)))))))) 3866 (, (car (nth index current-bindings))))))))
3881 functions))) 3867 functions)))
3882 (,@ body)) 3868 (,@ body))
3886 (setq index -1) 3872 (setq index -1)
3887 (mapcar 3873 (mapcar
3888 (function 3874 (function
3889 (lambda (function) 3875 (lambda (function)
3890 (setq index (1+ index)) 3876 (setq index (1+ index))
3891 (` (ad-real-fset 3877 (` (ad-safe-fset
3892 '(, function) 3878 '(, function)
3893 (, (car (nth index current-bindings))))))) 3879 (, (car (nth index current-bindings)))))))
3894 functions)))))))) 3880 functions))))))))
3895 3881
3896 (if (not (get 'ad-with-originals 'lisp-indent-hook)) 3882 (if (not (get 'ad-with-originals 'lisp-indent-hook))
3897 (put 'ad-with-originals 'lisp-indent-hook 1)) 3883 (put 'ad-with-originals 'lisp-indent-hook 1))
3898 3884
3899 3885
3900 ;; @@ Advising `defun', `defmacro', `fset' and `documentation' 3886 ;; @@ Advising `documentation':
3901 ;; =========================================================== 3887 ;; ============================
3902 ;; Use the advice mechanism to advise defun/defmacro/fset so we can forward 3888 ;; Use the advice mechanism to advise `documentation' to make it
3903 ;; advise functions that might be defined later during load/autoload. 3889 ;; generate proper documentation strings for advised definitions:
3904 ;; Enabling forward advice was the original motivation for doing this, it
3905 ;; has now been generalized to running definition hooks so other packages
3906 ;; can make use of this sort of functionality too.
3907
3908 (defvar ad-defined-function nil)
3909
3910 (defun ad-activate-defined-function (&optional function)
3911 "Activates the advice of an advised and defined FUNCTION.
3912 If the current definition of FUNCTION is byte-compiled then the advised
3913 definition will be compiled too. FUNCTION defaults to the value of
3914 `ad-defined-function'."
3915 (if (and (null function)
3916 ad-defined-function)
3917 (setq function ad-defined-function))
3918 (if (and (ad-is-advised function)
3919 (ad-real-definition function))
3920 (ad-activate function (ad-compiled-p (symbol-function function)))))
3921
3922 (defvar ad-advised-definers
3923 '(defun defmacro fset defalias define-function))
3924
3925 (defadvice defun (after ad-definition-hooks first disable preact)
3926 "Whenever a function gets re/defined with `defun' all hook functions
3927 in `ad-definition-hooks' will be run after the re/definition with
3928 `ad-defined-function' bound to the name of the function."
3929 (let ((ad-defined-function (ad-get-arg 0)))
3930 (run-hooks 'ad-definition-hooks)))
3931
3932 (defadvice defmacro (after ad-definition-hooks first disable preact)
3933 "Whenever a macro gets re/defined with `defmacro' all hook functions
3934 in `ad-definition-hooks' will be run after the re/definition with
3935 `ad-defined-function' bound to the name of the function."
3936 (let ((ad-defined-function (ad-get-arg 0)))
3937 (run-hooks 'ad-definition-hooks)))
3938
3939 (defadvice fset (after ad-definition-hooks first disable preact)
3940 "Whenever a function gets re/defined with `fset' all hook functions
3941 in `ad-definition-hooks' will be run after the re/definition with
3942 `ad-defined-function' bound to the name of the function. This advice was
3943 mainly created to handle forward-advice for byte-compiled files created
3944 by jwz's byte-compiler used in Lemacs.
3945 CAUTION: If you need the primitive `fset' behavior either deactivate
3946 its advice or use `ad-real-fset' instead!"
3947 (let ((ad-defined-function (ad-get-arg 0)))
3948 (run-hooks 'ad-definition-hooks)))
3949
3950 ;; In Lemacs this is just a noop:
3951 (defadvice defalias (after ad-definition-hooks first disable preact)
3952 "Whenever a function gets re/defined with `defalias' all hook functions
3953 in `ad-definition-hooks' will be run after the re/definition with
3954 `ad-defined-function' bound to the name of the function."
3955 (let ((ad-defined-function (ad-get-arg 0)))
3956 ;; The new `byte-compile' uses `defalias' to set the definition which
3957 ;; leads to infinite recursion if it gets to use the advised version
3958 ;; (with `fset' this didn't matter because the compiled `byte-compile'
3959 ;; called it via its byte-code). Should there be a general provision to
3960 ;; avoid recursive application of definition hooks?
3961 (ad-with-originals (defalias)
3962 (run-hooks 'ad-definition-hooks))))
3963
3964 ;; Needed for Emacs (seems to be an identical copy of `defalias', but
3965 ;; it is used in `simple.el' and might be used later, hence, advise it):
3966 (defadvice define-function (after ad-definition-hooks first disable preact)
3967 "Whenever a function gets re/defined with `define-function' all hook
3968 functions in `ad-definition-hooks' will be run after the re/definition with
3969 `ad-defined-function' bound to the name of the function."
3970 (let ((ad-defined-function (ad-get-arg 0)))
3971 (ad-with-originals (define-function)
3972 (run-hooks 'ad-definition-hooks))))
3973 3890
3974 (defadvice documentation (after ad-advised-docstring first disable preact) 3891 (defadvice documentation (after ad-advised-docstring first disable preact)
3975 "Builds an advised docstring if FUNCTION is advised." 3892 "Builds an advised docstring if FUNCTION is advised."
3976 ;; Because we get the function name from the advised docstring 3893 ;; Because we get the function name from the advised docstring
3977 ;; this will work for function names as well as for definitions: 3894 ;; this will work for function names as well as for definitions:
3986 ;; Handle optional `raw' argument: 3903 ;; Handle optional `raw' argument:
3987 (if (not (ad-get-arg 1)) 3904 (if (not (ad-get-arg 1))
3988 (setq ad-return-value 3905 (setq ad-return-value
3989 (substitute-command-keys ad-return-value)))))))) 3906 (substitute-command-keys ad-return-value))))))))
3990 3907
3991 ;; The following two advised functions are a (hopefully temporary) kludge
3992 ;; to fix a problem with the compilation of embedded (or non-top-level)
3993 ;; `defun/defmacro's when automatic activation of advice is enabled. For
3994 ;; the time of the compilation they backdefine `defun/defmacro' to their
3995 ;; original definition to make sure they are not treated as plain macros.
3996 ;; Both advices are forward advices, hence, they will only be activated if
3997 ;; automatic advice activation is enabled, but since that is the actual
3998 ;; situation where we have a problem, we can be sure that the advices will
3999 ;; be active when we need them.
4000
4001 ;; We only need this in Lemacs, because in Emacs it is
4002 ;; now taken care of directly by the byte-compiler:
4003 (cond ((ad-lemacs-p)
4004
4005 (defvar ad-advised-byte-compilers
4006 '(byte-compile-from-buffer byte-compile-top-level))
4007
4008 (defadvice byte-compile-from-buffer (around ad-deactivate-defun-defmacro
4009 first disable preact)
4010 "Deactivates `defun/defmacro' for proper compilation when they are embedded."
4011 (let (;; make sure no `require' starts them again by accident:
4012 (ad-advised-definers '(fset defalias define-function)))
4013 (ad-with-originals (defun defmacro)
4014 ad-do-it)))
4015
4016 (defadvice byte-compile-top-level (around ad-deactivate-defun-defmacro
4017 first disable preact)
4018 "Deactivates `defun/defmacro' for proper compilation when they are embedded."
4019 (let (;; make sure no `require' starts them again by accident:
4020 (ad-advised-definers '(fset defalias define-function)))
4021 (ad-with-originals (defun defmacro)
4022 ad-do-it)))
4023
4024 )) ;; end of cond
4025
4026 ;; Make sure advice-infos are not allocated in pure space
4027 ;; (this might not be necessary anymore):
4028 (ad-dolist (advised-function (cons 'documentation
4029 (append ad-advised-definers
4030 (if (ad-lemacs-p)
4031 ad-advised-byte-compilers))))
4032 (ad-set-advice-info advised-function (ad-copy-advice-info advised-function)))
4033
4034
4035 ;; @@ Forward advice support for jwz's byte-compiler (M-x serious-HACK-mode-on)
4036 ;; ============================================================================
4037 ;; Jamie Zawinski's optimizing byte-compiler used in v19 (and by some daring
4038 ;; folks in v18) produces compiled files that do not define functions via
4039 ;; explicit calls to `defun/defmacro', it rather uses `fset' for functions with
4040 ;; documentation strings, and hunks of byte-code for sets of functions without
4041 ;; any documentation. In Jamie's byte-compiler a series of compiled functions
4042 ;; without docstrings get hunked as
4043 ;; (progn (fset 'f1 <code1>) (fset 'f2 <code2>) ...).
4044 ;; The resulting progn will be compiled and the compiled form will be written
4045 ;; to the compiled file as `(byte-code [progn-code] [constants] [depth])'. To
4046 ;; handle forward advice we have to know when functions get defined so we can
4047 ;; activate any advice there might be. For standard v18 byte-compiled files
4048 ;; we can do this by simply advising `defun/defmacro' because these subrs are
4049 ;; evaluated explicitly when such a file is loaded. For Jamie's v19 compiler
4050 ;; our only choice is to additionally advise `fset' and change the subr
4051 ;; `byte-code' such that it analyzes its byte-code string looking for fset's
4052 ;; when we are currently loading a file. In v19 the general overhead caused
4053 ;; by the advice of `byte-code' shouldn't be too bad, because byte-compiled
4054 ;; functions do not call byte-code explicitly (as done in v18). In v18 this
4055 ;; is a problem because with the changed `byte-code' function function calls
4056 ;; become more expensive.
4057 ;;
4058 ;; Wish-List:
4059 ;; - special defining functions for use in byte-compiled files, e.g.,
4060 ;; `byte-compile-fset' and `byte-code-tl' which do the same as their
4061 ;; standard brothers, but which can be advised for forward advice without
4062 ;; the problems that advising `byte-code' generates.
4063 ;; - More generally, a symbol definition hook that could be used for
4064 ;; forward advice and related purposes.
4065 ;;
4066 ;; Until then: For the analysis of the byte-code string we simply scan it for
4067 ;; an `fset' opcode (M in ascii) that is preceded by two constant references,
4068 ;; the first of which points to the function name and the second to its code.
4069 ;; A constant reference can either be a simple one-byte one, or a three-byte
4070 ;; one if the function has more than 64 constants. The scanning can pretty
4071 ;; efficiently be done with a regular expression. Here it goes:
4072
4073 ;; Have to hardcode these opcodes if I don't
4074 ;; want to require the byte-compiler:
4075 (defvar byte-constant 192)
4076 (defvar byte-constant-limit 64)
4077 (defvar byte-constant2 129)
4078 (defvar byte-fset 77)
4079
4080 ;; Matches a byte-compiled fset operation with two constant arguments:
4081 (defvar ad-byte-code-fset-regexp
4082 (let* ((constant-reference
4083 (format "[%s-%s]"
4084 (char-to-string byte-constant)
4085 (char-to-string (+ byte-constant (1- byte-constant-limit)))))
4086 (constant2-reference
4087 ;; \0 makes it necessary to use concat instead of format in 18.57:
4088 (concat (char-to-string byte-constant2) "[\0-\377][\0-\377]"))
4089 (fset-opcode (char-to-string byte-fset)))
4090 (concat "\\(" constant-reference "\\|" constant2-reference "\\)"
4091 "\\(" constant-reference "\\|" constant2-reference "\\)"
4092 fset-opcode)))
4093
4094 (defun ad-find-fset-in-byte-code (code constants start)
4095 ;;"Finds the first two-constant fset operation in CODE after START.
4096 ;;Returns a three element list consisting of the name of the defined
4097 ;;function, its code (both taken from the CONSTANTS vector), and an
4098 ;;advanced start index."
4099 (let ((start
4100 ;; The odd case that this regexp matches something that isn't an
4101 ;; actual fset operation is handled by additional tests and a
4102 ;; condition handler in ad-scan-byte-code-for-fsets:
4103 (string-match ad-byte-code-fset-regexp code start))
4104 name-index code-index)
4105 (cond (start
4106 (cond ((= (aref code start) byte-constant2)
4107 (setq name-index
4108 (+ (aref code (setq start (1+ start)))
4109 (* (aref code (setq start (1+ start))) 256)))
4110 (setq start (1+ start)))
4111 (t (setq name-index (- (aref code start) byte-constant))
4112 (setq start (1+ start))))
4113 (cond ((= (aref code start) byte-constant2)
4114 (setq code-index
4115 (+ (aref code (setq start (1+ start)))
4116 (* (aref code (setq start (1+ start))) 256)))
4117 (setq start (1+ start)))
4118 (t (setq code-index (- (aref code start) byte-constant))
4119 (setq start (1+ start))))
4120 (list (aref constants name-index)
4121 (aref constants code-index)
4122 ;; start points to fset opcode:
4123 start))
4124 (t nil))))
4125
4126 (defun ad-scan-byte-code-for-fsets (ad-code ad-constants)
4127 ;; In case anything in here goes wrong we reset `byte-code' to its real
4128 ;; identity. In particular, the handler of the condition-case uses
4129 ;; `byte-code', so it better be the real one if we have an error:
4130 (ad-real-fset 'byte-code (symbol-function 'ad-real-byte-code))
4131 (condition-case nil
4132 (let ((fset-args '(0 0 0)))
4133 (while (setq fset-args (ad-find-fset-in-byte-code
4134 ad-code ad-constants
4135 (car (cdr (cdr fset-args)))))
4136 (if (and (symbolp (car fset-args))
4137 (fboundp (car fset-args))
4138 (eq (symbol-function (car fset-args))
4139 (car (cdr fset-args))))
4140 ;; We've found an fset that was executed during this call
4141 ;; to byte-code, and whose definition is still eq to the
4142 ;; current definition of the defined function:
4143 (let ((ad-defined-function (car fset-args)))
4144 (run-hooks 'ad-definition-hooks))))
4145 ;; Everything worked fine, readvise `byte-code':
4146 (ad-real-fset 'byte-code (symbol-function 'ad-advised-byte-code)))
4147 (error nil)))
4148
4149 ;; CAUTION: Don't try this at home!! Changing `byte-code' is a
4150 ;; pretty suicidal activity.
4151 ;; To allow v19 forward advice we cannot advise `byte-code' as a subr as
4152 ;; we did for `defun' etc., because `ad-subr-args' of the advised
4153 ;; `byte-code' would shield references to `ad-subr-args' in the body of
4154 ;; v18 compiled advised subrs such as `defun', and, more importantly, the
4155 ;; changed version of `byte-code' has to be as small and efficient as
4156 ;; possible because it is used in every call to a compiled function.
4157 ;; Hence, we previously saved its original definition and redefine it as
4158 ;; the following function - yuck:
4159
4160 ;; The arguments will scope around the body of every byte-compiled
4161 ;; function, hence they have to be obscure enough to not be equal to any
4162 ;; global or argument variable referenced by any compiled function:
4163 (defun ad-advised-byte-code (ad-cOdE ad-cOnStAnTs ad-dEpTh)
4164 "Modified version of `byte-code' subr used by the Advice package.
4165 `byte-code' has been modified to allow automatic activation of forward
4166 advice for functions that are defined in byte-compiled files.
4167 See `ad-real-byte-code' for original documentation."
4168 (prog1 (ad-real-byte-code ad-cOdE ad-cOnStAnTs ad-dEpTh)
4169 (if load-in-progress
4170 (ad-scan-byte-code-for-fsets ad-cOdE ad-cOnStAnTs))))
4171
4172 (defun ad-recover-byte-code ()
4173 "Recovers the real `byte-code' functionality."
4174 (interactive)
4175 (ad-real-fset 'byte-code (symbol-function 'ad-real-byte-code)))
4176
4177 (defun ad-enable-definition-hooks ()
4178 ;;"Enables definition hooks by redefining definition primitives.
4179 ;;Activates the advice of defun/defmacro/fset and redefines `byte-code'.
4180 ;;Redefining these primitives might lead to problems. Use
4181 ;;`ad-disable-definition-hooks' or `ad-stop-advice' in such a case
4182 ;;to establish a safe state."
4183 (ad-dolist (definer ad-advised-definers)
4184 (ad-enable-advice definer 'after 'ad-definition-hooks)
4185 (ad-activate definer 'compile))
4186 (if (ad-lemacs-p)
4187 (ad-dolist (byte-compiler ad-advised-byte-compilers)
4188 (ad-enable-advice byte-compiler 'around 'ad-deactivate-defun-defmacro)
4189 (ad-activate byte-compiler 'compile)))
4190 ;; Now redefine byte-code...
4191 (ad-real-fset 'byte-code (symbol-function 'ad-advised-byte-code)))
4192
4193 (defun ad-disable-definition-hooks ()
4194 ;;"Disables definition hooks by resetting definition primitives."
4195 (ad-recover-byte-code)
4196 (ad-dolist (definer ad-advised-definers)
4197 (ad-disable-advice definer 'after 'ad-definition-hooks)
4198 (ad-update definer))
4199 (if (ad-lemacs-p)
4200 (ad-dolist (byte-compiler ad-advised-byte-compilers)
4201 (ad-disable-advice byte-compiler 'around 'ad-deactivate-defun-defmacro)
4202 (ad-update byte-compiler 'compile))))
4203
4204 3908
4205 ;; @@ Starting, stopping and recovering from the advice package magic: 3909 ;; @@ Starting, stopping and recovering from the advice package magic:
4206 ;; =================================================================== 3910 ;; ===================================================================
4207 3911
4208 ;;;###autoload
4209 (defun ad-start-advice () 3912 (defun ad-start-advice ()
4210 "Redefines some primitives to start the advice magic. 3913 "Starts the automatic advice handling magic."
4211 If `ad-activate-on-definition' is t then advice information will
4212 automatically get activated whenever an advised function gets defined or
4213 redefined. This will enable goodies such as forward advice and
4214 automatically enable function definition hooks. If its value is nil but
4215 the value of `ad-enable-definition-hooks' is t then definition hooks
4216 will be enabled without having automatic advice activation, otherwise
4217 function definition hooks will be disabled too. If definition hooks are
4218 enabled then functions stored in `ad-definition-hooks' are run whenever
4219 a function gets defined or redefined."
4220 (interactive) 3914 (interactive)
3915 ;; Advising `ad-activate' means death!!
3916 (ad-set-advice-info 'ad-activate nil)
3917 (ad-safe-fset 'ad-activate 'ad-activate-on)
4221 (ad-enable-advice 'documentation 'after 'ad-advised-docstring) 3918 (ad-enable-advice 'documentation 'after 'ad-advised-docstring)
4222 (ad-activate 'documentation 'compile) 3919 (ad-activate-on 'documentation 'compile))
4223 (if (or ad-activate-on-definition
4224 ad-enable-definition-hooks)
4225 (ad-enable-definition-hooks)
4226 (ad-disable-definition-hooks))
4227 (setq ad-definition-hooks
4228 (if ad-activate-on-definition
4229 (if (memq 'ad-activate-defined-function ad-definition-hooks)
4230 ad-definition-hooks
4231 (cons 'ad-activate-defined-function ad-definition-hooks))
4232 (delq 'ad-activate-defined-function ad-definition-hooks))))
4233 3920
4234 (defun ad-stop-advice () 3921 (defun ad-stop-advice ()
4235 "Undefines some primitives to stop the advice magic. 3922 "Stops the automatic advice handling magic.
4236 This can also be used to recover from advice related emergencies." 3923 You should only need this in case of Advice-related emergencies."
4237 (interactive) 3924 (interactive)
4238 (ad-recover-byte-code) 3925 ;; Advising `ad-activate' means death!!
3926 (ad-set-advice-info 'ad-activate nil)
4239 (ad-disable-advice 'documentation 'after 'ad-advised-docstring) 3927 (ad-disable-advice 'documentation 'after 'ad-advised-docstring)
4240 (ad-update 'documentation) 3928 (ad-update 'documentation)
4241 (ad-disable-definition-hooks) 3929 (ad-safe-fset 'ad-activate 'ad-activate-off))
4242 (setq ad-definition-hooks
4243 (delq 'ad-activate-defined-function ad-definition-hooks)))
4244 3930
4245 (defun ad-recover-normality () 3931 (defun ad-recover-normality ()
4246 "Undoes all advice related redefinitions and unadvises everything. 3932 "Undoes all advice related redefinitions and unadvises everything.
4247 Use only in REAL emergencies." 3933 Use only in REAL emergencies."
4248 (interactive) 3934 (interactive)
4249 (ad-recover-byte-code) 3935 ;; Advising `ad-activate' means death!!
3936 (ad-set-advice-info 'ad-activate nil)
3937 (ad-safe-fset 'ad-activate 'ad-activate-off)
4250 (ad-recover-all) 3938 (ad-recover-all)
4251 (setq ad-advised-functions nil)) 3939 (setq ad-advised-functions nil))
4252 3940
4253 (if (and ad-start-advice-on-load 3941 ;; Until the Advice-related changes to `data.c' are part of Lemacs we
4254 ;; ...but only if we are compiled: 3942 ;; have to load the old implementation of advice activation hooks:
4255 (ad-compiled-p (symbol-function 'ad-start-advice))) 3943 (if (ad-lemacs-p)
4256 (ad-start-advice)) 3944 (require 'ad-hooks))
3945
3946 (ad-start-advice)
4257 3947
4258 (provide 'advice) 3948 (provide 'advice)
4259 3949
4260 ;;; advice.el ends here 3950 ;;; advice.el ends here
4261