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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/relint b890b5a 15/23: Track mutation in push and lambda


From: Mattias Engdegård
Subject: [elpa] externals/relint b890b5a 15/23: Track mutation in push and lambda in phase 2
Date: Sun, 29 Sep 2019 15:34:53 -0400 (EDT)

branch: externals/relint
commit b890b5ae5c78971efd62dcb0c0c33b982e0120ee
Author: Mattias Engdegård <address@hidden>
Commit: Mattias Engdegård <address@hidden>

    Track mutation in push and lambda in phase 2
---
 relint.el       | 29 +++++++++++++++++++++++++++++
 test/5.elisp    | 14 ++++++++++++++
 test/5.expected |  9 +++++++++
 3 files changed, 52 insertions(+)

diff --git a/relint.el b/relint.el
index 9d2d6e8..65fbd2c 100644
--- a/relint.el
+++ b/relint.el
@@ -1201,6 +1201,20 @@ directly."
                                    val)))))))
          (setq args (cddr args))
          (setq i (+ i 2)))))
+    (`(push ,expr ,(and (pred symbolp) name))
+     ;; Treat (push EXPR NAME) as (setq NAME (cons EXPR NAME)).
+     (relint--check-form-recursively-2 expr mutables file pos (cons 1 path))
+     (let ((local (assq name relint--locals)))
+       (when local
+         (setcdr local
+                 (let ((old-val (cdr local)))
+                   (and old-val
+                        (memq name mutables)
+                        (let ((val (catch 'relint-eval
+                                     (list (cons (relint--eval expr)
+                                                 (car old-val))))))
+                          (and (consp val)
+                               val))))))))
     (`(,(or 'if 'and 'or 'when 'unless) ,(and (pred consp) arg1) . ,rest)
      ;; Only first arg is executed unconditionally.
      ;; FIXME: A conditional in the tail position of its environment binding
@@ -1228,6 +1242,21 @@ directly."
               (car body) argnames file pos (cons i path)))
            (setq body (cdr body))
            (setq i (1+ i))))))
+    (`(lambda ,(and (pred listp) arglist) . ,body)
+     ;; Create local bindings for formal arguments (with unknown values).
+     (let* ((argnames (mapcan (lambda (arg)
+                                (and (symbolp arg)
+                                     (not (memq arg '(&optional &rest)))
+                                     (list arg)))
+                              arglist))
+            (relint--locals (append (mapcar #'list argnames) relint--locals)))
+       (let ((i 2))
+         (while (consp body)
+           (when (consp (car body))
+             (relint--check-form-recursively-2
+              (car body) argnames file pos (cons i path)))
+           (setq body (cdr body))
+           (setq i (1+ i))))))
     (_ 
      (pcase form
        (`(,(or 'looking-at 're-search-forward 're-search-backward
diff --git a/test/5.elisp b/test/5.elisp
index 406ef69..4d0e9b2 100644
--- a/test/5.elisp
+++ b/test/5.elisp
@@ -25,3 +25,17 @@
         (z "M"))
     (setq z "B")
     (looking-at (concat x y z "]"))))
+
+(defun test-push (x)
+  (let ((x (list "a")))
+    (push "+" x)
+    (looking-at (string-join x))))
+
+(defun test-setq-defun (x)
+  (setq x "[CC]")
+  (looking-at x))
+
+(defun test-setq-lambda ()
+  (lambda (y)
+    (setq y "[DD]")
+    (looking-at y)))
diff --git a/test/5.expected b/test/5.expected
index 75c59ea..7bde92e 100644
--- a/test/5.expected
+++ b/test/5.expected
@@ -10,3 +10,12 @@
 5.elisp:27:17: In call to looking-at: Duplicated `B' inside character 
alternative (pos 2)
   "[BB]"
    ..^
+5.elisp:32:17: In call to looking-at: Unescaped literal `+' (pos 0)
+  "+a"
+   ^
+5.elisp:36:15: In call to looking-at: Duplicated `C' inside character 
alternative (pos 2)
+  "[CC]"
+   ..^
+5.elisp:41:17: In call to looking-at: Duplicated `D' inside character 
alternative (pos 2)
+  "[DD]"
+   ..^



reply via email to

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