emacs-elpa-diffs
[Top][All Lists]
Advanced

[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]"
+   ..^



reply via email to

[Prev in Thread] Current Thread [Next in Thread]