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

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

[elpa] externals/relint e824db0 38/44: Expand locally defined macros


From: Mattias Engdegård
Subject: [elpa] externals/relint e824db0 38/44: Expand locally defined macros
Date: Tue, 26 Mar 2019 12:57:31 -0400 (EDT)

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

    Expand locally defined macros
---
 relint.el | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/relint.el b/relint.el
index 7e85bb3..4847fac 100644
--- a/relint.el
+++ b/relint.el
@@ -175,6 +175,11 @@
 ;; and BODY its single body expression.
 (defvar relint--function-defs)
 
+;; List of possibly safe macros defined in the current file, each
+;; element on the form (MACRO ARGS BODY), where ARGS is the lambda list
+;; and BODY its single body expression.
+(defvar relint--macro-defs)
+
 ;; Functions that are safe to call during evaluation.
 ;; Except for altering the match state, these are pure.
 ;; More functions could be added if there is evidence that it would
@@ -213,6 +218,7 @@
     assoc-default member-ignore-case alist-get
     last butlast number-sequence
     plist-get plist-member
+    1value
     consp atom stringp symbolp listp nlistp booleanp
     integerp numberp natnump fixnump bignump characterp zerop
     sequencep vectorp arrayp
@@ -311,9 +317,6 @@
              (throw 'relint-eval 'no-value)))))
    ((atom form)
     form)
-   ((not (symbolp (car form)))
-    (relint--add-to-error-buffer (format "eval error: %S\n" form))
-    (throw 'relint-eval 'no-value))
 
    ((eq (car form) 'quote)
     (if (and (consp (cadr form))
@@ -345,6 +348,14 @@
              (expr (cadr fn)))
         (relint--apply formals args expr))))
 
+   ;; Locally defined macros: try expanding.
+   ((assq (car form) relint--macro-defs)
+    (let ((args (cdr form)))
+      (let* ((macro (cdr (assq (car form) relint--macro-defs)))
+             (formals (car macro))
+             (expr (cadr macro)))
+        (relint--eval (relint--apply formals args expr)))))
+
    ;; replace-regexp-in-string: wrap the rep argument if it's a function.
    ((eq (car form) 'replace-regexp-in-string)
     (let ((all-args (mapcar #'relint--eval (cdr form))))
@@ -654,13 +665,20 @@
   (pcase form
     (`(,(or `defun `defmacro `defsubst)
        ,name ,args . ,body)
-     ;; Save the function for possible use.
-     (unless (eq (car form) 'defmacro)
-       (when (stringp (car body))
-         (setq body (cdr body)))          ; Skip doc string.
-       ;; Only consider functions with single-expression bodies.
-       (when (= (length body) 1)
-         (push (list name args (car body)) relint--function-defs)))
+
+     ;; Save the function or macro for possible use.
+     (while (or (stringp (car body))
+                (and (consp (car body))
+                     (memq (caar body) '(interactive declare))))
+       (setq body (cdr body)))          ; Skip doc and declarations.
+     ;; Only consider functions/macros with single-expression bodies.
+     (when (= (length body) 1)
+       (let ((entry (list name args (car body))))
+         (if (eq (car form) 'defmacro)
+             (push entry relint--macro-defs)
+           (push entry relint--function-defs))
+         ))
+
      ;; If any argument looks like a regexp, remember it so that it can be
      ;; checked in calls.
      (when (consp args)
@@ -865,6 +883,7 @@
             (relint--checked-variables nil)
             (relint--regexp-functions nil)
             (relint--function-defs nil)
+            (relint--macro-defs nil)
             )
         (relint--check-buffer file forms #'relint--check-form-recursively-1)
         (relint--check-buffer file forms #'relint--check-form-recursively-2)))



reply via email to

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