Add more function declarations

* lisp/subr.el (buffer-narrowed-p, sha1, match-substitute-replacement)
(version-to-list, version<, version<=, version=)
(function-get, subregexp-context-p, split-string)
(combine-and-quote-strings, split-string-and-unquote)
(replace-regexp-in-string, syntax-after)
(string-trim-left, string-trim):
* lisp/emacs-lisp/subr-x.el (hash-table-empty-p, hash-table-keys)
(hash-table-values, string-glyph-split)
(string-clean-whitespace, string-fill, string-limit)
(string-pixel-width):
* lisp/env.el (substitute-env-vars, substitute-env-in-file-name)
(setenv-internal):
* lisp/emacs-lisp/rx.el (rx-to-string):
* lisp/emacs-lisp/regexp-opt.el (regexp-opt-depth)
(regexp-opt-charset):
Add appropriate declarations: pure, side-effect-free, and/or
important-return-value.
This commit is contained in:
Mattias Engdegård 2023-05-26 12:28:15 +02:00
parent 54ac1165bc
commit ef778f5143
5 changed files with 32 additions and 1 deletions

View file

@ -154,6 +154,7 @@ usually more efficient than that of a simplified version:
"Return the depth of REGEXP.
This means the number of non-shy regexp grouping constructs
\(parenthesized expressions) in REGEXP."
(declare (pure t) (side-effect-free t))
(save-match-data
;; Hack to signal an error if REGEXP does not have balanced parentheses.
(string-match regexp "")
@ -270,6 +271,7 @@ Merges keywords to avoid backtracking in Emacs's regexp matcher."
CHARS should be a list of characters.
If CHARS is the empty list, the return value is a regexp that
never matches anything."
(declare (pure t) (side-effect-free t))
;; The basic idea is to find character ranges. Also we take care in the
;; position of character set meta characters in the character set regexp.
;;

View file

@ -1144,6 +1144,7 @@ If NO-GROUP is non-nil, don't bracket the result in a non-capturing
group.
For extending the `rx' notation in FORM, use `rx-define' or `rx-let-eval'."
(declare (important-return-value t))
(let* ((item (rx--translate form))
(exprs (if no-group
(car item)

View file

@ -81,18 +81,22 @@ Note how the single `-' got converted into a list before
threading."
(declare (indent 0) (debug thread-first))
`(internal--thread-argument nil ,@forms))
(defsubst hash-table-empty-p (hash-table)
"Check whether HASH-TABLE is empty (has 0 elements)."
(declare (side-effect-free t))
(zerop (hash-table-count hash-table)))
(defsubst hash-table-keys (hash-table)
"Return a list of keys in HASH-TABLE."
(declare (side-effect-free t))
(let ((keys nil))
(maphash (lambda (k _) (push k keys)) hash-table)
keys))
(defsubst hash-table-values (hash-table)
"Return a list of values in HASH-TABLE."
(declare (side-effect-free t))
(let ((values nil))
(maphash (lambda (_ v) (push v values)) hash-table)
values))
@ -149,6 +153,7 @@ carriage return."
All sequences of whitespaces in STRING are collapsed into a
single space character, and leading/trailing whitespace is
removed."
(declare (important-return-value t))
(let ((blank "[[:blank:]\r\n]+"))
(string-trim (replace-regexp-in-string blank " " string t t)
blank blank)))
@ -158,6 +163,7 @@ removed."
Wrapping is done where there is whitespace. If there are
individual words in STRING that are longer than LENGTH, the
result will have lines that are longer than LENGTH."
(declare (important-return-value t))
(with-temp-buffer
(insert string)
(goto-char (point-min))
@ -189,6 +195,7 @@ coding system that doesn't specify a BOM, like `utf-16le' or `utf-16be'.
When shortening strings for display purposes,
`truncate-string-to-width' is almost always a better alternative
than this function."
(declare (important-return-value t))
(unless (natnump length)
(signal 'wrong-type-argument (list 'natnump length)))
(if coding-system
@ -324,6 +331,7 @@ as the new values of the bound variables in the recursive invocation."
;;;###autoload
(defun string-pixel-width (string)
"Return the width of STRING in pixels."
(declare (important-return-value t))
(if (zerop (length string))
0
;; Keeping a work buffer around is more efficient than creating a
@ -344,6 +352,7 @@ This takes into account combining characters and grapheme clusters:
if compositions are enabled, each sequence of characters composed
on display into a single grapheme cluster is treated as a single
indivisible unit."
(declare (side-effect-free t))
(let ((result nil)
(start 0)
comp)

View file

@ -76,6 +76,7 @@ If it is non-nil and not a function, references to undefined variables are
left unchanged.
Use `$$' to insert a single dollar sign."
(declare (important-return-value t))
(let ((start 0))
(while (string-match env--substitute-vars-regexp string start)
(cond ((match-beginning 1)
@ -94,6 +95,7 @@ Use `$$' to insert a single dollar sign."
string))
(defun substitute-env-in-file-name (filename)
(declare (important-return-value t))
(substitute-env-vars filename
;; How 'bout we lookup other tables than the env?
;; E.g. we could accept bookmark names as well!
@ -104,6 +106,7 @@ Use `$$' to insert a single dollar sign."
(defun setenv-internal (env variable value keep-empty)
"Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY.
Changes ENV by side-effect, and returns its new value."
(declare (important-return-value t))
(let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)"))
(case-fold-search nil)
(scan env)

View file

@ -4006,6 +4006,7 @@ See also `locate-user-emacs-file'.")
(defsubst buffer-narrowed-p ()
"Return non-nil if the current buffer is narrowed."
(declare (side-effect-free t))
(/= (- (point-max) (point-min)) (buffer-size)))
(defmacro with-restriction (start end &rest rest)
@ -4132,7 +4133,7 @@ See Info node `(elisp)Security Considerations'.
If the optional POSIX argument is non-nil, ARGUMENT is quoted
according to POSIX shell quoting rules, regardless of the
system's shell."
(cond
(cond
((and (not posix) (eq system-type 'ms-dos))
;; Quote using double quotes, but escape any existing quotes in
;; the argument with backslashes.
@ -4264,6 +4265,7 @@ string; otherwise returna 40-character string.
Note that SHA-1 is not collision resistant and should not be used
for anything security-related. See `secure-hash' for
alternatives."
(declare (side-effect-free t))
(secure-hash 'sha1 object start end binary))
(defun function-get (f prop &optional autoload)
@ -4271,6 +4273,7 @@ alternatives."
If AUTOLOAD is non-nil and F is autoloaded, try to load it
in the hope that it will set PROP. If AUTOLOAD is `macro', do it only
if it's an autoloaded macro."
(declare (important-return-value t))
(let ((val nil))
(while (and (symbolp f)
(null (setq val (get f prop)))
@ -5226,6 +5229,7 @@ In other words, all back-references in the form `\\&' and `\\N'
are substituted with actual strings matched by the last search.
Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same
meaning as for `replace-match'."
(declare (side-effect-free t))
(let ((match (match-string 0 string)))
(save-match-data
(match-data--translate (- (match-beginning 0)))
@ -5287,6 +5291,7 @@ A non-subregexp context is for example within brackets, or within a
repetition bounds operator `\\=\\{...\\}', or right after a `\\'.
If START is non-nil, it should be a position in REGEXP, smaller
than POS, and known to be in a subregexp context."
(declare (important-return-value t))
;; Here's one possible implementation, with the great benefit that it
;; reuses the regexp-matcher's own parser, so it understands all the
;; details of the syntax. A disadvantage is that it needs to match the
@ -5368,6 +5373,7 @@ case that you wish to retain zero-length substrings when splitting on
whitespace, use `(split-string STRING split-string-default-separators)'.
Modifies the match data; use `save-match-data' if necessary."
(declare (important-return-value t))
(let* ((keep-nulls (not (if separators omit-nulls t)))
(rexp (or separators split-string-default-separators))
(start 0)
@ -5425,6 +5431,7 @@ Only some SEPARATORs will work properly.
Note that this is not intended to protect STRINGS from
interpretation by shells, use `shell-quote-argument' for that."
(declare (important-return-value t))
(let* ((sep (or separator " "))
(re (concat "[\\\"]" "\\|" (regexp-quote sep))))
(mapconcat
@ -5439,6 +5446,7 @@ interpretation by shells, use `shell-quote-argument' for that."
It understands Emacs Lisp quoting within STRING, such that
(split-string-and-unquote (combine-and-quote-strings strs)) == strs
The SEPARATOR regexp defaults to \"\\s-+\"."
(declare (important-return-value t))
(let ((sep (or separator "\\s-+"))
(i (string-search "\"" string)))
(if (null i)
@ -5506,6 +5514,7 @@ To replace only the first match (if any), make REGEXP match up to \\\\='
and replace a sub-expression, e.g.
(replace-regexp-in-string \"\\\\(foo\\\\).*\\\\\\='\" \"bar\" \" foo foo\" nil nil 1)
=> \" bar foo\""
(declare (important-return-value t))
;; To avoid excessive consing from multiple matches in long strings,
;; don't just call `replace-match' continually. Walk down the
@ -5861,6 +5870,7 @@ from `standard-syntax-table' otherwise."
(defun syntax-after (pos)
"Return the raw syntax descriptor for the char after POS.
If POS is outside the buffer's accessible portion, return nil."
(declare (important-return-value t))
(unless (or (< pos (point-min)) (>= pos (point-max)))
(let ((st (if parse-sexp-lookup-properties
(get-char-property pos 'syntax-table))))
@ -6675,6 +6685,7 @@ Examples of version conversion:
\"22.8beta3\" (22 8 -2 3)
See documentation for `version-separator' and `version-regexp-alist'."
(declare (side-effect-free t))
(unless (stringp ver)
(error "Version must be a string"))
;; Change .x.y to 0.x.y
@ -6805,6 +6816,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
which is higher than \"1alpha\", which is higher than \"1snapshot\".
Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
(declare (side-effect-free t))
(version-list-< (version-to-list v1) (version-to-list v2)))
(defun version<= (v1 v2)
@ -6815,6 +6827,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
which is higher than \"1alpha\", which is higher than \"1snapshot\".
Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
(declare (side-effect-free t))
(version-list-<= (version-to-list v1) (version-to-list v2)))
(defun version= (v1 v2)
@ -6825,6 +6838,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
which is higher than \"1alpha\", which is higher than \"1snapshot\".
Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
(declare (side-effect-free t))
(version-list-= (version-to-list v1) (version-to-list v2)))
(defvar package--builtin-versions
@ -6947,6 +6961,7 @@ returned list are in the same order as in TREE.
"Trim STRING of leading string matching REGEXP.
REGEXP defaults to \"[ \\t\\n\\r]+\"."
(declare (important-return-value t))
(if (string-match (if regexp
(concat "\\`\\(?:" regexp "\\)")
"\\`[ \t\n\r]+")
@ -6969,6 +6984,7 @@ REGEXP defaults to \"[ \\t\\n\\r]+\"."
"Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT.
TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
(declare (important-return-value t))
(string-trim-left (string-trim-right string trim-right) trim-left))
;; The initial anchoring is for better performance in searching matches.