[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)))
- [elpa] externals/relint 0604fad 43/44: Use a custom mode for the *relint* buffer, (continued)
- [elpa] externals/relint 0604fad 43/44: Use a custom mode for the *relint* buffer, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint ee70350 44/44: FSF copyright, URL, and increment version to 1.5, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 0fd1d46 29/44: Rename trawl to relint, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint e882b71 42/44: Detect regexps spliced into [...], Mattias Engdegård, 2019/03/26
- [elpa] externals/relint c1b92cc 36/44: Wrap and evaluate defined functions passed as parameters, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint d4a6d46 37/44: Evaluate some more functions, macros and special forms, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 019f4cf 10/44: Rewrite the partial evaluator and extend coverage, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 365dc91 41/44: Check bad skip-set provenance, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint a1829d7 39/44: Refactor the file scanning and linting code, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 0f76132 40/44: Add README.org, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint e824db0 38/44: Expand locally defined macros,
Mattias Engdegård <=
- [elpa] externals/relint c215d54 34/44: More careful evaluation of if, when, unless, and, or, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 15c799e 35/44: Evaluate calls to functions defined in the same file., Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 2d1f488 32/44: mapcar on non-list sequence, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint af745bb 30/44: Update the package description. Increment version to 1.4, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint e1b1ef9 22/44: Run in two phases on each file, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 7a1b632 33/44: Add wildcard-to-regexp as 'pure' function, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint f6fb8e6 31/44: Sundry cosmetic fixes, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 151dbb8 23/44: Handle some destructive list functions, Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 187d586 27/44: Scan arguments to `skip-chars-{forward, backward}', Mattias Engdegård, 2019/03/26
- [elpa] externals/relint 5af5466 26/44: Scan string-trim arguments, Mattias Engdegård, 2019/03/26