summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/bytecomp.el
diff options
context:
space:
mode:
authorHelmut Eller <eller.helmut@gmail.com>2023-08-03 08:33:40 +0200
committerMattias Engdegård <mattiase@acm.org>2023-08-08 18:23:00 +0200
commit3e79fd3d4e810c2ef4cf9925a747c93e036fddca (patch)
treea978150f0fbeca9823e3d89d54ea1886558cef65 /lisp/emacs-lisp/bytecomp.el
parentefb3ef0fe07a1fe8c713921ceba74f476c8aa40b (diff)
downloademacs-3e79fd3d4e810c2ef4cf9925a747c93e036fddca.tar.gz
emacs-3e79fd3d4e810c2ef4cf9925a747c93e036fddca.tar.bz2
emacs-3e79fd3d4e810c2ef4cf9925a747c93e036fddca.zip
Check keyword args of make-process
The functions make-process and make-network-process have many keyword args and it's easy to misspell some of them. Use a compiler macro to warn about some possible mistakes. * lisp/emacs-lisp/bytecomp.el (bytecomp--check-keyword-args): New helper. (make-process, make-network-process): Define a compiler macro that performs some checks but doesn't anything else. * test/lisp/emacs-lisp/bytecomp-tests.el: Add some tests. * test/lisp/emacs-lisp/bytecomp-resources/: (warn-make-process-missing-keyword-arg.el, warn-make-process-missing-keyword-value.el, warn-make-process-repeated-keyword-arg.el, warn-make-process-unknown-keyword-arg.el): New test files
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r--lisp/emacs-lisp/bytecomp.el61
1 files changed, 61 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index f6ba6ff9ea0..0df7b0bfe2a 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -5782,6 +5782,67 @@ and corresponding effects."
form ; arity error
`(forward-word (- (or ,arg 1)))))
+(defun bytecomp--check-keyword-args (form arglist allowed-keys required-keys)
+ (let ((fun (car form)))
+ (cl-flet ((missing (form keyword)
+ (byte-compile-warn-x
+ form
+ "`%S´ called without required keyword argument %S"
+ fun keyword))
+ (unrecognized (form keyword)
+ (byte-compile-warn-x
+ form
+ "`%S´ called with unknown keyword argument %S"
+ fun keyword))
+ (duplicate (form keyword)
+ (byte-compile-warn-x
+ form
+ "`%S´ called with repeated keyword argument %S"
+ fun keyword))
+ (missing-val (form keyword)
+ (byte-compile-warn-x
+ form
+ "missing value for keyword argument %S"
+ keyword)))
+ (let* ((seen '())
+ (l arglist))
+ (while (consp l)
+ (let ((key (car l)))
+ (cond ((and (keywordp key) (memq key allowed-keys))
+ (cond ((memq key seen)
+ (duplicate l key))
+ (t
+ (push key seen))))
+ (t (unrecognized l key)))
+ (when (null (cdr l))
+ (missing-val l key)))
+ (setq l (cddr l)))
+ (dolist (key required-keys)
+ (unless (memq key seen)
+ (missing form key))))))
+ form)
+
+(put 'make-process 'compiler-macro
+ #'(lambda (form &rest args)
+ (bytecomp--check-keyword-args
+ form args
+ '(:name
+ :buffer :command :coding :noquery :stop :connection-type
+ :filter :sentinel :stderr :file-handler)
+ '(:name :command))))
+
+(put 'make-network-process 'compiler-macro
+ #'(lambda (form &rest args)
+ (bytecomp--check-keyword-args
+ form args
+ '(:name
+ :buffer :host :service :type :family :local :remote :coding
+ :nowait :noquery :stop :filter :filter-multibyte :sentinel
+ :log :plist :tls-parameters :server :broadcast :dontroute
+ :keepalive :linger :oobinline :priority :reuseaddr :bindtodevice
+ :use-external-socket)
+ '(:name :service))))
+
(provide 'byte-compile)
(provide 'bytecomp)