diff options
| author | Stefan Monnier | 2022-04-07 15:59:09 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-04-07 15:59:09 -0400 |
| commit | 39e8fd357dd0a1f3776c05eee2cc5be451686712 (patch) | |
| tree | 7783c644dc02cef24ebb231d3aeb20292b0ec07d /src | |
| parent | 3b411417086ceb2ce3838160d01c6f250e47bbf3 (diff) | |
| download | emacs-39e8fd357dd0a1f3776c05eee2cc5be451686712.tar.gz emacs-39e8fd357dd0a1f3776c05eee2cc5be451686712.zip | |
OClosure: New function `function-documentation`
As mentioned in the original OClosure commit, OClosures (ab)use the
bytecode's docstring slot to hold the OClosure's type. This currently
prevents OClosures from having their own docstring.
Introduce a new generic function `function-documentation` to fetch the
docstring of a function, which can then be implemented in various
different ways depending on the OClosure's type.
* lisp/simple.el (function-documentation): New generic function.
(bad-package-check): Strength-reduce `eval` to `symbol-value`.
* src/doc.c (Fdocumentation): Use it.
* lisp/emacs-lisp/oclosure.el (oclosure--accessor-docstring): New function.
* test/lisp/emacs-lisp/oclosure-tests.el (oclosure-test):
Add test for accessor's docstrings.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc.c | 50 |
1 files changed, 1 insertions, 49 deletions
| @@ -341,56 +341,8 @@ string is passed through `substitute-command-keys'. */) | |||
| 341 | else if (MODULE_FUNCTIONP (fun)) | 341 | else if (MODULE_FUNCTIONP (fun)) |
| 342 | doc = module_function_documentation (XMODULE_FUNCTION (fun)); | 342 | doc = module_function_documentation (XMODULE_FUNCTION (fun)); |
| 343 | #endif | 343 | #endif |
| 344 | else if (COMPILEDP (fun)) | ||
| 345 | { | ||
| 346 | if (PVSIZE (fun) <= COMPILED_DOC_STRING) | ||
| 347 | return Qnil; | ||
| 348 | else | ||
| 349 | { | ||
| 350 | Lisp_Object tem = AREF (fun, COMPILED_DOC_STRING); | ||
| 351 | if (STRINGP (tem)) | ||
| 352 | doc = tem; | ||
| 353 | else if (FIXNATP (tem) || CONSP (tem)) | ||
| 354 | doc = tem; | ||
| 355 | else | ||
| 356 | return Qnil; | ||
| 357 | } | ||
| 358 | } | ||
| 359 | else if (STRINGP (fun) || VECTORP (fun)) | ||
| 360 | { | ||
| 361 | return build_string ("Keyboard macro."); | ||
| 362 | } | ||
| 363 | else if (CONSP (fun)) | ||
| 364 | { | ||
| 365 | Lisp_Object funcar = XCAR (fun); | ||
| 366 | if (!SYMBOLP (funcar)) | ||
| 367 | xsignal1 (Qinvalid_function, fun); | ||
| 368 | else if (EQ (funcar, Qkeymap)) | ||
| 369 | return build_string ("Prefix command (definition is a keymap associating keystrokes with commands)."); | ||
| 370 | else if (EQ (funcar, Qlambda) | ||
| 371 | || (EQ (funcar, Qclosure) && (fun = XCDR (fun), 1)) | ||
| 372 | || EQ (funcar, Qautoload)) | ||
| 373 | { | ||
| 374 | Lisp_Object tem1 = Fcdr (Fcdr (fun)); | ||
| 375 | Lisp_Object tem = Fcar (tem1); | ||
| 376 | if (STRINGP (tem)) | ||
| 377 | doc = tem; | ||
| 378 | /* Handle a doc reference--but these never come last | ||
| 379 | in the function body, so reject them if they are last. */ | ||
| 380 | else if ((FIXNATP (tem) || (CONSP (tem) && FIXNUMP (XCDR (tem)))) | ||
| 381 | && !NILP (XCDR (tem1))) | ||
| 382 | doc = tem; | ||
| 383 | else | ||
| 384 | return Qnil; | ||
| 385 | } | ||
| 386 | else | ||
| 387 | goto oops; | ||
| 388 | } | ||
| 389 | else | 344 | else |
| 390 | { | 345 | doc = call1 (intern ("function-documentation"), fun); |
| 391 | oops: | ||
| 392 | xsignal1 (Qinvalid_function, fun); | ||
| 393 | } | ||
| 394 | 346 | ||
| 395 | /* If DOC is 0, it's typically because of a dumped file missing | 347 | /* If DOC is 0, it's typically because of a dumped file missing |
| 396 | from the DOC file (bug in src/Makefile.in). */ | 348 | from the DOC file (bug in src/Makefile.in). */ |