[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/relint ff06875 09/12: Scan mutation and binding of cert
From: |
Mattias Engdegård |
Subject: |
[elpa] externals/relint ff06875 09/12: Scan mutation and binding of certain known regexp variables |
Date: |
Thu, 30 Jan 2020 10:53:40 -0500 (EST) |
branch: externals/relint
commit ff0687590f5a4519136bd73842f58ba2000559ac
Author: Mattias Engdegård <address@hidden>
Commit: Mattias Engdegård <address@hidden>
Scan mutation and binding of certain known regexp variables
This includes page-delimiter, paragraph-separate, paragraph-start,
sentence-end, comment-start-skip and comment-end-skip.
---
relint.el | 41 ++++++++++++++++++++++++++++-------------
test/9.elisp | 20 ++++++++++++++++++++
test/9.expected | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/relint.el b/relint.el
index 74c0417..c28fa7e 100644
--- a/relint.el
+++ b/relint.el
@@ -1044,6 +1044,11 @@ or in the car of an element."
(relint--check-re-string
re (format "%s (%s)" name rule-name) file pos path))))))
+(defconst relint--known-regexp-variables
+ '(page-delimiter paragraph-separate paragraph-start
+ sentence-end comment-start-skip comment-end-skip)
+ "List of known (global or buffer-local) regexp variables.")
+
(defun relint--regexp-generators (expr expanded)
"List of regexp-generating functions and variables used in EXPR.
EXPANDED is a list of expanded functions, to prevent recursion."
@@ -1055,9 +1060,7 @@ EXPANDED is a list of expanded functions, to prevent
recursion."
(and def
(eq (cadr def) 'expr)
(relint--regexp-generators (caddr def) expanded)))
- (and (or (memq expr '(page-delimiter paragraph-separate
- paragraph-start sentence-end
- comment-start-skip comment-end-skip))
+ (and (or (memq expr relint--known-regexp-variables)
;; This is guesswork, but effective.
(string-match-p
(rx (or (seq bos (or "regexp" "regex"))
@@ -1288,6 +1291,11 @@ return (NAME); on syntax error, return nil."
(cadr binding) mutables file pos (cons 1 path))
(let ((val (catch 'relint-eval
(list (relint--eval (cadr binding))))))
+ (when (and (consp val)
+ (stringp (car val))
+ (memq (car binding) relint--known-regexp-variables))
+ ;; Setting a special buffer-local regexp.
+ (relint--check-re (car val) (car binding) file pos (cons 1 path)))
(cons (car binding)
(if (eq val 'no-value)
nil
@@ -1341,7 +1349,7 @@ directly."
(setq index (1+ index))))))
(`(let* ,(and (pred listp) bindings) . ,body)
(relint--check-let* bindings body mutables file pos path 0))
- (`(setq . ,args)
+ (`(,(or 'setq 'setq-local) . ,args)
;; Only mutate lexical variables in the mutation list, which means
;; that this form will be executed exactly once during their remaining
;; lifetime. Other lexical vars will just be invalidated since we
@@ -1352,15 +1360,19 @@ directly."
(expr (cadr args)))
(relint--check-form-recursively-2
expr mutables file pos (cons i path))
- ;; Invalidate the variable if it was local; otherwise, ignore.
- (let ((local (assq name relint--locals)))
- (when local
- (setcdr local
- (and (memq name mutables)
- (let ((val (catch 'relint-eval
- (list (relint--eval expr)))))
- (and (not (eq val 'no-value))
- val)))))))
+ (if (memq name relint--known-regexp-variables)
+ ;; Setting a special buffer-local regexp.
+ (relint--check-re expr name file pos (cons i path))
+
+ ;; Invalidate the variable if it was local; otherwise, ignore.
+ (let ((local (assq name relint--locals)))
+ (when local
+ (setcdr local
+ (and (memq name mutables)
+ (let ((val (catch 'relint-eval
+ (list (relint--eval expr)))))
+ (and (not (eq val 'no-value))
+ val))))))))
(setq args (cddr args))
(setq i (+ i 2)))))
(`(push ,expr ,(and (pred symbolp) name))
@@ -1581,6 +1593,9 @@ directly."
(cons 'val val))))
(list 'expr re-arg))))
(push (cons name new) relint--variables)))))
+ (`(set (make-local-variable ',name) ,expr)
+ (when (memq name relint--known-regexp-variables)
+ (relint--check-re expr name file pos (cons 2 path))))
(`(define-generic-mode ,name ,_ ,_ ,font-lock-list ,auto-mode-list . ,_)
(let ((origin (format "define-generic-mode %s" name)))
(relint--check-font-lock-keywords font-lock-list origin
diff --git a/test/9.elisp b/test/9.elisp
new file mode 100644
index 0000000..9c6e46e
--- /dev/null
+++ b/test/9.elisp
@@ -0,0 +1,20 @@
+;;; Relint test file 9 -*- emacs-lisp -*-
+
+;; Test mutation/binding of known variables for detecting regexps.
+
+(defun test-9 ()
+ (setq-local page-delimiter "[aa]")
+ (setq-local paragraph-separate "[bb]")
+ (setq-local paragraph-start "[cc]")
+ (setq-local sentence-end "[dd]")
+ (setq-local comment-start-skip "[ee]")
+ (setq-local comment-end-skip "[ff]")
+
+ (setq sentence-end "[gg]")
+ (set (make-local-variable 'paragraph-start) "[hh]")
+
+ (let ((paragraph-separate "[ii]")
+ (page-delimiter "[jj]"))
+ (let* ((comment-start-skip "[kk]")
+ (comment-end-skip "[ll]"))
+ (asdf))))
diff --git a/test/9.expected b/test/9.expected
new file mode 100644
index 0000000..2400b56
--- /dev/null
+++ b/test/9.expected
@@ -0,0 +1,36 @@
+9.elisp:6:30: In page-delimiter: Duplicated `a' inside character alternative
(pos 2)
+ "[aa]"
+ ..^
+9.elisp:7:34: In paragraph-separate: Duplicated `b' inside character
alternative (pos 2)
+ "[bb]"
+ ..^
+9.elisp:8:31: In paragraph-start: Duplicated `c' inside character alternative
(pos 2)
+ "[cc]"
+ ..^
+9.elisp:9:28: In sentence-end: Duplicated `d' inside character alternative
(pos 2)
+ "[dd]"
+ ..^
+9.elisp:10:34: In comment-start-skip: Duplicated `e' inside character
alternative (pos 2)
+ "[ee]"
+ ..^
+9.elisp:11:32: In comment-end-skip: Duplicated `f' inside character
alternative (pos 2)
+ "[ff]"
+ ..^
+9.elisp:13:22: In sentence-end: Duplicated `g' inside character alternative
(pos 2)
+ "[gg]"
+ ..^
+9.elisp:14:47: In paragraph-start: Duplicated `h' inside character alternative
(pos 2)
+ "[hh]"
+ ..^
+9.elisp:16:29: In paragraph-separate: Duplicated `i' inside character
alternative (pos 2)
+ "[ii]"
+ ..^
+9.elisp:17:25: In page-delimiter: Duplicated `j' inside character alternative
(pos 2)
+ "[jj]"
+ ..^
+9.elisp:18:32: In comment-start-skip: Duplicated `k' inside character
alternative (pos 2)
+ "[kk]"
+ ..^
+9.elisp:19:30: In comment-end-skip: Duplicated `l' inside character
alternative (pos 2)
+ "[ll]"
+ ..^
- [elpa] externals/relint updated (5c6079b -> 3315f03), Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 1103f5c 01/12: Suppress error summary in noninteractive mode if no errors (bug #6), Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 3885977 03/12: Adjust package header, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint f5bbfdb 02/12: Describe exit status in relint-batch doc string, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 2ebd33d 04/12: Disable tests requiring Emacs 27 for the time being (bug #7), Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 800f5cc 06/12: Scan function/macro doc strings for hints to regexp arguments, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint ff06875 09/12: Scan mutation and binding of certain known regexp variables,
Mattias Engdegård <=
- [elpa] externals/relint dcb474b 10/12: Detect user-defined regexp-returning functions, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint ccfc9e0 08/12: Scan all variables whose name contain '-font-lock-keywords', Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 32dbad1 07/12: Scan arguments to syntax-propertize-{precompile-}rules, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 641cf71 05/12: Require Emacs 26.1 (for mapcan), Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 5b684ea 11/12: Require xr 1.15, Mattias Engdegård, 2020/01/30
- [elpa] externals/relint 3315f03 12/12: Increment version to 1.13, Mattias Engdegård, 2020/01/30