branch: externals/dash
commit 693153276ec56f0f60fabecfabcd3d181e45c850
Author: Basil L. Contovounesios <ba...@contovou.net>
Commit: Basil L. Contovounesios <ba...@contovou.net>

    Improve compatibility with static-if
    
    * dash.el: Conditionally define Emacs 30 static-if polyfill.  Use it
    for choosing between gv-define-setter and defsetf.  This reduces the
    chances of, e.g., (x) and (val) being expanded as macros (#402).
    (dash--assoc-fn, -andfn, dash-fontify-mode): Move run-time checks to
    compile time.  This simplifies the code a bit and reduces the need
    for heavy-handed warning suppression.
    
    Fixes #402.
---
 dash.el | 62 +++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/dash.el b/dash.el
index ed2a859235..5e1cbc6979 100644
--- a/dash.el
+++ b/dash.el
@@ -30,6 +30,15 @@
 ;;; Code:
 
 (eval-when-compile
+  (unless (fboundp 'static-if)
+    (defmacro static-if (condition then-form &rest else-forms)
+      "Expand to THEN-FORM or ELSE-FORMS based on compile-time CONDITION.
+Polyfill for Emacs 30 `static-if'."
+      (declare (debug (sexp sexp &rest sexp)) (indent 2))
+      (if (eval condition lexical-binding)
+          then-form
+        (cons 'progn else-forms))))
+
   ;; TODO: Emacs 24.3 first introduced `gv', so remove this and all
   ;; calls to `defsetf' when support for earlier versions is dropped.
   (unless (fboundp 'gv-define-setter)
@@ -1036,13 +1045,9 @@ See also: `-first-item', etc."
   (declare (pure t) (side-effect-free t))
   (car (last list)))
 
-;; Use `with-no-warnings' to suppress unbound `-last-item' or
-;; undefined `gv--defsetter' warnings arising from both
-;; `gv-define-setter' and `defsetf' in certain Emacs versions.
-(with-no-warnings
-  (if (fboundp 'gv-define-setter)
-      (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
-    (defsetf -last-item (x) (val) `(setcar (last ,x) ,val))))
+(static-if (fboundp 'gv-define-setter)
+    (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
+  (defsetf -last-item (x) (val) `(setcar (last ,x) ,val)))
 
 (defun -butlast (list)
   "Return a list of all items in list except for the last."
@@ -2901,16 +2906,14 @@ example:
   (let ((cmp -compare-fn))
     (cond ((memq cmp '(nil equal)) #'assoc)
           ((eq cmp #'eq) #'assq)
-          ;; Since Emacs 26, `assoc' accepts a custom `testfn'.
-          ;; Version testing would be simpler here, but feature
-          ;; testing gets more brownie points, I guess.
-          ((condition-case nil
-               (with-no-warnings (assoc nil () #'eql))
-             (wrong-number-of-arguments t))
-           (lambda (key alist)
-             (--first (and (consp it) (funcall cmp (car it) key)) alist)))
-          ((with-no-warnings
-             (lambda (key alist)
+          ((lambda (key alist)
+             ;; Since Emacs 26, `assoc' accepts a custom `testfn'.
+             ;; Version testing would be simpler here, but feature
+             ;; testing gets more brownie points, I guess.
+             (static-if (condition-case nil
+                            (assoc nil () #'eql)
+                          (wrong-number-of-arguments t))
+                 (--first (and (consp it) (funcall cmp (car it) key)) alist)
                (assoc key alist cmp)))))))
 
 (defun dash--hash-test-fn ()
@@ -3801,11 +3804,9 @@ See also: `-orfn' and `-not'."
   ;; Open-code for speed.
   (cond ((cdr preds) (lambda (&rest args) (--every (apply it args) preds)))
         (preds (car preds))
-        ;; As a `pure' function, this runtime check may generate
-        ;; backward-incompatible bytecode for `(-andfn)' at compile-time,
-        ;; but I doubt that's a problem in practice (famous last words).
-        ((fboundp 'always) #'always)
-        ((lambda (&rest _) t))))
+        ((static-if (fboundp 'always)
+             #'always
+           (lambda (&rest _) t)))))
 
 (defun -iteratefn (fn n)
   "Return a function FN composed N times with itself.
@@ -4067,15 +4068,14 @@ See also `dash-fontify-mode-lighter' and
   (if dash-fontify-mode
       (font-lock-add-keywords nil dash--keywords t)
     (font-lock-remove-keywords nil dash--keywords))
-  (cond ((fboundp 'font-lock-flush) ;; Added in Emacs 25.
-         (font-lock-flush))
-        ;; `font-lock-fontify-buffer' unconditionally enables
-        ;; `font-lock-mode' and is marked `interactive-only' in later
-        ;; Emacs versions which have `font-lock-flush', so we guard
-        ;; and pacify as needed, respectively.
-        (font-lock-mode
-         (with-no-warnings
-           (font-lock-fontify-buffer)))))
+  (static-if (fboundp 'font-lock-flush)
+      ;; Added in Emacs 25.
+      (font-lock-flush)
+    (when font-lock-mode
+      ;; Unconditionally enables `font-lock-mode' and is marked
+      ;; `interactive-only' in later Emacs versions which have
+      ;; `font-lock-flush'.
+      (font-lock-fontify-buffer))))
 
 (defun dash--turn-on-fontify-mode ()
   "Enable `dash-fontify-mode' if in an Emacs Lisp buffer."

Reply via email to