Function: byte-compile-form
byte-compile-form is a byte-compiled function defined in
bytecomp.el.gz.
Signature
(byte-compile-form FORM &optional FOR-EFFECT)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/bytecomp.el.gz
;; This is the recursive entry point for compiling each subform of an
;; expression.
;; If for-effect is non-nil, byte-compile-form will output a byte-discard
;; before terminating (ie no value will be left on the stack).
;; A byte-compile handler may, when byte-compile--for-effect is non-nil, choose
;; output code which does not leave a value on the stack, and then set
;; byte-compile--for-effect to nil (to prevent byte-compile-form from
;; outputting the byte-discard).
;; If a handler wants to call another handler, it should do so via
;; byte-compile-form, or take extreme care to handle byte-compile--for-effect
;; correctly. (Use byte-compile-form-do-effect to reset the
;; byte-compile--for-effect flag too.)
;;
(defun byte-compile-form (form &optional for-effect)
(let ((byte-compile--for-effect for-effect))
(macroexp--with-extended-form-stack form
(cond
((not (consp form))
(cond ((or (not (symbolp form)) (macroexp--const-symbol-p form))
(byte-compile-constant form))
((and byte-compile--for-effect byte-compile-delete-errors)
(setq byte-compile--for-effect nil))
(t (byte-compile-variable-ref form))))
((symbolp (car form))
(let* ((fn (car form))
(handler (get fn 'byte-compile))
(interactive-only
(or (function-get fn 'interactive-only)
(memq fn byte-compile-interactive-only-functions))))
(when (memq fn '(set symbol-value run-hooks ;; add-to-list
add-hook remove-hook run-hook-with-args
run-hook-with-args-until-success
run-hook-with-args-until-failure))
(pcase (cdr form)
(`(',var . ,_)
(when (and (memq var byte-compile-lexical-variables)
(byte-compile-warning-enabled-p 'lexical var))
(byte-compile-warn
(format-message "%s cannot use lexical var `%s'" fn var))))))
;; Warn about using obsolete hooks.
(if (memq fn '(add-hook remove-hook))
(let ((hook (car-safe (cdr form))))
(if (eq (car-safe hook) 'quote)
(byte-compile-check-variable (cadr hook) nil))))
(when (and (byte-compile-warning-enabled-p 'suspicious)
(macroexp--const-symbol-p fn))
(byte-compile-warn-x fn "`%s' called as a function" fn))
(when (and (byte-compile-warning-enabled-p 'interactive-only fn)
interactive-only)
(byte-compile-warn-x fn "`%s' is for interactive use only%s"
fn
(cond ((stringp interactive-only)
(format "; %s"
(substitute-command-keys
interactive-only)))
((and (symbolp interactive-only)
(not (eq interactive-only t)))
(format-message "; use `%s' instead."
interactive-only))
(t "."))))
(let ((mutargs (function-get (car form) 'mutates-arguments)))
(when mutargs
(dolist (idx (if (symbolp mutargs)
(funcall mutargs form)
mutargs))
(let ((arg (nth idx form)))
(when (and (or (and (eq (car-safe arg) 'quote)
(consp (nth 1 arg)))
(arrayp arg))
(byte-compile-warning-enabled-p
'mutate-constant (car form)))
(byte-compile-warn-x form "`%s' on constant %s (arg %d)"
(car form)
(if (consp arg) "list" (type-of arg))
idx))))))
(let ((funargs (function-get (car form) 'funarg-positions)))
(dolist (funarg funargs)
(let ((arg (if (numberp funarg)
(nth funarg form)
(cadr (memq funarg form)))))
(when (and (eq 'quote (car-safe arg))
(eq 'lambda (car-safe (cadr arg))))
(byte-compile-warn-x
arg "(lambda %s ...) quoted with %s rather than with #%s"
(or (nth 1 (cadr arg)) "()")
"'" "'"))))) ; avoid styled quotes
(if (eq (car-safe (symbol-function (car form))) 'macro)
(byte-compile-report-error
(format-message "`%s' defined after use in %S (missing `require' of a library file?)"
(car form) form)))
(when byte-compile--for-effect
(let ((sef (function-get (car form) 'side-effect-free)))
(cond
((and sef (or (eq sef 'error-free)
byte-compile-delete-errors))
;; This transform is normally done in the Lisp optimizer,
;; so maybe we don't need to bother about it here?
(setq form (cons 'progn (cdr form)))
(setq handler #'byte-compile-progn))
((and (or sef (function-get (car form) 'important-return-value))
;; Don't warn for arguments to `ignore'.
(not (eq byte-compile--for-effect 'for-effect-no-warn))
(bytecomp--actually-important-return-value-p form)
(byte-compile-warning-enabled-p
'ignored-return-value (car form)))
(byte-compile-warn-x
(car form)
"value from call to `%s' is unused%s"
(car form)
(cond ((eq (car form) 'mapcar)
"; use `mapc' or `dolist' instead")
(t "")))))))
(if (and handler
;; Make sure that function exists.
(and (functionp handler)
;; Ignore obsolete byte-compile function used by former
;; CL code to handle compiler macros (we do it
;; differently now).
(not (eq handler 'cl-byte-compile-compiler-macro))))
(funcall handler form)
(byte-compile-normal-call form))))
((and (byte-code-function-p (car form))
(memq byte-optimize '(t lap)))
(byte-compile-unfold-bcf form))
((byte-compile-normal-call form)))
(if byte-compile--for-effect
(byte-compile-discard)))))