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

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

[elpa] externals/compat 044acff 58/99: Optionally let compat-func-arity


From: ELPA Syncer
Subject: [elpa] externals/compat 044acff 58/99: Optionally let compat-func-arity handle advice
Date: Sun, 17 Oct 2021 05:57:57 -0400 (EDT)

branch: externals/compat
commit 044acff588345479be01713b3059d4facfac381b
Author: Philip Kaludercic <philipk@posteo.net>
Commit: Philip Kaludercic <philipk@posteo.net>

    Optionally let compat-func-arity handle advice
    
    With an optional argument, currently only used by compat-maxargs-/=,
    compat-func-arity can check the arity of the effective advised
    function, without the oldfun argument.  This is necessary to ensure
    that conditional advice can properly check if the right number of
    arguments are being handled.
---
 compat.el | 43 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/compat.el b/compat.el
index aea3a1b..ed2c118 100644
--- a/compat.el
+++ b/compat.el
@@ -43,17 +43,43 @@
 
 ;;;; Core functionality
 
+(declare-function ad-is-advised "advice" (function))
+(declare-function ad-is-active "advice" (function))
+(declare-function ad-get-advice-info-field "advice" (function field))
+
 ;; The implementation is extracted here so that compatibility advice
 ;; can check if the right number of arguments are being handled.
-(defun compat-func-arity (func)
-  "A reimplementation of `func-arity' for FUNC."
+(defun compat-func-arity (func &optional handle-advice)
+  "A reimplementation of `func-arity' for FUNC.
+If HANDLE-ADVICE is non-nil, return the effective arity of the
+advice."
   (cond
-   ((null func)
+   ((or (null func) (and (symbolp func) (not (fboundp func))) )
     (signal 'void-function func))
+   ((and handle-advice
+         (featurep 'nadvice)
+         (advice--p func))
+    (let* ((adv (advice--car (symbol-function #'alist-get)))
+           (arity (compat-func-arity adv)))
+      (cons (1- (car arity))
+            (if (numberp (cdr arity))
+                (1- (cdr arity))
+              (cdr arity)))))
+   ((and handle-advice
+         (featurep 'advice)
+         ;; See `ad-advice-p'
+         (ad-is-advised func)
+         (ad-is-active func))
+    (let* ((adv (symbol-function
+                 (ad-get-advice-info-field
+                  func 'advicefunname)))
+           (arity (compat-func-arity adv)))
+      (cons (1- (car arity))
+            (if (numberp (cdr arity))
+                (1- (cdr arity))
+              (cdr arity)))))
    ((and (symbolp func) (not (null func)))
-    (compat-func-arity (condition-case nil
-                           (indirect-function func)
-                         (void-function nil))))
+    (compat-func-arity (symbol-function func)))
    ((eq (car-safe func) 'macro)
     (compat-func-arity (cdr func)))
    ((subrp func)
@@ -93,8 +119,9 @@
 
 (defun compat-maxargs-/= (func n)
   "Non-nil when FUNC doesn't accept at most N arguments."
-  (not (eq (cdr (compat-func-arity func)) n)))
-
+  (condition-case nil
+      (not (eq (cdr (compat-func-arity func t)) n))
+    (void-function t)))
 
 ;; Suppress errors triggered by requiring non-existent libraries in
 ;; older versions of Emacs (e.g. subr-x).



reply via email to

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