aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorStefan Monnier2022-01-31 11:07:06 -0500
committerStefan Monnier2022-01-31 11:07:26 -0500
commit1d1b664fbb9232aa40d8daa54a689cfd63d38aa9 (patch)
tree164ad10242c8566c3c8fa1d0c12c50804f82d791 /src/data.c
parent90bbf27f02b1e7bf9cc0f0206313795c210c565b (diff)
downloademacs-1d1b664fbb9232aa40d8daa54a689cfd63d38aa9.tar.gz
emacs-1d1b664fbb9232aa40d8daa54a689cfd63d38aa9.zip
(function-history): New symbol property (bug#53632)
Rework the code we have in Fdefalias that tries to keep track of definitions so as to be able to undo them later. We used to store in `load-history` when an autoload is redefined as a non-autoload and in the `autoload` symbol property we used to store the autoload data that used to be used before it got overriden. Instead, store the history of the function definition of a symbol in its `function-history` symbol property. To make this list cheap in the default case, the latest value is not stored in the list (since it's in the `symbol-function`) and neither is the first file. So if there's only been a single definition (the most common case), the list is empty and the property is just not present at all. The patch also gets rid of the `autoload` vs `defun` distinction in `load-history` which seems unnecessary (a significant part of the motivation for this patch was to get rid of the special handling of autoloads in this part of the code). * src/data.c (add_to_function_history): New function. (defalias): Use it. Don't add the `t` entries for autoloads and always use `defun` regardless of the kind of definition. Change `Vautoload_queue` to only hold the function symbols since the rest is now available from `function-history`. * src/eval.c (un_autoload): Adjust accordingly. * src/lread.c (load-history): Udate docstring. * lisp/loadhist.el (loadhist-unload-filename): New var. (unload-feature): Bind it. (loadhist-unload-element): Document its availability. (loadhist--restore-autoload): Delete var. (loadhist--unload-function): Delete function. (loadhist-unload-element): Delete the `t` and `autoload` methods. Rewrite the `defun` method using `function-history`. * lisp/help-fns.el: Require `seq`. (help-fns--autoloaded-p): Rewrite. (help-fns-function-description-header): Adjust call accordingly. * doc/lispref/loading.texi (Where Defined): Remove `autoload` and `t` entries from `load-history` since we don't generate them any more. Document the `function-history` which replaces the `autoload` property. (Unloading): Adjust symbol property name accordingly. * test/lisp/loadhist-resources/loadhist--bar.el: * test/lisp/loadhist-resources/loadhist--foo.el: New files. * test/lisp/loadhist-tests.el (loadhist-tests-unload-feature-nested) (loadhist-tests-unload-feature-notnested): New tests.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/data.c b/src/data.c
index a5a76a27554..95d29ac9e98 100644
--- a/src/data.c
+++ b/src/data.c
@@ -859,6 +859,43 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
859 return definition; 859 return definition;
860} 860}
861 861
862static void
863add_to_function_history (Lisp_Object symbol, Lisp_Object olddef)
864{
865 eassert (!NILP (olddef));
866
867 Lisp_Object past = Fget (symbol, Qfunction_history);
868 Lisp_Object file = Qnil;
869 /* FIXME: Sadly, `Vload_file_name` gives less precise information
870 (it's sometimes non-nil when it shoujld be nil). */
871 Lisp_Object tail = Vcurrent_load_list;
872 FOR_EACH_TAIL_SAFE (tail)
873 if (NILP (XCDR (tail)) && STRINGP (XCAR (tail)))
874 file = XCAR (tail);
875
876 Lisp_Object tem = Fplist_member (past, file);
877 if (!NILP (tem))
878 { /* New def from a file used before.
879 Overwrite the previous record associated with this file. */
880 if (EQ (tem, past))
881 /* The new def is from the same file as the last change, so
882 there's nothing to do: unloading the file should revert to
883 the status before the last change rather than before this load. */
884 return;
885 Lisp_Object pastlen = Flength (past);
886 Lisp_Object temlen = Flength (tem);
887 EMACS_INT tempos = XFIXNUM (pastlen) - XFIXNUM (temlen);
888 eassert (tempos > 1);
889 Lisp_Object prev = Fnthcdr (make_fixnum (tempos - 2), past);
890 /* Remove the previous info for this file.
891 E.g. change `hist` from (... OTHERFILE DEF3 THISFILE DEF2 ...)
892 to (... OTHERFILE DEF2). */
893 XSETCDR (prev, XCDR (tem));
894 }
895 /* Push new def from new file. */
896 Fput (symbol, Qfunction_history, Fcons (file, Fcons (olddef, past)));
897}
898
862void 899void
863defalias (Lisp_Object symbol, Lisp_Object definition) 900defalias (Lisp_Object symbol, Lisp_Object definition)
864{ 901{
@@ -866,19 +903,19 @@ defalias (Lisp_Object symbol, Lisp_Object definition)
866 bool autoload = AUTOLOADP (definition); 903 bool autoload = AUTOLOADP (definition);
867 if (!will_dump_p () || !autoload) 904 if (!will_dump_p () || !autoload)
868 { /* Only add autoload entries after dumping, because the ones before are 905 { /* Only add autoload entries after dumping, because the ones before are
869 not useful and else we get loads of them from the loaddefs.el. */ 906 not useful and else we get loads of them from the loaddefs.el.
870 Lisp_Object function = XSYMBOL (symbol)->u.s.function; 907 That saves us about 110KB in the pdmp file (Jan 2022). */
871 908 LOADHIST_ATTACH (Fcons (Qdefun, symbol));
872 if (AUTOLOADP (function)) 909 }
873 /* Remember that the function was already an autoload. */ 910 }
874 LOADHIST_ATTACH (Fcons (Qt, symbol));
875 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
876
877 if (!NILP (Vautoload_queue) && !NILP (function))
878 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
879 911
880 if (AUTOLOADP (function)) 912 {
881 Fput (symbol, Qautoload, XCDR (function)); 913 Lisp_Object olddef = XSYMBOL (symbol)->u.s.function;
914 if (!NILP (olddef))
915 {
916 if (!NILP (Vautoload_queue))
917 Vautoload_queue = Fcons (symbol, Vautoload_queue);
918 add_to_function_history (symbol, olddef);
882 } 919 }
883 } 920 }
884 921
@@ -4171,6 +4208,7 @@ syms_of_data (void)
4171 4208
4172 DEFSYM (Qinteractive_form, "interactive-form"); 4209 DEFSYM (Qinteractive_form, "interactive-form");
4173 DEFSYM (Qdefalias_fset_function, "defalias-fset-function"); 4210 DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
4211 DEFSYM (Qfunction_history, "function-history");
4174 4212
4175 DEFSYM (Qbyte_code_function_p, "byte-code-function-p"); 4213 DEFSYM (Qbyte_code_function_p, "byte-code-function-p");
4176 4214