diff options
| author | Stefan Monnier | 2024-01-31 18:56:43 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2024-02-02 13:07:53 -0500 |
| commit | e9a668274e441645aed28e8c353187dfed35fcae (patch) | |
| tree | 3c2e2701ce973c49e31895dabbc1a0a1ea84bdfb | |
| parent | e2d1ac2f258a069f950d4df80c8096bfa34081fc (diff) | |
| download | emacs-e9a668274e441645aed28e8c353187dfed35fcae.tar.gz emacs-e9a668274e441645aed28e8c353187dfed35fcae.zip | |
bytecomp.el: Rewrite the way we print dynamic docstrings
We used to print dynamic docstrings "manually" for two reasons:
- References should look like `(#$ . POS)` but `prin1` was unable
to print just `#$` for an sexp.
- `make-docfile` needed to find those docstrings and the object
to which they belonged.
The second point is moot now that we don't use `make-docfile` on
`.elc` files. So this patch lifts the first restriction,
using `print-number-table`.
The rest of the patch then simplifies and regularises the
bytecompiler's generation of dynamic docstrings, which can
now also easily be done for "inner" defvars and other places.
* src/print.c (print_preprocess, print_object): Handle strings in
`print-number-table`.
(Vprint_number_table): Improve docstring.
* lisp/emacs-lisp/bytecomp.el:
(byte-compile--list-with-n): New function.
(byte-compile--docstring-style-warn): Rename from
`byte-compile-docstring-style-warn` and change calling convention.
(byte-compile--\#$, byte-compile--docstrings): New vars.
(byte-compile-close-variables): Bind them.
(byte-compile--docstring): New function.
(byte-compile-from-buffer): Set `byte-compile--\#$`.
(byte-compile-output-file-form): Use `byte-compile--\#$` instead
of special casing specific forms.
(byte-compile--output-docform-recurse, byte-compile-output-docform):
Delete functions.
(byte-compile-file-form-autoload, byte-compile-file-form-defalias)
(byte-compile-file-form-defvar-function, byte-compile-lambda):
Use `byte-compile--docstring` and `byte-compile--list-with-n`.
(byte-compile--declare-var): Add optional `not-toplevel` arg.
(byte-compile-defvar): Add `toplevel` arg. Use `byte-compile--docstring`.
(byte-compile-file-form-defvar): Delegate to `byte-compile-defvar`.
(byte-compile--custom-declare-face): New function. Use it for
`custom-declare-face`.
(byte-compile-file-form-defmumble): Use `byte-compile-output-file-form`
* src/doc.c (Fdocumentation_stringp): New function.
(syms_of_doc): Defsubr it.
(store_function_docstring): Remove left-over code from when we
used DOC for the docstring of some Lisp files.
* lisp/cus-face.el (custom-declare-face): Accept dynamic docstrings.
* lisp/faces.el (face-documentation): Handle dynamic docstrings.
* lisp/help-fns.el (describe-face): Simplify accordingly.
| -rw-r--r-- | lisp/cus-face.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 466 | ||||
| -rw-r--r-- | lisp/faces.el | 4 | ||||
| -rw-r--r-- | lisp/help-fns.el | 5 | ||||
| -rw-r--r-- | src/doc.c | 58 | ||||
| -rw-r--r-- | src/print.c | 19 |
6 files changed, 218 insertions, 336 deletions
diff --git a/lisp/cus-face.el b/lisp/cus-face.el index 0c8b6b0b97c..47afa841f5e 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | (defun custom-declare-face (face spec doc &rest args) | 32 | (defun custom-declare-face (face spec doc &rest args) |
| 33 | "Like `defface', but with FACE evaluated as a normal argument." | 33 | "Like `defface', but with FACE evaluated as a normal argument." |
| 34 | (when (and doc | 34 | (when (and doc |
| 35 | (not (stringp doc))) | 35 | (not (documentation-stringp doc))) |
| 36 | (error "Invalid (or missing) doc string %S" doc)) | 36 | (error "Invalid (or missing) doc string %S" doc)) |
| 37 | (unless (get face 'face-defface-spec) | 37 | (unless (get face 'face-defface-spec) |
| 38 | (face-spec-set face (purecopy spec) 'face-defface-spec) | 38 | (face-spec-set face (purecopy spec) 'face-defface-spec) |
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index becc77f504a..6e66771658e 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -345,7 +345,7 @@ A value of `all' really means all." | |||
| 345 | '(docstrings-non-ascii-quotes) | 345 | '(docstrings-non-ascii-quotes) |
| 346 | "List of warning types that are only enabled during Emacs builds. | 346 | "List of warning types that are only enabled during Emacs builds. |
| 347 | This is typically either warning types that are being phased in | 347 | This is typically either warning types that are being phased in |
| 348 | (but shouldn't be enabled for packages yet), or that are only relevant | 348 | \(but shouldn't be enabled for packages yet), or that are only relevant |
| 349 | for the Emacs build itself.") | 349 | for the Emacs build itself.") |
| 350 | 350 | ||
| 351 | (defvar byte-compile--suppressed-warnings nil | 351 | (defvar byte-compile--suppressed-warnings nil |
| @@ -1740,68 +1740,82 @@ Also ignore URLs." | |||
| 1740 | The byte-compiler will emit a warning for documentation strings | 1740 | The byte-compiler will emit a warning for documentation strings |
| 1741 | containing lines wider than this. If `fill-column' has a larger | 1741 | containing lines wider than this. If `fill-column' has a larger |
| 1742 | value, it will override this variable." | 1742 | value, it will override this variable." |
| 1743 | :group 'bytecomp | ||
| 1744 | :type 'natnum | 1743 | :type 'natnum |
| 1745 | :safe #'natnump | 1744 | :safe #'natnump |
| 1746 | :version "28.1") | 1745 | :version "28.1") |
| 1747 | 1746 | ||
| 1748 | (define-obsolete-function-alias 'byte-compile-docstring-length-warn | 1747 | (defun byte-compile--list-with-n (list n elem) |
| 1749 | 'byte-compile-docstring-style-warn "29.1") | 1748 | "Return LIST with its Nth element replaced by ELEM." |
| 1750 | 1749 | (if (eq elem (nth n list)) | |
| 1751 | (defun byte-compile-docstring-style-warn (form) | 1750 | list |
| 1752 | "Warn if there are stylistic problems with the docstring in FORM. | 1751 | (nconc (take n list) |
| 1753 | Warn if documentation string of FORM is too wide. | 1752 | (list elem) |
| 1753 | (nthcdr (1+ n) list)))) | ||
| 1754 | |||
| 1755 | (defun byte-compile--docstring-style-warn (docs kind name) | ||
| 1756 | "Warn if there are stylistic problems in the docstring DOCS. | ||
| 1757 | Warn if documentation string is too wide. | ||
| 1754 | It is too wide if it has any lines longer than the largest of | 1758 | It is too wide if it has any lines longer than the largest of |
| 1755 | `fill-column' and `byte-compile-docstring-max-column'." | 1759 | `fill-column' and `byte-compile-docstring-max-column'." |
| 1756 | (when (byte-compile-warning-enabled-p 'docstrings) | 1760 | (when (byte-compile-warning-enabled-p 'docstrings) |
| 1757 | (let* ((kind nil) (name nil) (docs nil) | 1761 | (let* ((name (if (eq (car-safe name) 'quote) (cadr name) name)) |
| 1758 | (prefix (lambda () | 1762 | (prefix (lambda () |
| 1759 | (format "%s%s" | 1763 | (format "%s%s" |
| 1760 | kind | 1764 | kind |
| 1761 | (if name (format-message " `%s' " name) ""))))) | 1765 | (if name (format-message " `%S' " name) ""))))) |
| 1762 | (pcase (car form) | 1766 | (let ((col (max byte-compile-docstring-max-column fill-column))) |
| 1763 | ((or 'autoload 'custom-declare-variable 'defalias | 1767 | (when (and (byte-compile-warning-enabled-p 'docstrings-wide) |
| 1764 | 'defconst 'define-abbrev-table | 1768 | (byte-compile--wide-docstring-p docs col)) |
| 1765 | 'defvar 'defvaralias | 1769 | (byte-compile-warn-x |
| 1766 | 'custom-declare-face) | 1770 | name |
| 1767 | (setq kind (nth 0 form)) | 1771 | "%sdocstring wider than %s characters" (funcall prefix) col))) |
| 1768 | (setq name (nth 1 form)) | 1772 | ;; There's a "naked" ' character before a symbol/list, so it |
| 1769 | (when (and (consp name) (eq (car name) 'quote)) | 1773 | ;; should probably be quoted with \=. |
| 1770 | (setq name (cadr name))) | 1774 | (when (string-match-p (rx (| (in " \t") bol) |
| 1771 | (setq docs (nth 3 form))) | 1775 | (? (in "\"#")) |
| 1772 | ('lambda | 1776 | "'" |
| 1773 | (setq kind "") ; can't be "function", unfortunately | 1777 | (in "A-Za-z" "(")) |
| 1774 | (setq docs (nth 2 form)))) | 1778 | docs) |
| 1775 | (when (and kind docs (stringp docs)) | 1779 | (byte-compile-warn-x |
| 1776 | (let ((col (max byte-compile-docstring-max-column fill-column))) | 1780 | name |
| 1777 | (when (and (byte-compile-warning-enabled-p 'docstrings-wide) | 1781 | (concat "%sdocstring has wrong usage of unescaped single quotes" |
| 1778 | (byte-compile--wide-docstring-p docs col)) | 1782 | " (use \\=%c or different quoting such as %c...%c)") |
| 1779 | (byte-compile-warn-x | 1783 | (funcall prefix) ?' ?` ?')) |
| 1780 | name | 1784 | ;; There's a "Unicode quote" in the string -- it should probably |
| 1781 | "%sdocstring wider than %s characters" (funcall prefix) col))) | 1785 | ;; be an ASCII one instead. |
| 1782 | ;; There's a "naked" ' character before a symbol/list, so it | 1786 | (when (byte-compile-warning-enabled-p 'docstrings-non-ascii-quotes) |
| 1783 | ;; should probably be quoted with \=. | 1787 | (when (string-match-p (rx (| " \"" (in " \t") bol) |
| 1784 | (when (string-match-p (rx (| (in " \t") bol) | 1788 | (in "‘’")) |
| 1785 | (? (in "\"#")) | ||
| 1786 | "'" | ||
| 1787 | (in "A-Za-z" "(")) | ||
| 1788 | docs) | 1789 | docs) |
| 1789 | (byte-compile-warn-x | 1790 | (byte-compile-warn-x |
| 1790 | name | 1791 | name |
| 1791 | (concat "%sdocstring has wrong usage of unescaped single quotes" | 1792 | "%sdocstring uses curved single quotes; use %s instead of ‘...’" |
| 1792 | " (use \\=%c or different quoting such as %c...%c)") | 1793 | (funcall prefix) "`...'")))))) |
| 1793 | (funcall prefix) ?' ?` ?')) | 1794 | |
| 1794 | ;; There's a "Unicode quote" in the string -- it should probably | 1795 | (defvar byte-compile--\#$) ; Special value that will print as `#$'. |
| 1795 | ;; be an ASCII one instead. | 1796 | (defvar byte-compile--docstrings nil "Table of already compiled docstrings.") |
| 1796 | (when (byte-compile-warning-enabled-p 'docstrings-non-ascii-quotes) | 1797 | |
| 1797 | (when (string-match-p (rx (| " \"" (in " \t") bol) | 1798 | (defun byte-compile--docstring (doc kind name &optional is-a-value) |
| 1798 | (in "‘’")) | 1799 | (byte-compile--docstring-style-warn doc kind name) |
| 1799 | docs) | 1800 | ;; Make docstrings dynamic, when applicable. |
| 1800 | (byte-compile-warn-x | 1801 | (cond |
| 1801 | name | 1802 | ((and byte-compile-dynamic-docstrings |
| 1802 | "%sdocstring uses curved single quotes; use %s instead of ‘...’" | 1803 | ;; The native compiler doesn't use those dynamic docstrings. |
| 1803 | (funcall prefix) "`...'")))))) | 1804 | (not byte-native-compiling) |
| 1804 | form) | 1805 | ;; Docstrings can only be dynamic when compiling a file. |
| 1806 | byte-compile--\#$) | ||
| 1807 | (let* ((byte-pos (with-memoization | ||
| 1808 | ;; Reuse a previously written identical docstring. | ||
| 1809 | ;; This is not done out of thriftiness but to try and | ||
| 1810 | ;; make sure that "equal" functions remain `equal'. | ||
| 1811 | ;; (Often those identical docstrings come from | ||
| 1812 | ;; `help-add-fundoc-usage'). | ||
| 1813 | ;; Needed e.g. for `advice-tests-nadvice'. | ||
| 1814 | (gethash doc byte-compile--docstrings) | ||
| 1815 | (byte-compile-output-as-comment doc nil))) | ||
| 1816 | (newdoc (cons byte-compile--\#$ byte-pos))) | ||
| 1817 | (if is-a-value newdoc (macroexp-quote newdoc)))) | ||
| 1818 | (t doc))) | ||
| 1805 | 1819 | ||
| 1806 | ;; If we have compiled any calls to functions which are not known to be | 1820 | ;; If we have compiled any calls to functions which are not known to be |
| 1807 | ;; defined, issue a warning enumerating them. | 1821 | ;; defined, issue a warning enumerating them. |
| @@ -1836,6 +1850,8 @@ It is too wide if it has any lines longer than the largest of | |||
| 1836 | ;; macroenvironment. | 1850 | ;; macroenvironment. |
| 1837 | (copy-alist byte-compile-initial-macro-environment)) | 1851 | (copy-alist byte-compile-initial-macro-environment)) |
| 1838 | (byte-compile--outbuffer nil) | 1852 | (byte-compile--outbuffer nil) |
| 1853 | (byte-compile--\#$ nil) | ||
| 1854 | (byte-compile--docstrings (make-hash-table :test 'equal)) | ||
| 1839 | (overriding-plist-environment nil) | 1855 | (overriding-plist-environment nil) |
| 1840 | (byte-compile-function-environment nil) | 1856 | (byte-compile-function-environment nil) |
| 1841 | (byte-compile-bound-variables nil) | 1857 | (byte-compile-bound-variables nil) |
| @@ -2363,7 +2379,12 @@ With argument ARG, insert value in current buffer after the form." | |||
| 2363 | (setq case-fold-search nil)) | 2379 | (setq case-fold-search nil)) |
| 2364 | (displaying-byte-compile-warnings | 2380 | (displaying-byte-compile-warnings |
| 2365 | (with-current-buffer inbuffer | 2381 | (with-current-buffer inbuffer |
| 2366 | (when byte-compile-current-file | 2382 | (when byte-compile-dest-file |
| 2383 | (setq byte-compile--\#$ | ||
| 2384 | (copy-sequence ;It needs to be a fresh new object. | ||
| 2385 | ;; Also it stands for the `load-file-name' when the `.elc' will | ||
| 2386 | ;; be loaded, so make it look like it. | ||
| 2387 | byte-compile-dest-file)) | ||
| 2367 | (byte-compile-insert-header byte-compile-current-file | 2388 | (byte-compile-insert-header byte-compile-current-file |
| 2368 | byte-compile--outbuffer) | 2389 | byte-compile--outbuffer) |
| 2369 | ;; Instruct native-comp to ignore this file. | 2390 | ;; Instruct native-comp to ignore this file. |
| @@ -2456,11 +2477,7 @@ Call from the source buffer." | |||
| 2456 | 2477 | ||
| 2457 | (defun byte-compile-output-file-form (form) | 2478 | (defun byte-compile-output-file-form (form) |
| 2458 | ;; Write the given form to the output buffer, being careful of docstrings | 2479 | ;; Write the given form to the output buffer, being careful of docstrings |
| 2459 | ;; (for `byte-compile-dynamic-docstrings') in defvar, defvaralias, | 2480 | ;; (for `byte-compile-dynamic-docstrings'). |
| 2460 | ;; defconst, autoload, and custom-declare-variable. | ||
| 2461 | ;; defalias calls are output directly by byte-compile-file-form-defmumble; | ||
| 2462 | ;; it does not pay to first build the defalias in defmumble and then parse | ||
| 2463 | ;; it here. | ||
| 2464 | (when byte-native-compiling | 2481 | (when byte-native-compiling |
| 2465 | ;; Spill output for the native compiler here | 2482 | ;; Spill output for the native compiler here |
| 2466 | (push (make-byte-to-native-top-level :form form :lexical lexical-binding) | 2483 | (push (make-byte-to-native-top-level :form form :lexical lexical-binding) |
| @@ -2470,123 +2487,17 @@ Call from the source buffer." | |||
| 2470 | (print-level nil) | 2487 | (print-level nil) |
| 2471 | (print-quoted t) | 2488 | (print-quoted t) |
| 2472 | (print-gensym t) | 2489 | (print-gensym t) |
| 2473 | (print-circle t)) ; Handle circular data structures. | 2490 | (print-circle t) |
| 2474 | (if (memq (car-safe form) '(defvar defvaralias defconst | 2491 | (print-continuous-numbering t) |
| 2475 | autoload custom-declare-variable)) | 2492 | (print-number-table (make-hash-table :test #'eq))) |
| 2476 | (byte-compile-output-docform nil nil nil '("\n(" ")") form nil 3 | 2493 | (when byte-compile--\#$ |
| 2477 | (memq (car form) | 2494 | (puthash byte-compile--\#$ "#$" print-number-table)) |
| 2478 | '(defvaralias autoload | 2495 | (princ "\n" byte-compile--outbuffer) |
| 2479 | custom-declare-variable))) | 2496 | (prin1 form byte-compile--outbuffer) |
| 2480 | (princ "\n" byte-compile--outbuffer) | 2497 | nil)) |
| 2481 | (prin1 form byte-compile--outbuffer) | ||
| 2482 | nil))) | ||
| 2483 | 2498 | ||
| 2484 | (defvar byte-compile--for-effect) | 2499 | (defvar byte-compile--for-effect) |
| 2485 | 2500 | ||
| 2486 | (defun byte-compile--output-docform-recurse | ||
| 2487 | (info position form cvecindex docindex quoted) | ||
| 2488 | "Print a form with a doc string. INFO is (prefix postfix). | ||
| 2489 | POSITION is where the next doc string is to be inserted. | ||
| 2490 | CVECINDEX is the index in the FORM of the constant vector, or nil. | ||
| 2491 | DOCINDEX is the index of the doc string (or nil) in the FORM. | ||
| 2492 | QUOTED says that we have to put a quote before the | ||
| 2493 | list that represents a doc string reference. | ||
| 2494 | `defvaralias', `autoload' and `custom-declare-variable' need that. | ||
| 2495 | |||
| 2496 | Return the position after any inserted docstrings as comments." | ||
| 2497 | (let ((index 0) | ||
| 2498 | doc-string-position) | ||
| 2499 | ;; Insert the doc string, and make it a comment with #@LENGTH. | ||
| 2500 | (when (and byte-compile-dynamic-docstrings | ||
| 2501 | (stringp (nth docindex form))) | ||
| 2502 | (goto-char position) | ||
| 2503 | (setq doc-string-position | ||
| 2504 | (byte-compile-output-as-comment | ||
| 2505 | (nth docindex form) nil) | ||
| 2506 | position (point)) | ||
| 2507 | (goto-char (point-max))) | ||
| 2508 | |||
| 2509 | (insert (car info)) | ||
| 2510 | (prin1 (car form) byte-compile--outbuffer) | ||
| 2511 | (while (setq form (cdr form)) | ||
| 2512 | (setq index (1+ index)) | ||
| 2513 | (insert " ") | ||
| 2514 | (cond ((eq index cvecindex) | ||
| 2515 | (let* ((cvec (car form)) | ||
| 2516 | (len (length cvec)) | ||
| 2517 | (index2 0) | ||
| 2518 | elt) | ||
| 2519 | (insert "[") | ||
| 2520 | (while (< index2 len) | ||
| 2521 | (setq elt (aref cvec index2)) | ||
| 2522 | (if (byte-code-function-p elt) | ||
| 2523 | (setq position | ||
| 2524 | (byte-compile--output-docform-recurse | ||
| 2525 | '("#[" "]") position | ||
| 2526 | (append elt nil) ; Convert the vector to a list. | ||
| 2527 | 2 4 nil)) | ||
| 2528 | (prin1 elt byte-compile--outbuffer)) | ||
| 2529 | (setq index2 (1+ index2)) | ||
| 2530 | (unless (eq index2 len) | ||
| 2531 | (insert " "))) | ||
| 2532 | (insert "]"))) | ||
| 2533 | ((= index docindex) | ||
| 2534 | (cond | ||
| 2535 | (doc-string-position | ||
| 2536 | (princ (format (if quoted "'(#$ . %d)" "(#$ . %d)") | ||
| 2537 | doc-string-position) | ||
| 2538 | byte-compile--outbuffer)) | ||
| 2539 | ((stringp (car form)) | ||
| 2540 | (let ((print-escape-newlines nil)) | ||
| 2541 | (goto-char (prog1 (1+ (point)) | ||
| 2542 | (prin1 (car form) | ||
| 2543 | byte-compile--outbuffer))) | ||
| 2544 | (insert "\\\n") | ||
| 2545 | (goto-char (point-max)))) | ||
| 2546 | (t (prin1 (car form) byte-compile--outbuffer)))) | ||
| 2547 | (t (prin1 (car form) byte-compile--outbuffer)))) | ||
| 2548 | (insert (cadr info)) | ||
| 2549 | position)) | ||
| 2550 | |||
| 2551 | (defun byte-compile-output-docform (preface tailpiece name info form | ||
| 2552 | cvecindex docindex | ||
| 2553 | quoted) | ||
| 2554 | "Print a form with a doc string. INFO is (prefix postfix). | ||
| 2555 | If PREFACE, NAME, and TAILPIECE are non-nil, print them too, | ||
| 2556 | before/after INFO and the FORM but after the doc string itself. | ||
| 2557 | CVECINDEX is the index in the FORM of the constant vector, or nil. | ||
| 2558 | DOCINDEX is the index of the doc string (or nil) in the FORM. | ||
| 2559 | QUOTED says that we have to put a quote before the | ||
| 2560 | list that represents a doc string reference. | ||
| 2561 | `defvaralias', `autoload' and `custom-declare-variable' need that." | ||
| 2562 | ;; We need to examine byte-compile-dynamic-docstrings | ||
| 2563 | ;; in the input buffer (now current), not in the output buffer. | ||
| 2564 | (let ((dynamic-docstrings byte-compile-dynamic-docstrings)) | ||
| 2565 | (with-current-buffer byte-compile--outbuffer | ||
| 2566 | (let ((byte-compile-dynamic-docstrings dynamic-docstrings) | ||
| 2567 | (position (point)) | ||
| 2568 | (print-continuous-numbering t) | ||
| 2569 | print-number-table | ||
| 2570 | ;; FIXME: The bindings below are only needed for when we're | ||
| 2571 | ;; called from ...-defmumble. | ||
| 2572 | (print-escape-newlines t) | ||
| 2573 | (print-length nil) | ||
| 2574 | (print-level nil) | ||
| 2575 | (print-quoted t) | ||
| 2576 | (print-gensym t) | ||
| 2577 | (print-circle t)) ; Handle circular data structures. | ||
| 2578 | (when preface | ||
| 2579 | ;; FIXME: We don't handle uninterned names correctly. | ||
| 2580 | ;; E.g. if cl-define-compiler-macro uses uninterned name we get: | ||
| 2581 | ;; (defalias '#1=#:foo--cmacro #[514 ...]) | ||
| 2582 | ;; (put 'foo 'compiler-macro '#:foo--cmacro) | ||
| 2583 | (insert preface) | ||
| 2584 | (prin1 name byte-compile--outbuffer)) | ||
| 2585 | (byte-compile--output-docform-recurse | ||
| 2586 | info position form cvecindex docindex quoted) | ||
| 2587 | (when tailpiece | ||
| 2588 | (insert tailpiece)))))) | ||
| 2589 | |||
| 2590 | (defun byte-compile-keep-pending (form &optional handler) | 2501 | (defun byte-compile-keep-pending (form &optional handler) |
| 2591 | (if (memq byte-optimize '(t source)) | 2502 | (if (memq byte-optimize '(t source)) |
| 2592 | (setq form (byte-optimize-one-form form t))) | 2503 | (setq form (byte-optimize-one-form form t))) |
| @@ -2606,7 +2517,7 @@ list that represents a doc string reference. | |||
| 2606 | (if byte-compile-output | 2517 | (if byte-compile-output |
| 2607 | (let ((form (byte-compile-out-toplevel t 'file))) | 2518 | (let ((form (byte-compile-out-toplevel t 'file))) |
| 2608 | (cond ((eq (car-safe form) 'progn) | 2519 | (cond ((eq (car-safe form) 'progn) |
| 2609 | (mapc 'byte-compile-output-file-form (cdr form))) | 2520 | (mapc #'byte-compile-output-file-form (cdr form))) |
| 2610 | (form | 2521 | (form |
| 2611 | (byte-compile-output-file-form form))) | 2522 | (byte-compile-output-file-form form))) |
| 2612 | (setq byte-compile-constants nil | 2523 | (setq byte-compile-constants nil |
| @@ -2681,12 +2592,12 @@ list that represents a doc string reference. | |||
| 2681 | (setq byte-compile-unresolved-functions | 2592 | (setq byte-compile-unresolved-functions |
| 2682 | (delq (assq funsym byte-compile-unresolved-functions) | 2593 | (delq (assq funsym byte-compile-unresolved-functions) |
| 2683 | byte-compile-unresolved-functions))))) | 2594 | byte-compile-unresolved-functions))))) |
| 2684 | (if (stringp (nth 3 form)) | 2595 | (let* ((doc (nth 3 form)) |
| 2685 | (prog1 | 2596 | (newdoc (if (not (stringp doc)) doc |
| 2686 | form | 2597 | (byte-compile--docstring |
| 2687 | (byte-compile-docstring-style-warn form)) | 2598 | doc 'autoload (nth 1 form))))) |
| 2688 | ;; No doc string, so we can compile this as a normal form. | 2599 | (byte-compile-keep-pending (byte-compile--list-with-n form 3 newdoc) |
| 2689 | (byte-compile-keep-pending form 'byte-compile-normal-call))) | 2600 | #'byte-compile-normal-call))) |
| 2690 | 2601 | ||
| 2691 | (put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar) | 2602 | (put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar) |
| 2692 | (put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar) | 2603 | (put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar) |
| @@ -2698,9 +2609,10 @@ list that represents a doc string reference. | |||
| 2698 | (byte-compile-warn-x | 2609 | (byte-compile-warn-x |
| 2699 | sym "global/dynamic var `%s' lacks a prefix" sym))) | 2610 | sym "global/dynamic var `%s' lacks a prefix" sym))) |
| 2700 | 2611 | ||
| 2701 | (defun byte-compile--declare-var (sym) | 2612 | (defun byte-compile--declare-var (sym &optional not-toplevel) |
| 2702 | (byte-compile--check-prefixed-var sym) | 2613 | (byte-compile--check-prefixed-var sym) |
| 2703 | (when (memq sym byte-compile-lexical-variables) | 2614 | (when (and (not not-toplevel) |
| 2615 | (memq sym byte-compile-lexical-variables)) | ||
| 2704 | (setq byte-compile-lexical-variables | 2616 | (setq byte-compile-lexical-variables |
| 2705 | (delq sym byte-compile-lexical-variables)) | 2617 | (delq sym byte-compile-lexical-variables)) |
| 2706 | (when (byte-compile-warning-enabled-p 'lexical sym) | 2618 | (when (byte-compile-warning-enabled-p 'lexical sym) |
| @@ -2709,19 +2621,7 @@ list that represents a doc string reference. | |||
| 2709 | (push sym byte-compile--seen-defvars)) | 2621 | (push sym byte-compile--seen-defvars)) |
| 2710 | 2622 | ||
| 2711 | (defun byte-compile-file-form-defvar (form) | 2623 | (defun byte-compile-file-form-defvar (form) |
| 2712 | (let ((sym (nth 1 form))) | 2624 | (byte-compile-defvar form 'toplevel)) |
| 2713 | (byte-compile--declare-var sym) | ||
| 2714 | (if (eq (car form) 'defconst) | ||
| 2715 | (push sym byte-compile-const-variables))) | ||
| 2716 | (if (and (null (cddr form)) ;No `value' provided. | ||
| 2717 | (eq (car form) 'defvar)) ;Just a declaration. | ||
| 2718 | nil | ||
| 2719 | (byte-compile-docstring-style-warn form) | ||
| 2720 | (setq form (copy-sequence form)) | ||
| 2721 | (when (consp (nth 2 form)) | ||
| 2722 | (setcar (cdr (cdr form)) | ||
| 2723 | (byte-compile-top-level (nth 2 form) nil 'file))) | ||
| 2724 | form)) | ||
| 2725 | 2625 | ||
| 2726 | (put 'define-abbrev-table 'byte-hunk-handler | 2626 | (put 'define-abbrev-table 'byte-hunk-handler |
| 2727 | 'byte-compile-file-form-defvar-function) | 2627 | 'byte-compile-file-form-defvar-function) |
| @@ -2729,26 +2629,37 @@ list that represents a doc string reference. | |||
| 2729 | 2629 | ||
| 2730 | (defun byte-compile-file-form-defvar-function (form) | 2630 | (defun byte-compile-file-form-defvar-function (form) |
| 2731 | (pcase-let (((or `',name (let name nil)) (nth 1 form))) | 2631 | (pcase-let (((or `',name (let name nil)) (nth 1 form))) |
| 2732 | (if name (byte-compile--declare-var name))) | 2632 | (if name (byte-compile--declare-var name)) |
| 2733 | ;; Variable aliases are better declared before the corresponding variable, | 2633 | ;; Variable aliases are better declared before the corresponding variable, |
| 2734 | ;; since it makes it more likely that only one of the two vars has a value | 2634 | ;; since it makes it more likely that only one of the two vars has a value |
| 2735 | ;; before the `defvaralias' gets executed, which avoids the need to | 2635 | ;; before the `defvaralias' gets executed, which avoids the need to |
| 2736 | ;; merge values. | 2636 | ;; merge values. |
| 2737 | (pcase form | 2637 | (pcase form |
| 2738 | (`(defvaralias ,_ ',newname . ,_) | 2638 | (`(defvaralias ,_ ',newname . ,_) |
| 2739 | (when (memq newname byte-compile-bound-variables) | 2639 | (when (memq newname byte-compile-bound-variables) |
| 2740 | (if (byte-compile-warning-enabled-p 'suspicious) | 2640 | (if (byte-compile-warning-enabled-p 'suspicious) |
| 2741 | (byte-compile-warn-x | 2641 | (byte-compile-warn-x |
| 2742 | newname | 2642 | newname |
| 2743 | "Alias for `%S' should be declared before its referent" newname))))) | 2643 | "Alias for `%S' should be declared before its referent" |
| 2744 | (byte-compile-docstring-style-warn form) | 2644 | newname))))) |
| 2745 | (byte-compile-keep-pending form)) | 2645 | (let ((doc (nth 3 form))) |
| 2646 | (when (stringp doc) | ||
| 2647 | (setcar (nthcdr 3 form) | ||
| 2648 | (byte-compile--docstring doc (nth 0 form) name)))) | ||
| 2649 | (byte-compile-keep-pending form))) | ||
| 2746 | 2650 | ||
| 2747 | (put 'custom-declare-variable 'byte-hunk-handler | 2651 | (put 'custom-declare-variable 'byte-hunk-handler |
| 2748 | 'byte-compile-file-form-defvar-function) | 2652 | 'byte-compile-file-form-defvar-function) |
| 2749 | 2653 | ||
| 2750 | (put 'custom-declare-face 'byte-hunk-handler | 2654 | (put 'custom-declare-face 'byte-hunk-handler |
| 2751 | 'byte-compile-docstring-style-warn) | 2655 | #'byte-compile--custom-declare-face) |
| 2656 | (defun byte-compile--custom-declare-face (form) | ||
| 2657 | (let ((kind (nth 0 form)) (name (nth 1 form)) (docs (nth 3 form))) | ||
| 2658 | (when (stringp docs) | ||
| 2659 | (let ((newdocs (byte-compile--docstring docs kind name))) | ||
| 2660 | (unless (eq docs newdocs) | ||
| 2661 | (setq form (byte-compile--list-with-n form 3 newdocs))))) | ||
| 2662 | form)) | ||
| 2752 | 2663 | ||
| 2753 | (put 'require 'byte-hunk-handler 'byte-compile-file-form-require) | 2664 | (put 'require 'byte-hunk-handler 'byte-compile-file-form-require) |
| 2754 | (defun byte-compile-file-form-require (form) | 2665 | (defun byte-compile-file-form-require (form) |
| @@ -2902,33 +2813,24 @@ not to take responsibility for the actual compilation of the code." | |||
| 2902 | (cons (cons bare-name code) | 2813 | (cons (cons bare-name code) |
| 2903 | (symbol-value this-kind)))) | 2814 | (symbol-value this-kind)))) |
| 2904 | 2815 | ||
| 2905 | (if rest | 2816 | (byte-compile-flush-pending) |
| 2906 | ;; There are additional args to `defalias' (like maybe a docstring) | 2817 | (let ((newform `(defalias ',bare-name |
| 2907 | ;; that the code below can't handle: punt! | 2818 | ,(if macro `'(macro . ,code) code) ,@rest))) |
| 2908 | nil | ||
| 2909 | ;; Otherwise, we have a bona-fide defun/defmacro definition, and use | ||
| 2910 | ;; special code to allow dynamic docstrings and byte-code. | ||
| 2911 | (byte-compile-flush-pending) | ||
| 2912 | (when byte-native-compiling | 2819 | (when byte-native-compiling |
| 2913 | ;; Spill output for the native compiler here. | 2820 | ;; Don't let `byte-compile-output-file-form' push the form to |
| 2821 | ;; `byte-to-native-top-level-forms' because we want to use | ||
| 2822 | ;; `make-byte-to-native-func-def' when possible. | ||
| 2914 | (push | 2823 | (push |
| 2915 | (if macro | 2824 | (if (or macro rest) |
| 2916 | (make-byte-to-native-top-level | 2825 | (make-byte-to-native-top-level |
| 2917 | :form `(defalias ',name '(macro . ,code) nil) | 2826 | :form newform |
| 2918 | :lexical lexical-binding) | 2827 | :lexical lexical-binding) |
| 2919 | (make-byte-to-native-func-def :name name | 2828 | (make-byte-to-native-func-def :name name |
| 2920 | :byte-func code)) | 2829 | :byte-func code)) |
| 2921 | byte-to-native-top-level-forms)) | 2830 | byte-to-native-top-level-forms)) |
| 2922 | ;; Output the form by hand, that's much simpler than having | 2831 | (let ((byte-native-compiling nil)) |
| 2923 | ;; b-c-output-file-form analyze the defalias. | 2832 | (byte-compile-output-file-form newform))) |
| 2924 | (byte-compile-output-docform | 2833 | t)))) |
| 2925 | "\n(defalias '" ")" | ||
| 2926 | bare-name | ||
| 2927 | (if macro '(" '(macro . #[" "])") '(" #[" "]")) | ||
| 2928 | (append code nil) ; Turn byte-code-function-p into list. | ||
| 2929 | 2 4 | ||
| 2930 | nil) | ||
| 2931 | t))))) | ||
| 2932 | 2834 | ||
| 2933 | (defun byte-compile-output-as-comment (exp quoted) | 2835 | (defun byte-compile-output-as-comment (exp quoted) |
| 2934 | "Print Lisp object EXP in the output file at point, inside a comment. | 2836 | "Print Lisp object EXP in the output file at point, inside a comment. |
| @@ -3129,9 +3031,9 @@ lambda-expression." | |||
| 3129 | (setq fun (cons 'lambda fun)) | 3031 | (setq fun (cons 'lambda fun)) |
| 3130 | (unless (eq 'lambda (car-safe fun)) | 3032 | (unless (eq 'lambda (car-safe fun)) |
| 3131 | (error "Not a lambda list: %S" fun))) | 3033 | (error "Not a lambda list: %S" fun))) |
| 3132 | (byte-compile-docstring-style-warn fun) | ||
| 3133 | (byte-compile-check-lambda-list (nth 1 fun)) | 3034 | (byte-compile-check-lambda-list (nth 1 fun)) |
| 3134 | (let* ((arglist (nth 1 fun)) | 3035 | (let* ((arglist (nth 1 fun)) |
| 3036 | (bare-arglist (byte-run-strip-symbol-positions arglist)) ; for compile-defun. | ||
| 3135 | (arglistvars (byte-run-strip-symbol-positions | 3037 | (arglistvars (byte-run-strip-symbol-positions |
| 3136 | (byte-compile-arglist-vars arglist))) | 3038 | (byte-compile-arglist-vars arglist))) |
| 3137 | (byte-compile-bound-variables | 3039 | (byte-compile-bound-variables |
| @@ -3140,16 +3042,22 @@ lambda-expression." | |||
| 3140 | (body (cdr (cdr fun))) | 3042 | (body (cdr (cdr fun))) |
| 3141 | (doc (if (stringp (car body)) | 3043 | (doc (if (stringp (car body)) |
| 3142 | (prog1 (car body) | 3044 | (prog1 (car body) |
| 3143 | ;; Discard the doc string | 3045 | ;; Discard the doc string from the body |
| 3144 | ;; unless it is the last element of the body. | 3046 | ;; unless it is the last element of the body. |
| 3145 | (if (cdr body) | 3047 | (if (cdr body) |
| 3146 | (setq body (cdr body)))))) | 3048 | (setq body (cdr body)))))) |
| 3147 | (int (assq 'interactive body)) | 3049 | (int (assq 'interactive body)) |
| 3148 | command-modes) | 3050 | command-modes) |
| 3149 | (when lexical-binding | 3051 | (when lexical-binding |
| 3052 | (when arglist | ||
| 3053 | ;; byte-compile-make-args-desc lost the args's names, | ||
| 3054 | ;; so preserve them in the docstring. | ||
| 3055 | (setq doc (help-add-fundoc-usage doc bare-arglist))) | ||
| 3150 | (dolist (var arglistvars) | 3056 | (dolist (var arglistvars) |
| 3151 | (when (assq var byte-compile--known-dynamic-vars) | 3057 | (when (assq var byte-compile--known-dynamic-vars) |
| 3152 | (byte-compile--warn-lexical-dynamic var 'lambda)))) | 3058 | (byte-compile--warn-lexical-dynamic var 'lambda)))) |
| 3059 | (when (stringp doc) | ||
| 3060 | (setq doc (byte-compile--docstring doc "" nil 'is-a-value))) | ||
| 3153 | ;; Process the interactive spec. | 3061 | ;; Process the interactive spec. |
| 3154 | (when int | 3062 | (when int |
| 3155 | ;; Skip (interactive) if it is in front (the most usual location). | 3063 | ;; Skip (interactive) if it is in front (the most usual location). |
| @@ -3193,8 +3101,7 @@ lambda-expression." | |||
| 3193 | (and lexical-binding | 3101 | (and lexical-binding |
| 3194 | (byte-compile-make-lambda-lexenv | 3102 | (byte-compile-make-lambda-lexenv |
| 3195 | arglistvars)) | 3103 | arglistvars)) |
| 3196 | reserved-csts)) | 3104 | reserved-csts))) |
| 3197 | (bare-arglist (byte-run-strip-symbol-positions arglist))) ; for compile-defun. | ||
| 3198 | ;; Build the actual byte-coded function. | 3105 | ;; Build the actual byte-coded function. |
| 3199 | (cl-assert (eq 'byte-code (car-safe compiled))) | 3106 | (cl-assert (eq 'byte-code (car-safe compiled))) |
| 3200 | (let ((out | 3107 | (let ((out |
| @@ -3206,12 +3113,7 @@ lambda-expression." | |||
| 3206 | ;; byte-string, constants-vector, stack depth | 3113 | ;; byte-string, constants-vector, stack depth |
| 3207 | (cdr compiled) | 3114 | (cdr compiled) |
| 3208 | ;; optionally, the doc string. | 3115 | ;; optionally, the doc string. |
| 3209 | (cond ((and lexical-binding arglist) | 3116 | (when (or doc int) (list doc)) |
| 3210 | ;; byte-compile-make-args-desc lost the args's names, | ||
| 3211 | ;; so preserve them in the docstring. | ||
| 3212 | (list (help-add-fundoc-usage doc bare-arglist))) | ||
| 3213 | ((or doc int) | ||
| 3214 | (list doc))) | ||
| 3215 | ;; optionally, the interactive spec (and the modes the | 3117 | ;; optionally, the interactive spec (and the modes the |
| 3216 | ;; command applies to). | 3118 | ;; command applies to). |
| 3217 | (cond | 3119 | (cond |
| @@ -5091,49 +4993,49 @@ binding slots have been popped." | |||
| 5091 | (push (nth 1 (nth 1 form)) byte-compile-global-not-obsolete-vars)) | 4993 | (push (nth 1 (nth 1 form)) byte-compile-global-not-obsolete-vars)) |
| 5092 | (byte-compile-normal-call form)) | 4994 | (byte-compile-normal-call form)) |
| 5093 | 4995 | ||
| 5094 | (defun byte-compile-defvar (form) | 4996 | (defun byte-compile-defvar (form &optional toplevel) |
| 5095 | ;; This is not used for file-level defvar/consts. | 4997 | (let* ((fun (nth 0 form)) |
| 5096 | (when (and (symbolp (nth 1 form)) | 4998 | (var (nth 1 form)) |
| 5097 | (not (string-match "[-*/:$]" (symbol-name (nth 1 form)))) | 4999 | (value (nth 2 form)) |
| 5098 | (byte-compile-warning-enabled-p 'lexical (nth 1 form))) | 5000 | (string (nth 3 form))) |
| 5099 | (byte-compile-warn-x | 5001 | (byte-compile--declare-var var (not toplevel)) |
| 5100 | (nth 1 form) | ||
| 5101 | "global/dynamic var `%s' lacks a prefix" | ||
| 5102 | (nth 1 form))) | ||
| 5103 | (byte-compile-docstring-style-warn form) | ||
| 5104 | (let ((fun (nth 0 form)) | ||
| 5105 | (var (nth 1 form)) | ||
| 5106 | (value (nth 2 form)) | ||
| 5107 | (string (nth 3 form))) | ||
| 5108 | (when (or (> (length form) 4) | ||
| 5109 | (and (eq fun 'defconst) (null (cddr form)))) | ||
| 5110 | (let ((ncall (length (cdr form)))) | ||
| 5111 | (byte-compile-warn-x | ||
| 5112 | fun | ||
| 5113 | "`%s' called with %d argument%s, but %s %s" | ||
| 5114 | fun ncall | ||
| 5115 | (if (= 1 ncall) "" "s") | ||
| 5116 | (if (< ncall 2) "requires" "accepts only") | ||
| 5117 | "2-3"))) | ||
| 5118 | (push var byte-compile-bound-variables) | ||
| 5119 | (if (eq fun 'defconst) | 5002 | (if (eq fun 'defconst) |
| 5120 | (push var byte-compile-const-variables)) | 5003 | (push var byte-compile-const-variables)) |
| 5121 | (when (and string (not (stringp string))) | 5004 | (cond |
| 5005 | ((stringp string) | ||
| 5006 | (setq string (byte-compile--docstring string fun var 'is-a-value))) | ||
| 5007 | (string | ||
| 5122 | (byte-compile-warn-x | 5008 | (byte-compile-warn-x |
| 5123 | string | 5009 | string |
| 5124 | "third arg to `%s %s' is not a string: %s" | 5010 | "third arg to `%s %s' is not a string: %s" |
| 5125 | fun var string)) | 5011 | fun var string))) |
| 5126 | ;; Delegate the actual work to the function version of the | 5012 | (if toplevel |
| 5127 | ;; special form, named with a "-1" suffix. | 5013 | ;; At top-level we emit calls to defvar/defconst. |
| 5128 | (byte-compile-form-do-effect | 5014 | (if (and (null (cddr form)) ;No `value' provided. |
| 5129 | (cond | 5015 | (eq (car form) 'defvar)) ;Just a declaration. |
| 5130 | ((eq fun 'defconst) `(defconst-1 ',var ,@(nthcdr 2 form))) | 5016 | nil |
| 5131 | ((not (cddr form)) `',var) ; A simple (defvar foo) just returns foo. | 5017 | (let ((tail (nthcdr 4 form))) |
| 5132 | (t `(defvar-1 ',var | 5018 | (when (or tail string) (push string tail)) |
| 5133 | ;; Don't eval `value' if `defvar' wouldn't eval it either. | 5019 | (when (cddr form) |
| 5134 | ,(if (macroexp-const-p value) value | 5020 | (push (if (not (consp value)) value |
| 5135 | `(if (boundp ',var) nil ,value)) | 5021 | (byte-compile-top-level value nil 'file)) |
| 5136 | ,@(nthcdr 3 form))))))) | 5022 | tail)) |
| 5023 | `(,fun ,var ,@tail))) | ||
| 5024 | ;; At non-top-level, since there is no byte code for | ||
| 5025 | ;; defvar/defconst, we delegate the actual work to the function | ||
| 5026 | ;; version of the special form, named with a "-1" suffix. | ||
| 5027 | (byte-compile-form-do-effect | ||
| 5028 | (cond | ||
| 5029 | ((eq fun 'defconst) | ||
| 5030 | `(defconst-1 ',var ,@(byte-compile--list-with-n | ||
| 5031 | (nthcdr 2 form) 1 (macroexp-quote string)))) | ||
| 5032 | ((not (cddr form)) `',var) ; A simple (defvar foo) just returns foo. | ||
| 5033 | (t `(defvar-1 ',var | ||
| 5034 | ;; Don't eval `value' if `defvar' wouldn't eval it either. | ||
| 5035 | ,(if (macroexp-const-p value) value | ||
| 5036 | `(if (boundp ',var) nil ,value)) | ||
| 5037 | ,@(byte-compile--list-with-n | ||
| 5038 | (nthcdr 3 form) 0 (macroexp-quote string))))))))) | ||
| 5137 | 5039 | ||
| 5138 | (defun byte-compile-autoload (form) | 5040 | (defun byte-compile-autoload (form) |
| 5139 | (and (macroexp-const-p (nth 1 form)) | 5041 | (and (macroexp-const-p (nth 1 form)) |
| @@ -5159,14 +5061,6 @@ binding slots have been popped." | |||
| 5159 | ;; For the compilation itself, we could largely get rid of this hunk-handler, | 5061 | ;; For the compilation itself, we could largely get rid of this hunk-handler, |
| 5160 | ;; if it weren't for the fact that we need to figure out when a defalias | 5062 | ;; if it weren't for the fact that we need to figure out when a defalias |
| 5161 | ;; defines a macro, so as to add it to byte-compile-macro-environment. | 5063 | ;; defines a macro, so as to add it to byte-compile-macro-environment. |
| 5162 | ;; | ||
| 5163 | ;; FIXME: we also use this hunk-handler to implement the function's | ||
| 5164 | ;; dynamic docstring feature (via byte-compile-file-form-defmumble). | ||
| 5165 | ;; We should probably actually implement it (more elegantly) in | ||
| 5166 | ;; byte-compile-lambda so it applies to all lambdas. We did it here | ||
| 5167 | ;; so the resulting .elc format was recognizable by make-docfile, | ||
| 5168 | ;; but since then we stopped using DOC for the docstrings of | ||
| 5169 | ;; preloaded elc files so that obstacle is gone. | ||
| 5170 | (let ((byte-compile-free-references nil) | 5064 | (let ((byte-compile-free-references nil) |
| 5171 | (byte-compile-free-assignments nil)) | 5065 | (byte-compile-free-assignments nil)) |
| 5172 | (pcase form | 5066 | (pcase form |
| @@ -5175,7 +5069,11 @@ binding slots have been popped." | |||
| 5175 | ;; - `arg' is the expression to which it is defined. | 5069 | ;; - `arg' is the expression to which it is defined. |
| 5176 | ;; - `rest' is the rest of the arguments. | 5070 | ;; - `rest' is the rest of the arguments. |
| 5177 | (`(,_ ',name ,arg . ,rest) | 5071 | (`(,_ ',name ,arg . ,rest) |
| 5178 | (byte-compile-docstring-style-warn form) | 5072 | (let ((doc (car rest))) |
| 5073 | (when (stringp doc) | ||
| 5074 | (setq rest (byte-compile--list-with-n | ||
| 5075 | rest 0 | ||
| 5076 | (byte-compile--docstring doc (nth 0 form) name))))) | ||
| 5179 | (pcase-let* | 5077 | (pcase-let* |
| 5180 | ;; `macro' is non-nil if it defines a macro. | 5078 | ;; `macro' is non-nil if it defines a macro. |
| 5181 | ;; `fun' is the function part of `arg' (defaults to `arg'). | 5079 | ;; `fun' is the function part of `arg' (defaults to `arg'). |
diff --git a/lisp/faces.el b/lisp/faces.el index d5120f42b92..c3a54a08a3d 100644 --- a/lisp/faces.el +++ b/lisp/faces.el | |||
| @@ -651,11 +651,11 @@ Optional argument INHERIT is passed to `face-attribute'." | |||
| 651 | If FACE is a face-alias, get the documentation for the target face." | 651 | If FACE is a face-alias, get the documentation for the target face." |
| 652 | (let ((alias (get face 'face-alias))) | 652 | (let ((alias (get face 'face-alias))) |
| 653 | (if alias | 653 | (if alias |
| 654 | (let ((doc (get alias 'face-documentation))) | 654 | (let ((doc (documentation-property alias 'face-documentation))) |
| 655 | (format "%s is an alias for the face `%s'.%s" face alias | 655 | (format "%s is an alias for the face `%s'.%s" face alias |
| 656 | (if doc (format "\n%s" doc) | 656 | (if doc (format "\n%s" doc) |
| 657 | ""))) | 657 | ""))) |
| 658 | (get face 'face-documentation)))) | 658 | (documentation-property face 'face-documentation)))) |
| 659 | 659 | ||
| 660 | 660 | ||
| 661 | (defun set-face-documentation (face string) | 661 | (defun set-face-documentation (face string) |
diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 99642d08bbd..1ba848c107d 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el | |||
| @@ -1799,9 +1799,8 @@ If FRAME is omitted or nil, use the selected frame." | |||
| 1799 | alias) | 1799 | alias) |
| 1800 | "")))) | 1800 | "")))) |
| 1801 | (insert "\nDocumentation:\n" | 1801 | (insert "\nDocumentation:\n" |
| 1802 | (substitute-command-keys | 1802 | (or (face-documentation face) |
| 1803 | (or (face-documentation face) | 1803 | "Not documented as a face.") |
| 1804 | "Not documented as a face.")) | ||
| 1805 | "\n\n")) | 1804 | "\n\n")) |
| 1806 | (with-current-buffer standard-output | 1805 | (with-current-buffer standard-output |
| 1807 | (save-excursion | 1806 | (save-excursion |
| @@ -357,6 +357,20 @@ reread_doc_file (Lisp_Object file) | |||
| 357 | return 1; | 357 | return 1; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | DEFUN ("documentation-stringp", Fdocumentation_stringp, Sdocumentation_stringp, | ||
| 361 | 1, 1, 0, | ||
| 362 | doc: /* Return non-nil if OBJECT is a well-formed docstring object. | ||
| 363 | OBJECT can be either a string or a reference if it's kept externally. */) | ||
| 364 | (Lisp_Object object) | ||
| 365 | { | ||
| 366 | return (STRINGP (object) | ||
| 367 | || FIXNUMP (object) /* Reference to DOC. */ | ||
| 368 | || (CONSP (object) /* Reference to .elc. */ | ||
| 369 | && STRINGP (XCAR (object)) | ||
| 370 | && FIXNUMP (XCDR (object))) | ||
| 371 | ? Qt : Qnil); | ||
| 372 | } | ||
| 373 | |||
| 360 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, | 374 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, |
| 361 | doc: /* Return the documentation string of FUNCTION. | 375 | doc: /* Return the documentation string of FUNCTION. |
| 362 | Unless a non-nil second argument RAW is given, the | 376 | Unless a non-nil second argument RAW is given, the |
| @@ -502,46 +516,13 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset) | |||
| 502 | /* If it's a lisp form, stick it in the form. */ | 516 | /* If it's a lisp form, stick it in the form. */ |
| 503 | if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) | 517 | if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) |
| 504 | fun = XCDR (fun); | 518 | fun = XCDR (fun); |
| 505 | if (CONSP (fun)) | ||
| 506 | { | ||
| 507 | Lisp_Object tem = XCAR (fun); | ||
| 508 | if (EQ (tem, Qlambda) || EQ (tem, Qautoload) | ||
| 509 | || (EQ (tem, Qclosure) && (fun = XCDR (fun), 1))) | ||
| 510 | { | ||
| 511 | tem = Fcdr (Fcdr (fun)); | ||
| 512 | if (CONSP (tem) && FIXNUMP (XCAR (tem))) | ||
| 513 | /* FIXME: This modifies typically pure hash-cons'd data, so its | ||
| 514 | correctness is quite delicate. */ | ||
| 515 | XSETCAR (tem, make_fixnum (offset)); | ||
| 516 | } | ||
| 517 | } | ||
| 518 | /* Lisp_Subrs have a slot for it. */ | 519 | /* Lisp_Subrs have a slot for it. */ |
| 519 | else if (SUBRP (fun) && !SUBR_NATIVE_COMPILEDP (fun)) | 520 | if (SUBRP (fun) && !SUBR_NATIVE_COMPILEDP (fun)) |
| 520 | { | 521 | XSUBR (fun)->doc = offset; |
| 521 | XSUBR (fun)->doc = offset; | 522 | else |
| 522 | } | ||
| 523 | |||
| 524 | /* Bytecode objects sometimes have slots for it. */ | ||
| 525 | else if (COMPILEDP (fun)) | ||
| 526 | { | 523 | { |
| 527 | /* This bytecode object must have a slot for the | 524 | AUTO_STRING (format, "Ignoring DOC string on non-subr: %S"); |
| 528 | docstring, since we've found a docstring for it. */ | 525 | CALLN (Fmessage, format, obj); |
| 529 | if (PVSIZE (fun) > COMPILED_DOC_STRING | ||
| 530 | /* Don't overwrite a non-docstring value placed there, | ||
| 531 | * such as the symbols used for Oclosures. */ | ||
| 532 | && VALID_DOCSTRING_P (AREF (fun, COMPILED_DOC_STRING))) | ||
| 533 | ASET (fun, COMPILED_DOC_STRING, make_fixnum (offset)); | ||
| 534 | else | ||
| 535 | { | ||
| 536 | AUTO_STRING (format, | ||
| 537 | (PVSIZE (fun) > COMPILED_DOC_STRING | ||
| 538 | ? "Docstring slot busy for %s" | ||
| 539 | : "No docstring slot for %s")); | ||
| 540 | CALLN (Fmessage, format, | ||
| 541 | (SYMBOLP (obj) | ||
| 542 | ? SYMBOL_NAME (obj) | ||
| 543 | : build_string ("<anonymous>"))); | ||
| 544 | } | ||
| 545 | } | 526 | } |
| 546 | } | 527 | } |
| 547 | 528 | ||
| @@ -776,6 +757,7 @@ compute the correct value for the current terminal in the nil case. */); | |||
| 776 | doc: /* If nil, a nil `text-quoting-style' is treated as `grave'. */); | 757 | doc: /* If nil, a nil `text-quoting-style' is treated as `grave'. */); |
| 777 | /* Initialized by ‘main’. */ | 758 | /* Initialized by ‘main’. */ |
| 778 | 759 | ||
| 760 | defsubr (&Sdocumentation_stringp); | ||
| 779 | defsubr (&Sdocumentation); | 761 | defsubr (&Sdocumentation); |
| 780 | defsubr (&Ssubr_documentation); | 762 | defsubr (&Ssubr_documentation); |
| 781 | defsubr (&Sdocumentation_property); | 763 | defsubr (&Sdocumentation_property); |
diff --git a/src/print.c b/src/print.c index c6a3dba3163..c2beff0ed55 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1412,7 +1412,7 @@ print_preprocess (Lisp_Object obj) | |||
| 1412 | && SYMBOLP (obj) | 1412 | && SYMBOLP (obj) |
| 1413 | && !SYMBOL_INTERNED_P (obj))) | 1413 | && !SYMBOL_INTERNED_P (obj))) |
| 1414 | { /* OBJ appears more than once. Let's remember that. */ | 1414 | { /* OBJ appears more than once. Let's remember that. */ |
| 1415 | if (!FIXNUMP (num)) | 1415 | if (SYMBOLP (num)) /* In practice, nil or t. */ |
| 1416 | { | 1416 | { |
| 1417 | print_number_index++; | 1417 | print_number_index++; |
| 1418 | /* Negative number indicates it hasn't been printed yet. */ | 1418 | /* Negative number indicates it hasn't been printed yet. */ |
| @@ -2265,6 +2265,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2265 | goto next_obj; | 2265 | goto next_obj; |
| 2266 | } | 2266 | } |
| 2267 | } | 2267 | } |
| 2268 | else if (STRINGP (num)) | ||
| 2269 | { | ||
| 2270 | strout (SDATA (num), SCHARS (num), SBYTES (num), printcharfun); | ||
| 2271 | goto next_obj; | ||
| 2272 | } | ||
| 2268 | } | 2273 | } |
| 2269 | 2274 | ||
| 2270 | print_depth++; | 2275 | print_depth++; |
| @@ -2554,11 +2559,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2554 | goto next_obj; | 2559 | goto next_obj; |
| 2555 | case PVEC_SUB_CHAR_TABLE: | 2560 | case PVEC_SUB_CHAR_TABLE: |
| 2556 | { | 2561 | { |
| 2557 | /* Make each lowest sub_char_table start a new line. | ||
| 2558 | Otherwise we'll make a line extremely long, which | ||
| 2559 | results in slow redisplay. */ | ||
| 2560 | if (XSUB_CHAR_TABLE (obj)->depth == 3) | ||
| 2561 | printchar ('\n', printcharfun); | ||
| 2562 | print_c_string ("#^^[", printcharfun); | 2562 | print_c_string ("#^^[", printcharfun); |
| 2563 | int n = sprintf (buf, "%d %d", | 2563 | int n = sprintf (buf, "%d %d", |
| 2564 | XSUB_CHAR_TABLE (obj)->depth, | 2564 | XSUB_CHAR_TABLE (obj)->depth, |
| @@ -2664,7 +2664,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2664 | /* With the print-circle feature. */ | 2664 | /* With the print-circle feature. */ |
| 2665 | Lisp_Object num = Fgethash (next, Vprint_number_table, | 2665 | Lisp_Object num = Fgethash (next, Vprint_number_table, |
| 2666 | Qnil); | 2666 | Qnil); |
| 2667 | if (FIXNUMP (num)) | 2667 | if (!(NILP (num) || EQ (num, Qt))) |
| 2668 | { | 2668 | { |
| 2669 | print_c_string (" . ", printcharfun); | 2669 | print_c_string (" . ", printcharfun); |
| 2670 | obj = next; | 2670 | obj = next; |
| @@ -2928,7 +2928,10 @@ This variable should not be set with `setq'; bind it with a `let' instead. */); | |||
| 2928 | DEFVAR_LISP ("print-number-table", Vprint_number_table, | 2928 | DEFVAR_LISP ("print-number-table", Vprint_number_table, |
| 2929 | doc: /* A vector used internally to produce `#N=' labels and `#N#' references. | 2929 | doc: /* A vector used internally to produce `#N=' labels and `#N#' references. |
| 2930 | The Lisp printer uses this vector to detect Lisp objects referenced more | 2930 | The Lisp printer uses this vector to detect Lisp objects referenced more |
| 2931 | than once. | 2931 | than once. If an entry contains a number, then the corresponding key is |
| 2932 | referenced more than once: a positive sign indicates that it's already been | ||
| 2933 | printed, and the absolute value indicates the number to use when printing. | ||
| 2934 | If an entry contains a string, that string is printed instead. | ||
| 2932 | 2935 | ||
| 2933 | When you bind `print-continuous-numbering' to t, you should probably | 2936 | When you bind `print-continuous-numbering' to t, you should probably |
| 2934 | also bind `print-number-table' to nil. This ensures that the value of | 2937 | also bind `print-number-table' to nil. This ensures that the value of |