nadvice: Fix bug#61179

Advising interactive forms relies on the ability to distinguish
interactive forms that do nothing else than return a function.
So, be careful to preserve this info.
Furthermore, interactive forms are expected to be evaluated in
the lexical context captured by the closure to which they belong,
so be careful to preserve that context when manipulating those forms.

* lisp/emacs-lisp/cconv.el (cconv-convert, cconv-analyze-form) <lambda>:
Preserve the info that an interactive form does nothing else than
return a function.

* lisp/emacs-lisp/nadvice.el (advice--interactive-form-1): New function.
(advice--interactive-form): Use it.
(advice--make-interactive-form): Refine to also accept function values
quoted with `quote`.  Remove obsolete TODO.

* test/lisp/emacs-lisp/nadvice-tests.el: Don't disallow byte-compilation.
(advice-test-bug61179): New test.

* lisp/emacs-lisp/oclosure.el (cconv--interactive-helper): Allow
the `if` arg to be a form.
* lisp/simple.el (oclosure-interactive-form): Adjust accordingly.
This commit is contained in:
Stefan Monnier 2023-02-04 11:23:31 -05:00
parent 229d0772e2
commit c39c26e33f
5 changed files with 46 additions and 14 deletions

View file

@ -213,8 +213,16 @@ function being an around advice."
(should (equal (cl-prin1-to-string (car x))
"#f(advice first :before #f(advice car :after cdr))"))))
;; Local Variables:
;; no-byte-compile: t
;; End:
(ert-deftest advice-test-bug61179 ()
(let* ((magic 42)
(ad (lambda (&rest _)
(interactive (lambda (is)
(cons magic (advice-eval-interactive-spec is))))
nil))
(sym (make-symbol "adtest")))
(defalias sym (lambda (&rest args) (interactive (list 'main)) args))
(should (equal (call-interactively sym) '(main)))
(advice-add sym :before ad)
(should (equal (call-interactively sym) '(42 main)))))
;;; nadvice-tests.el ends here