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

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

[elpa] externals/relint 151dbb8 23/44: Handle some destructive list func


From: Mattias Engdegård
Subject: [elpa] externals/relint 151dbb8 23/44: Handle some destructive list functions
Date: Tue, 26 Mar 2019 12:57:28 -0400 (EDT)

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

    Handle some destructive list functions
    
    Safely evaluate nconc, delete, delq, nreverse, nbutlast and delete-dups.
---
 trawl.el | 46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/trawl.el b/trawl.el
index a5d84da..5149a20 100644
--- a/trawl.el
+++ b/trawl.el
@@ -163,7 +163,7 @@
     format format-message
     regexp-quote regexp-opt regexp-opt-charset
     reverse
-    member memq remove remq
+    member memq remove remq member-ignore-case
     assoc assq rassoc rassq
     identity
     string make-string make-list
@@ -185,6 +185,15 @@
     sequencep vectorp arrayp
     + - * / % mod 1+ 1- max min < <= = > >= /= abs))
 
+;; Alist mapping non-safe functions to semantically equivalent safe
+;; alternatives.
+(defconst trawl--safe-alternatives
+  '((nconc . append)
+    (delete . remove)
+    (delq . remq)
+    (nreverse . reverse)
+    (nbutlast . butlast)))
+
 ;; Transform FORM into an expression that is safe to evaluate with the
 ;; bindings in trawl--variables and parameters in PARAMS.
 ;; Return the transformed expression with known variables substituted away,
@@ -217,9 +226,10 @@
   (cond
    ;; Functions (and some special forms/macros) considered safe.
    ((symbolp f)
-    (and (or (memq f trawl--safe-functions)
-             (memq f '(if when unless and or)))
-         f))
+    (cond ((or (memq f trawl--safe-functions)
+               (memq f '(if when unless and or)))
+           f)
+          ((cdr (assq f trawl--safe-alternatives)))))
    ((atom f) nil)
    ((eq (car f) 'function)
     (trawl--safe-function (cadr f) params))
@@ -263,6 +273,7 @@
 ;; become `no-value'.
 (defun trawl--eval (form)
   (cond
+   ((memq form '(nil t)) form)
    ((symbolp form)
     (and form
          (let ((binding (assq form trawl--variables)))
@@ -317,6 +328,17 @@
         (eval (cons (car form)
                     (mapcar (lambda (x) (list 'quote x)) args))))))
 
+   ((assq (car form) trawl--safe-alternatives)
+    (trawl--eval (cons (cdr (assq (car form) trawl--safe-alternatives))
+                       (cdr form))))
+
+   ;; delete-dups: Work on a copy of the argument.
+   ((eq (car form) 'delete-dups)
+    (let ((arg (trawl--eval (cadr form))))
+      (if (eq arg 'no-value)
+          'no-value
+        (delete-dups (copy-sequence arg)))))
+
    ((memq (car form) '(\` backquote-list*))
     (trawl--eval (macroexpand form)))
 
@@ -351,7 +373,7 @@
    ;; evaluate.
    ((memq (car form) '(mapcar mapcan))
     (let ((fun (trawl--safe-function (trawl--eval (cadr form)) nil))
-          (seq (delq nil (trawl--eval-list (caddr form)))))
+          (seq (remq nil (trawl--eval-list (caddr form)))))
       (if fun
           (condition-case err
               (funcall (car form) fun seq)
@@ -450,10 +472,20 @@
    ;; Pure structure-generating functions: Apply even if we cannot evaluate
    ;; all arguments (they will be nil), because we want a reasonable
    ;; approximation of the structure.
-   ((memq (car form) '(list append cons))
+   ((memq (car form) '(list append cons reverse remove remq))
     (apply (car form) (mapcar #'trawl--eval-list (cdr form))))
 
-   ((eq (car form) 'purecopy)
+   ((assq (car form) trawl--safe-alternatives)
+    (trawl--eval-list (cons (cdr (assq (car form) trawl--safe-alternatives))
+                            (cdr form))))
+
+   ((eq (car form) 'delete-dups)
+    (let ((arg (trawl--eval (cadr form))))
+      (if (eq arg 'no-value)
+          'no-value
+        (delete-dups (copy-sequence arg)))))
+
+   ((memq (car form) '(purecopy copy-sequence copy-alist))
     (trawl--eval-list (cadr form)))
 
    ((memq (car form) '(\` backquote-list*))



reply via email to

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