summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/bytecomp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r--lisp/emacs-lisp/bytecomp.el854
1 files changed, 493 insertions, 361 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 708e6123606..7ddca19626e 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -468,7 +468,8 @@ Return the compile-time value of FORM."
;; 3.2.3.1, "Processing of Top Level Forms". The semantics are very
;; subtle: see test/lisp/emacs-lisp/bytecomp-tests.el for interesting
;; cases.
- (setf form (macroexp-macroexpand form byte-compile-macro-environment))
+ (let ((print-symbols-bare t))
+ (setf form (macroexp-macroexpand form byte-compile-macro-environment)))
(if (eq (car-safe form) 'progn)
(cons 'progn
(mapcar (lambda (subform)
@@ -499,8 +500,8 @@ Return the compile-time value of FORM."
byte-compile-new-defuns))
(setf result
(byte-compile-eval
- (byte-compile-top-level
- (byte-compile-preprocess form)))))))
+ (byte-compile-top-level
+ (byte-compile-preprocess form)))))))
(list 'quote result))))
(eval-and-compile . ,(lambda (&rest body)
(byte-compile-recurse-toplevel
@@ -509,10 +510,11 @@ Return the compile-time value of FORM."
;; Don't compile here, since we don't know
;; whether to compile as byte-compile-form
;; or byte-compile-file-form.
- (let ((expanded
- (macroexpand--all-toplevel
- form
- macroexpand-all-environment)))
+ (let* ((print-symbols-bare t)
+ (expanded
+ (macroexpand--all-toplevel
+ form
+ macroexpand-all-environment)))
(eval expanded lexical-binding)
expanded)))))
(with-suppressed-warnings
@@ -1213,6 +1215,41 @@ message buffer `default-directory'."
(f2 (file-relative-name file dir)))
(if (< (length f2) (length f1)) f2 f1)))
+(defun byte-compile--first-symbol (form)
+ "Return the \"first\" symbol found in form, or 0 if there is none.
+Here, \"first\" is by a depth first search."
+ (let (sym)
+ (cond
+ ((symbolp form) form)
+ ((consp form)
+ (or (and (symbolp (setq sym (byte-compile--first-symbol (car form))))
+ sym)
+ (and (symbolp (setq sym (byte-compile--first-symbol (cdr form))))
+ sym)
+ 0))
+ ((and (vectorp form)
+ (> (length form) 0))
+ (let ((i 0)
+ (len (length form))
+ elt)
+ (catch 'sym
+ (while (< i len)
+ (when (symbolp
+ (setq elt (byte-compile--first-symbol (aref form i))))
+ (throw 'sym elt))
+ (setq i (1+ i)))
+ 0)))
+ (t 0))))
+
+(defun byte-compile--warning-source-offset ()
+ "Return a source offset from `byte-compile-form-stack'.
+Return nil if such is not found."
+ (catch 'offset
+ (dolist (form byte-compile-form-stack)
+ (let ((s (byte-compile--first-symbol form)))
+ (if (symbol-with-pos-p s)
+ (throw 'offset (symbol-with-pos-pos s)))))))
+
;; This is used as warning-prefix for the compiler.
;; It is always called with the warnings buffer current.
(defun byte-compile-warning-prefix (level entry)
@@ -1230,16 +1267,36 @@ message buffer `default-directory'."
(format "%s:" (byte-compile-abbreviate-file
load-file-name dir)))
(t "")))
+ (offset (byte-compile--warning-source-offset))
(pos (if (and byte-compile-current-file
- (integerp byte-compile-read-position))
+ (integerp byte-compile-read-position)
+ (or offset (not symbols-with-pos-enabled)))
(with-current-buffer byte-compile-current-buffer
- (format "%d:%d:"
- (save-excursion
- (goto-char byte-compile-last-position)
- (1+ (count-lines (point-min) (point-at-bol))))
- (save-excursion
- (goto-char byte-compile-last-position)
- (1+ (current-column)))))
+ ;; (format "%d:%d:"
+ ;; (save-excursion
+ ;; (goto-char (if symbols-with-pos-enabled
+ ;; (+ byte-compile-read-position offset)
+ ;; byte-compile-last-position)
+ ;; )
+ ;; (1+ (count-lines (point-min) (point-at-bol))))
+ ;; (save-excursion
+ ;; (goto-char (if symbols-with-pos-enabled
+ ;; (+ byte-compile-read-position offset)
+ ;; byte-compile-last-position)
+ ;; )
+ ;; (1+ (current-column))))
+;;;; EXPERIMENTAL STOUGH, 2018-11-22
+ (let (old-l old-c new-l new-c)
+ (save-excursion
+ (goto-char byte-compile-last-position)
+ (setq old-l (1+ (count-lines (point-min) (point-at-bol)))
+ old-c (1+ (current-column)))
+ (goto-char offset)
+ (setq new-l (1+ (count-lines (point-min) (point-at-bol)))
+ new-c (1+ (current-column)))
+ (format "%d:%d:%d:%d:" old-l old-c new-l new-c)))
+;;;; END OF EXPERIMENTAL STOUGH
+ )
""))
(form (if (eq byte-compile-current-form :end) "end of data"
(or byte-compile-current-form "toplevel form"))))
@@ -1348,6 +1405,14 @@ function directly; use `byte-compile-warn' or
(error "%s" format) ; byte-compile-file catches and logs it
(byte-compile-log-warning format t :warning)))
+(defun byte-compile-warn-x (arg format &rest args)
+ "Issue a byte compiler warning.
+ARG is the source element (likely a symbol with position) central to
+ the warning, intended to supply source position information.
+FORMAT and ARGS are as in `byte-compile-warn'."
+ (let ((byte-compile-form-stack (cons arg byte-compile-form-stack)))
+ (apply #'byte-compile-warn format args)))
+
(defun byte-compile-warn-obsolete (symbol)
"Warn that SYMBOL (a variable or function) is obsolete."
(when (byte-compile-warning-enabled-p 'obsolete symbol)
@@ -1357,7 +1422,7 @@ function directly; use `byte-compile-warn' or
(or funcp (get symbol 'byte-obsolete-variable))
(if funcp "function" "variable"))))
(unless (and funcp (memq symbol byte-compile-not-obsolete-funcs))
- (byte-compile-warn "%s" msg)))))
+ (byte-compile-warn-x symbol "%s" msg)))))
(defun byte-compile-report-error (error-info &optional fill)
"Report Lisp error in compilation.
@@ -1482,7 +1547,8 @@ when printing the error message."
(defun byte-compile-emit-callargs-warn (name actual-args min-args max-args)
(byte-compile-set-symbol-position name)
- (byte-compile-warn
+ (byte-compile-warn-x
+ name
"%s called with %d argument%s, but %s %s"
name actual-args
(if (= 1 actual-args) "" "s")
@@ -1548,7 +1614,7 @@ extra args."
n)))
(nargs (- (length form) 2)))
(unless (= nargs nfields)
- (byte-compile-warn
+ (byte-compile-warn-x (car form)
"`%s' called with %d args to fill %d format field(s)" (car form)
nargs nfields)))))
@@ -1562,7 +1628,7 @@ extra args."
(when (eq (car-safe name) 'quote)
(or (not (eq (car form) 'custom-declare-variable))
(plist-get keyword-args :type)
- (byte-compile-warn
+ (byte-compile-warn-x (cadr name)
"defcustom for `%s' fails to specify type" (cadr name)))
(if (and (memq (car form) '(custom-declare-face custom-declare-variable))
byte-compile-current-group)
@@ -1571,7 +1637,7 @@ extra args."
(or (and (eq (car form) 'custom-declare-group)
(equal name ''emacs))
(plist-get keyword-args :group)
- (byte-compile-warn
+ (byte-compile-warn-x (cadr name)
"%s for `%s' fails to specify containing group"
(cdr (assq (car form)
'((custom-declare-group . defgroup)
@@ -1590,7 +1656,7 @@ extra args."
(let ((calls (assq name byte-compile-unresolved-functions))
nums sig min max)
(when (and calls macrop)
- (byte-compile-warn "macro `%s' defined too late" name))
+ (byte-compile-warn-x name "macro `%s' defined too late" name))
(setq byte-compile-unresolved-functions
(delq calls byte-compile-unresolved-functions))
(setq calls (delq t calls)) ;Ignore higher-order uses of the function.
@@ -1598,8 +1664,8 @@ extra args."
(when (and (symbolp name)
(eq (function-get name 'byte-optimizer)
'byte-compile-inline-expand))
- (byte-compile-warn "defsubst `%s' was used before it was defined"
- name))
+ (byte-compile-warn-x name "defsubst `%s' was used before it was defined"
+ name))
(setq sig (byte-compile-arglist-signature arglist)
nums (sort (copy-sequence (cddr calls)) (function <))
min (car nums)
@@ -1607,7 +1673,8 @@ extra args."
(when (or (< min (car sig))
(and (cdr sig) (> max (cdr sig))))
(byte-compile-set-symbol-position name)
- (byte-compile-warn
+ (byte-compile-warn-x
+ name
"%s being defined to take %s%s, but was previously called with %s"
name
(byte-compile-arglist-signature-string sig)
@@ -1626,7 +1693,8 @@ extra args."
(sig2 (byte-compile-arglist-signature arglist)))
(unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
(byte-compile-set-symbol-position name)
- (byte-compile-warn
+ (byte-compile-warn-x
+ name
"%s %s used to take %s %s, now takes %s"
(if macrop "macro" "function")
name
@@ -1715,8 +1783,10 @@ It is too wide if it has any lines longer than the largest of
(setq name (if name (format " `%s' " name) ""))
(when (and kind docs (stringp docs)
(byte-compile--wide-docstring-p docs col))
- (byte-compile-warn "%s%sdocstring wider than %s characters"
- kind name col))))
+ (byte-compile-warn-x
+ name
+ "%s%s docstring wider than %s characters"
+ kind name col))))
form)
;; If we have compiled any calls to functions which are not known to be
@@ -1731,7 +1801,8 @@ It is too wide if it has any lines longer than the largest of
(let ((f (car urf)))
(when (not (memq f byte-compile-new-defuns))
(let ((byte-compile-last-position (cadr urf)))
- (byte-compile-warn
+ (byte-compile-warn-x
+ f
(if (fboundp f) "the function `%s' might not be defined at runtime." "the function `%s' is not known to be defined.")
(car urf))))))))
nil)
@@ -1789,7 +1860,8 @@ It is too wide if it has any lines longer than the largest of
(warning-series-started
(and (markerp warning-series)
(eq (marker-buffer warning-series)
- (get-buffer byte-compile-log-buffer)))))
+ (get-buffer byte-compile-log-buffer))))
+ (byte-compile-form-stack byte-compile-form-stack))
(if (or (eq warning-series 'byte-compile-warning-series)
warning-series-started)
;; warning-series does come from compilation,
@@ -2010,174 +2082,176 @@ See also `emacs-lisp-byte-compile-and-load'."
;; Force logging of the file name for each file compiled.
(setq byte-compile-last-logged-file nil)
- (let ((byte-compile-current-file filename)
- (byte-compile-current-group nil)
- (set-auto-coding-for-load t)
- (byte-compile--seen-defvars nil)
- (byte-compile--known-dynamic-vars
- (byte-compile--load-dynvars (getenv "EMACS_DYNVARS_FILE")))
- target-file input-buffer output-buffer
- byte-compile-dest-file byte-compiler-error-flag)
- (setq target-file (byte-compile-dest-file filename))
- (setq byte-compile-dest-file target-file)
- (with-current-buffer
- ;; It would be cleaner to use a temp buffer, but if there was
- ;; an error, we leave this buffer around for diagnostics.
- ;; Its name is documented in the lispref.
- (setq input-buffer (get-buffer-create
- (concat " *Compiler Input*"
- (if (zerop byte-compile-level) ""
- (format "-%s" byte-compile-level)))))
- (erase-buffer)
- (setq buffer-file-coding-system nil)
- ;; Always compile an Emacs Lisp file as multibyte
- ;; unless the file itself forces unibyte with -*-coding: raw-text;-*-
- (set-buffer-multibyte t)
- (insert-file-contents filename)
- ;; Mimic the way after-insert-file-set-coding can make the
- ;; buffer unibyte when visiting this file.
- (when (or (eq last-coding-system-used 'no-conversion)
- (eq (coding-system-type last-coding-system-used) 5))
- ;; For coding systems no-conversion and raw-text...,
- ;; edit the buffer as unibyte.
- (set-buffer-multibyte nil))
- ;; Run hooks including the uncompression hook.
- ;; If they change the file name, then change it for the output also.
- (let ((buffer-file-name filename)
- (dmm (default-value 'major-mode))
- ;; Ignore unsafe local variables.
- ;; We only care about a few of them for our purposes.
- (enable-local-variables :safe)
- (enable-local-eval nil))
- (unwind-protect
- (progn
- (setq-default major-mode 'emacs-lisp-mode)
- ;; Arg of t means don't alter enable-local-variables.
- (delay-mode-hooks (normal-mode t)))
- (setq-default major-mode dmm))
- ;; There may be a file local variable setting (bug#10419).
- (setq buffer-read-only nil
- filename buffer-file-name))
- ;; Don't inherit lexical-binding from caller (bug#12938).
- (unless (local-variable-p 'lexical-binding)
- (setq-local lexical-binding nil))
- ;; Set the default directory, in case an eval-when-compile uses it.
- (setq default-directory (file-name-directory filename)))
- ;; Check if the file's local variables explicitly specify not to
- ;; compile this file.
- (if (with-current-buffer input-buffer no-byte-compile)
- (progn
- ;; (message "%s not compiled because of `no-byte-compile: %s'"
- ;; (byte-compile-abbreviate-file filename)
- ;; (with-current-buffer input-buffer no-byte-compile))
- (when (and target-file (file-exists-p target-file))
- (message "%s deleted because of `no-byte-compile: %s'"
- (byte-compile-abbreviate-file target-file)
- (buffer-local-value 'no-byte-compile input-buffer))
- (condition-case nil (delete-file target-file) (error nil)))
- ;; We successfully didn't compile this file.
- 'no-byte-compile)
- (when byte-compile-verbose
- (message "Compiling %s..." filename))
- ;; It is important that input-buffer not be current at this call,
- ;; so that the value of point set in input-buffer
- ;; within byte-compile-from-buffer lingers in that buffer.
- (setq output-buffer
- (save-current-buffer
- (let ((byte-compile-level (1+ byte-compile-level)))
- (byte-compile-from-buffer input-buffer))))
- (if byte-compiler-error-flag
- nil
- (when byte-compile-verbose
- (message "Compiling %s...done" filename))
- (kill-buffer input-buffer)
- (with-current-buffer output-buffer
- (when (and target-file
- (or (not byte-native-compiling)
- (and byte-native-compiling byte+native-compile)))
- (goto-char (point-max))
- (insert "\n") ; aaah, unix.
- (cond
- ((and (file-writable-p target-file)
- ;; We attempt to create a temporary file in the
- ;; target directory, so the target directory must be
- ;; writable.
- (file-writable-p
- (file-name-directory
- ;; Need to expand in case TARGET-FILE doesn't
- ;; include a directory (Bug#45287).
- (expand-file-name target-file))))
- ;; We must disable any code conversion here.
- (let* ((coding-system-for-write 'no-conversion)
- ;; Write to a tempfile so that if another Emacs
- ;; process is trying to load target-file (eg in a
- ;; parallel bootstrap), it does not risk getting a
- ;; half-finished file. (Bug#4196)
- (tempfile
- (make-temp-file (when (file-writable-p target-file)
- (expand-file-name target-file))))
- (default-modes (default-file-modes))
- (temp-modes (logand default-modes #o600))
- (desired-modes (logand default-modes #o666))
- (kill-emacs-hook
- (cons (lambda () (ignore-errors
- (delete-file tempfile)))
- kill-emacs-hook)))
- (unless (= temp-modes desired-modes)
- (set-file-modes tempfile desired-modes 'nofollow))
- (write-region (point-min) (point-max) tempfile nil 1)
- ;; This has the intentional side effect that any
- ;; hard-links to target-file continue to
- ;; point to the old file (this makes it possible
- ;; for installed files to share disk space with
- ;; the build tree, without causing problems when
- ;; emacs-lisp files in the build tree are
- ;; recompiled). Previously this was accomplished by
- ;; deleting target-file before writing it.
- (if byte-native-compiling
- ;; Defer elc final renaming.
- (setf byte-to-native-output-file
- (cons tempfile target-file))
- (rename-file tempfile target-file t)))
- (or noninteractive
- byte-native-compiling
- (message "Wrote %s" target-file)))
- ((file-writable-p target-file)
- ;; In case the target directory isn't writable (see e.g. Bug#44631),
- ;; try writing to the output file directly. We must disable any
- ;; code conversion here.
- (let ((coding-system-for-write 'no-conversion))
- (with-file-modes (logand (default-file-modes) #o666)
- (write-region (point-min) (point-max) target-file nil 1)))
- (or noninteractive (message "Wrote %s" target-file)))
- (t
- ;; This is just to give a better error message than write-region
- (let ((exists (file-exists-p target-file)))
- (signal (if exists 'file-error 'file-missing)
- (list "Opening output file"
- (if exists
- "Cannot overwrite file"
- "Directory not writable or nonexistent")
- target-file))))))
- (kill-buffer (current-buffer)))
- (if (and byte-compile-generate-call-tree
- (or (eq t byte-compile-generate-call-tree)
- (y-or-n-p (format "Report call tree for %s? "
- filename))))
- (save-excursion
- (display-call-tree filename)))
- (let ((gen-dynvars (getenv "EMACS_GENERATE_DYNVARS")))
- (when (and gen-dynvars (not (equal gen-dynvars ""))
- byte-compile--seen-defvars)
- (let ((dynvar-file (concat target-file ".dynvars")))
- (message "Generating %s" dynvar-file)
- (with-temp-buffer
- (dolist (var (delete-dups byte-compile--seen-defvars))
- (insert (format "%S\n" (cons var filename))))
- (write-region (point-min) (point-max) dynvar-file)))))
- (if load
- (load target-file))
- t))))
+ (prog1
+ (let ((byte-compile-current-file filename)
+ (byte-compile-current-group nil)
+ (set-auto-coding-for-load t)
+ (byte-compile--seen-defvars nil)
+ (byte-compile--known-dynamic-vars
+ (byte-compile--load-dynvars (getenv "EMACS_DYNVARS_FILE")))
+ target-file input-buffer output-buffer
+ byte-compile-dest-file byte-compiler-error-flag)
+ (setq target-file (byte-compile-dest-file filename))
+ (setq byte-compile-dest-file target-file)
+ (with-current-buffer
+ ;; It would be cleaner to use a temp buffer, but if there was
+ ;; an error, we leave this buffer around for diagnostics.
+ ;; Its name is documented in the lispref.
+ (setq input-buffer (get-buffer-create
+ (concat " *Compiler Input*"
+ (if (zerop byte-compile-level) ""
+ (format "-%s" byte-compile-level)))))
+ (erase-buffer)
+ (setq buffer-file-coding-system nil)
+ ;; Always compile an Emacs Lisp file as multibyte
+ ;; unless the file itself forces unibyte with -*-coding: raw-text;-*-
+ (set-buffer-multibyte t)
+ (insert-file-contents filename)
+ ;; Mimic the way after-insert-file-set-coding can make the
+ ;; buffer unibyte when visiting this file.
+ (when (or (eq last-coding-system-used 'no-conversion)
+ (eq (coding-system-type last-coding-system-used) 5))
+ ;; For coding systems no-conversion and raw-text...,
+ ;; edit the buffer as unibyte.
+ (set-buffer-multibyte nil))
+ ;; Run hooks including the uncompression hook.
+ ;; If they change the file name, then change it for the output also.
+ (let ((buffer-file-name filename)
+ (dmm (default-value 'major-mode))
+ ;; Ignore unsafe local variables.
+ ;; We only care about a few of them for our purposes.
+ (enable-local-variables :safe)
+ (enable-local-eval nil))
+ (unwind-protect
+ (progn
+ (setq-default major-mode 'emacs-lisp-mode)
+ ;; Arg of t means don't alter enable-local-variables.
+ (delay-mode-hooks (normal-mode t)))
+ (setq-default major-mode dmm))
+ ;; There may be a file local variable setting (bug#10419).
+ (setq buffer-read-only nil
+ filename buffer-file-name))
+ ;; Don't inherit lexical-binding from caller (bug#12938).
+ (unless (local-variable-p 'lexical-binding)
+ (setq-local lexical-binding nil))
+ ;; Set the default directory, in case an eval-when-compile uses it.
+ (setq default-directory (file-name-directory filename)))
+ ;; Check if the file's local variables explicitly specify not to
+ ;; compile this file.
+ (if (with-current-buffer input-buffer no-byte-compile)
+ (progn
+ ;; (message "%s not compiled because of `no-byte-compile: %s'"
+ ;; (byte-compile-abbreviate-file filename)
+ ;; (with-current-buffer input-buffer no-byte-compile))
+ (when (and target-file (file-exists-p target-file))
+ (message "%s deleted because of `no-byte-compile: %s'"
+ (byte-compile-abbreviate-file target-file)
+ (buffer-local-value 'no-byte-compile input-buffer))
+ (condition-case nil (delete-file target-file) (error nil)))
+ ;; We successfully didn't compile this file.
+ 'no-byte-compile)
+ (when byte-compile-verbose
+ (message "Compiling %s..." filename))
+ ;; It is important that input-buffer not be current at this call,
+ ;; so that the value of point set in input-buffer
+ ;; within byte-compile-from-buffer lingers in that buffer.
+ (setq output-buffer
+ (save-current-buffer
+ (let ((symbols-with-pos-enabled t)
+ (byte-compile-level (1+ byte-compile-level)))
+ (byte-compile-from-buffer input-buffer))))
+ (if byte-compiler-error-flag
+ nil
+ (when byte-compile-verbose
+ (message "Compiling %s...done" filename))
+ (kill-buffer input-buffer)
+ (with-current-buffer output-buffer
+ (when (and target-file
+ (or (not byte-native-compiling)
+ (and byte-native-compiling byte+native-compile)))
+ (goto-char (point-max))
+ (insert "\n") ; aaah, unix.
+ (cond
+ ((and (file-writable-p target-file)
+ ;; We attempt to create a temporary file in the
+ ;; target directory, so the target directory must be
+ ;; writable.
+ (file-writable-p
+ (file-name-directory
+ ;; Need to expand in case TARGET-FILE doesn't
+ ;; include a directory (Bug#45287).
+ (expand-file-name target-file))))
+ ;; We must disable any code conversion here.
+ (let* ((coding-system-for-write 'no-conversion)
+ ;; Write to a tempfile so that if another Emacs
+ ;; process is trying to load target-file (eg in a
+ ;; parallel bootstrap), it does not risk getting a
+ ;; half-finished file. (Bug#4196)
+ (tempfile
+ (make-temp-file (when (file-writable-p target-file)
+ (expand-file-name target-file))))
+ (default-modes (default-file-modes))
+ (temp-modes (logand default-modes #o600))
+ (desired-modes (logand default-modes #o666))
+ (kill-emacs-hook
+ (cons (lambda () (ignore-errors
+ (delete-file tempfile)))
+ kill-emacs-hook)))
+ (unless (= temp-modes desired-modes)
+ (set-file-modes tempfile desired-modes 'nofollow))
+ (write-region (point-min) (point-max) tempfile nil 1)
+ ;; This has the intentional side effect that any
+ ;; hard-links to target-file continue to
+ ;; point to the old file (this makes it possible
+ ;; for installed files to share disk space with
+ ;; the build tree, without causing problems when
+ ;; emacs-lisp files in the build tree are
+ ;; recompiled). Previously this was accomplished by
+ ;; deleting target-file before writing it.
+ (if byte-native-compiling
+ ;; Defer elc final renaming.
+ (setf byte-to-native-output-file
+ (cons tempfile target-file))
+ (rename-file tempfile target-file t)))
+ (or noninteractive
+ byte-native-compiling
+ (message "Wrote %s" target-file)))
+ ((file-writable-p target-file)
+ ;; In case the target directory isn't writable (see e.g. Bug#44631),
+ ;; try writing to the output file directly. We must disable any
+ ;; code conversion here.
+ (let ((coding-system-for-write 'no-conversion))
+ (with-file-modes (logand (default-file-modes) #o666)
+ (write-region (point-min) (point-max) target-file nil 1)))
+ (or noninteractive (message "Wrote %s" target-file)))
+ (t
+ ;; This is just to give a better error message than write-region
+ (let ((exists (file-exists-p target-file)))
+ (signal (if exists 'file-error 'file-missing)
+ (list "Opening output file"
+ (if exists
+ "Cannot overwrite file"
+ "Directory not writable or nonexistent")
+ target-file))))))
+ (kill-buffer (current-buffer)))
+ (if (and byte-compile-generate-call-tree
+ (or (eq t byte-compile-generate-call-tree)
+ (y-or-n-p (format "Report call tree for %s? "
+ filename))))
+ (save-excursion
+ (display-call-tree filename)))
+ (let ((gen-dynvars (getenv "EMACS_GENERATE_DYNVARS")))
+ (when (and gen-dynvars (not (equal gen-dynvars ""))
+ byte-compile--seen-defvars)
+ (let ((dynvar-file (concat target-file ".dynvars")))
+ (message "Generating %s" dynvar-file)
+ (with-temp-buffer
+ (dolist (var (delete-dups byte-compile--seen-defvars))
+ (insert (format "%S\n" (cons var filename))))
+ (write-region (point-min) (point-max) dynvar-file)))))
+ (if load
+ (load target-file))
+ t)))))
;;; compiling a single function
;;;###autoload
@@ -2189,18 +2263,20 @@ With argument ARG, insert value in current buffer after the form."
(save-excursion
(end-of-defun)
(beginning-of-defun)
- (let* ((byte-compile-current-file (current-buffer))
+ (let* ((print-symbols-bare t)
+ (byte-compile-current-file (current-buffer))
(byte-compile-current-buffer (current-buffer))
(byte-compile-read-position (point))
(byte-compile-last-position byte-compile-read-position)
(byte-compile-last-warned-form 'nothing)
(value (eval
(let ((read-with-symbol-positions (current-buffer))
- (read-symbol-positions-list nil))
+ (read-symbol-positions-list nil)
+ (symbols-with-pos-enabled t))
(displaying-byte-compile-warnings
(byte-compile-sexp
(eval-sexp-add-defvars
- (read (current-buffer))
+ (read-positioning-symbols (current-buffer))
byte-compile-read-position))))
lexical-binding)))
(cond (arg
@@ -2235,7 +2311,7 @@ With argument ARG, insert value in current buffer after the form."
(read-symbol-positions-list nil)
;; #### This is bound in b-c-close-variables.
;; (byte-compile-warnings byte-compile-warnings)
- )
+ (symbols-with-pos-enabled t))
(byte-compile-close-variables
(with-current-buffer
(setq byte-compile--outbuffer
@@ -2284,9 +2360,9 @@ With argument ARG, insert value in current buffer after the form."
(setq byte-compile-read-position (point)
byte-compile-last-position byte-compile-read-position)
(let* ((lread--unescaped-character-literals nil)
- (form (read inbuffer))
+ (form (read-positioning-symbols inbuffer))
(warning (byte-run--unescaped-character-literals-warning)))
- (when warning (byte-compile-warn "%s" warning))
+ (when warning (byte-compile-warn-x form "%s" warning))
(byte-compile-toplevel-file-form form)))
;; Compile pending forms at end of file.
(byte-compile-flush-pending)
@@ -2350,7 +2426,8 @@ Call from the source buffer."
;; Spill output for the native compiler here
(push (make-byte-to-native-top-level :form form :lexical lexical-binding)
byte-to-native-top-level-forms))
- (let ((print-escape-newlines t)
+ (let ((print-symbols-bare t)
+ (print-escape-newlines t)
(print-length nil)
(print-level nil)
(print-quoted t)
@@ -2385,8 +2462,8 @@ list that represents a doc string reference.
;; in the input buffer (now current), not in the output buffer.
(let ((dynamic-docstrings byte-compile-dynamic-docstrings))
(with-current-buffer byte-compile--outbuffer
- (let (position)
-
+ (let (position
+ (print-symbols-bare t))
;; Insert the doc string, and make it a comment with #@LENGTH.
(and (>= (nth 1 info) 0)
dynamic-docstrings
@@ -2496,7 +2573,8 @@ list that represents a doc string reference.
byte-compile-jump-tables nil))))
(defun byte-compile-preprocess (form &optional _for-effect)
- (setq form (macroexpand-all form byte-compile-macro-environment))
+ (let ((print-symbols-bare t))
+ (setq form (macroexpand-all form byte-compile-macro-environment)))
;; FIXME: We should run byte-optimize-form here, but it currently does not
;; recurse through all the code, so we'd have to fix this first.
;; Maybe a good fix would be to merge byte-optimize-form into
@@ -2509,11 +2587,16 @@ list that represents a doc string reference.
;; byte-hunk-handlers cannot call this!
(defun byte-compile-toplevel-file-form (top-level-form)
- (byte-compile-recurse-toplevel
- top-level-form
- (lambda (form)
- (let ((byte-compile-current-form nil)) ; close over this for warnings.
- (byte-compile-file-form (byte-compile-preprocess form t))))))
+ ;; (let ((byte-compile-form-stack
+ ;; (cons top-level-form byte-compile-form-stack)))
+ (push top-level-form byte-compile-form-stack)
+ (prog1
+ (byte-compile-recurse-toplevel
+ top-level-form
+ (lambda (form)
+ (let ((byte-compile-current-form nil)) ; close over this for warnings.
+ (byte-compile-file-form (byte-compile-preprocess form t)))))
+ (pop byte-compile-form-stack)))
;; byte-hunk-handlers can call this.
(defun byte-compile-file-form (form)
@@ -2562,7 +2645,8 @@ list that represents a doc string reference.
(delq (assq funsym byte-compile-unresolved-functions)
byte-compile-unresolved-functions)))))
(if (stringp (nth 3 form))
- (prog1 form
+ (prog1
+ form
(byte-compile-docstring-length-warn form))
;; No doc string, so we can compile this as a normal form.
(byte-compile-keep-pending form 'byte-compile-normal-call)))
@@ -2574,7 +2658,8 @@ list that represents a doc string reference.
(when (and (symbolp sym)
(not (string-match "[-*/:$]" (symbol-name sym)))
(byte-compile-warning-enabled-p 'lexical sym))
- (byte-compile-warn "global/dynamic var `%s' lacks a prefix" sym)))
+ (byte-compile-warn-x
+ sym "global/dynamic var `%s' lacks a prefix" sym)))
(defun byte-compile--declare-var (sym)
(byte-compile--check-prefixed-var sym)
@@ -2582,7 +2667,7 @@ list that represents a doc string reference.
(setq byte-compile-lexical-variables
(delq sym byte-compile-lexical-variables))
(when (byte-compile-warning-enabled-p 'lexical sym)
- (byte-compile-warn "Variable `%S' declared after its first use" sym)))
+ (byte-compile-warn-x sym "Variable `%S' declared after its first use" sym)))
(push sym byte-compile-bound-variables)
(push sym byte-compile--seen-defvars))
@@ -2595,10 +2680,16 @@ list that represents a doc string reference.
(eq (car form) 'defvar)) ;Just a declaration.
nil
(byte-compile-docstring-length-warn form)
+ (setq form (copy-sequence form))
(cond ((consp (nth 2 form))
- (setq form (copy-sequence form))
(setcar (cdr (cdr form))
- (byte-compile-top-level (nth 2 form) nil 'file))))
+ (byte-compile-top-level (nth 2 form) nil 'file)))
+ ((symbolp (nth 2 form))
+ (setcar (cddr form) (bare-symbol (nth 2 form))))
+ (t (setcar (cddr form) (nth 2 form))))
+ (setcar form (bare-symbol (car form)))
+ (if (symbolp (nth 1 form))
+ (setcar (cdr form) (bare-symbol (nth 1 form))))
form))
(put 'define-abbrev-table 'byte-hunk-handler
@@ -2616,7 +2707,8 @@ list that represents a doc string reference.
(`(defvaralias ,_ ',newname . ,_)
(when (memq newname byte-compile-bound-variables)
(if (byte-compile-warning-enabled-p 'suspicious)
- (byte-compile-warn
+ (byte-compile-warn-x
+ newname
"Alias for `%S' should be declared before its referent" newname)))))
(byte-compile-docstring-length-warn form)
(byte-compile-keep-pending form))
@@ -2675,7 +2767,8 @@ list that represents a doc string reference.
(put 'make-obsolete 'byte-hunk-handler 'byte-compile-file-form-make-obsolete)
(defun byte-compile-file-form-make-obsolete (form)
(prog1 (byte-compile-keep-pending form)
- (apply 'make-obsolete (mapcar 'eval (cdr form)))))
+ (apply 'make-obsolete
+ (mapcar 'eval (cdr form)))))
(defun byte-compile-file-form-defmumble (name macro arglist body rest)
"Process a `defalias' for NAME.
@@ -2690,23 +2783,24 @@ not to take responsibility for the actual compilation of the code."
'byte-compile-macro-environment))
(this-one (assq name (symbol-value this-kind)))
(that-one (assq name (symbol-value that-kind)))
+ (bare-name (bare-symbol name))
(byte-compile-current-form name)) ; For warnings.
(byte-compile-set-symbol-position name)
- (push name byte-compile-new-defuns)
+ (push bare-name byte-compile-new-defuns)
;; When a function or macro is defined, add it to the call tree so that
;; we can tell when functions are not used.
(if byte-compile-generate-call-tree
- (or (assq name byte-compile-call-tree)
+ (or (assq bare-name byte-compile-call-tree)
(setq byte-compile-call-tree
- (cons (list name nil nil) byte-compile-call-tree))))
+ (cons (list bare-name nil nil) byte-compile-call-tree))))
(if (byte-compile-warning-enabled-p 'redefine name)
(byte-compile-arglist-warn name arglist macro))
(if byte-compile-verbose
(message "Compiling %s... (%s)"
- (or byte-compile-current-file "") name))
+ (or byte-compile-current-file "") bare-name))
(cond ((not (or macro (listp body)))
;; We do not know positively if the definition is a macro
;; or a function, so we shouldn't emit warnings.
@@ -2715,29 +2809,34 @@ not to take responsibility for the actual compilation of the code."
(that-one
(if (and (byte-compile-warning-enabled-p 'redefine name)
;; Don't warn when compiling the stubs in byte-run...
- (not (assq name byte-compile-initial-macro-environment)))
- (byte-compile-warn
+ (not (assq bare-name byte-compile-initial-macro-environment)))
+ (byte-compile-warn-x
+ name
"`%s' defined multiple times, as both function and macro"
- name))
+ bare-name))
(setcdr that-one nil))
(this-one
(when (and (byte-compile-warning-enabled-p 'redefine name)
;; Hack: Don't warn when compiling the magic internal
;; byte-compiler macros in byte-run.el...
- (not (assq name byte-compile-initial-macro-environment)))
- (byte-compile-warn "%s `%s' defined multiple times in this file"
- (if macro "macro" "function")
- name)))
- ((eq (car-safe (symbol-function name))
+ (not (assq bare-name byte-compile-initial-macro-environment)))
+ (byte-compile-warn-x
+ name
+ "%s `%s' defined multiple times in this file"
+ (if macro "macro" "function")
+ bare-name)))
+ ((eq (car-safe (symbol-function bare-name))
(if macro 'lambda 'macro))
- (when (byte-compile-warning-enabled-p 'redefine name)
- (byte-compile-warn "%s `%s' being redefined as a %s"
- (if macro "function" "macro")
- name
- (if macro "macro" "function")))
+ (when (byte-compile-warning-enabled-p 'redefine bare-name)
+ (byte-compile-warn-x
+ name
+ "%s `%s' being redefined as a %s"
+ (if macro "function" "macro")
+ bare-name
+ (if macro "macro" "function")))
;; Shadow existing definition.
(set this-kind
- (cons (cons name nil)
+ (cons (cons bare-name nil)
(symbol-value this-kind))))
)
@@ -2748,8 +2847,8 @@ not to take responsibility for the actual compilation of the code."
(stringp (car-safe (cdr-safe (cdr-safe body)))))
;; FIXME: We've done that already just above, so this looks wrong!
;;(byte-compile-set-symbol-position name)
- (byte-compile-warn "probable `\"' without `\\' in doc string of %s"
- name))
+ (byte-compile-warn-x
+ name "probable `\"' without `\\' in doc string of %s" bare-name))
(if (not (listp body))
;; The precise definition requires evaluation to find out, so it
@@ -2757,7 +2856,7 @@ not to take responsibility for the actual compilation of the code."
;; For a macro, that means we can't use that macro in the same file.
(progn
(unless macro
- (push (cons name (if (listp arglist) `(declared ,arglist) t))
+ (push (cons bare-name (if (listp arglist) `(declared ,arglist) t))
byte-compile-function-environment))
;; Tell the caller that we didn't compile it yet.
nil)
@@ -2767,10 +2866,10 @@ not to take responsibility for the actual compilation of the code."
;; A definition in b-c-initial-m-e should always take precedence
;; during compilation, so don't let it be redefined. (Bug#8647)
(or (and macro
- (assq name byte-compile-initial-macro-environment))
+ (assq bare-name byte-compile-initial-macro-environment))
(setcdr this-one code))
(set this-kind
- (cons (cons name code)
+ (cons (cons bare-name code)
(symbol-value this-kind))))
(if rest
@@ -2786,18 +2885,19 @@ not to take responsibility for the actual compilation of the code."
(if (not (stringp (documentation code t))) -1 4)))
(when byte-native-compiling
;; Spill output for the native compiler here.
- (push (if macro
- (make-byte-to-native-top-level
- :form `(defalias ',name '(macro . ,code) nil)
- :lexical lexical-binding)
- (make-byte-to-native-func-def :name name
- :byte-func code))
- byte-to-native-top-level-forms))
+ (push
+ (if macro
+ (make-byte-to-native-top-level
+ :form `(defalias ',name '(macro . ,code) nil)
+ :lexical lexical-binding)
+ (make-byte-to-native-func-def :name name
+ :byte-func code))
+ byte-to-native-top-level-forms))
;; Output the form by hand, that's much simpler than having
;; b-c-output-file-form analyze the defalias.
(byte-compile-output-docform
"\n(defalias '"
- name
+ bare-name
(if macro `(" '(macro . #[" ,index "])") `(" #[" ,index "]"))
(append code nil) ; Turn byte-code-function-p into list.
(and (atom code) byte-compile-dynamic
@@ -2880,37 +2980,38 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(macro (eq (car-safe fun) 'macro)))
(if macro
(setq fun (cdr fun)))
- (cond
- ;; Up until Emacs-24.1, byte-compile silently did nothing when asked to
- ;; compile something invalid. So let's tune down the complaint from an
- ;; error to a simple message for the known case where signaling an error
- ;; causes problems.
- ((byte-code-function-p fun)
- (message "Function %s is already compiled"
- (if (symbolp form) form "provided"))
- fun)
- (t
- (let (final-eval)
- (when (or (symbolp form) (eq (car-safe fun) 'closure))
- ;; `fun' is a function *value*, so try to recover its corresponding
- ;; source code.
- (setq lexical-binding (eq (car fun) 'closure))
- (setq fun (byte-compile--reify-function fun))
- (setq final-eval t))
- ;; Expand macros.
- (setq fun (byte-compile-preprocess fun))
- (setq fun (byte-compile-top-level fun nil 'eval))
- (if (symbolp form)
- ;; byte-compile-top-level returns an *expression* equivalent to the
- ;; `fun' expression, so we need to evaluate it, tho normally
- ;; this is not needed because the expression is just a constant
- ;; byte-code object, which is self-evaluating.
- (setq fun (eval fun t)))
- (if final-eval
- (setq fun (eval fun t)))
- (if macro (push 'macro fun))
- (if (symbolp form) (fset form fun))
- fun)))))))
+ (prog1
+ (cond
+ ;; Up until Emacs-24.1, byte-compile silently did nothing when asked to
+ ;; compile something invalid. So let's tune down the complaint from an
+ ;; error to a simple message for the known case where signaling an error
+ ;; causes problems.
+ ((byte-code-function-p fun)
+ (message "Function %s is already compiled"
+ (if (symbolp form) form "provided"))
+ fun)
+ (t
+ (let (final-eval)
+ (when (or (symbolp form) (eq (car-safe fun) 'closure))
+ ;; `fun' is a function *value*, so try to recover its corresponding
+ ;; source code.
+ (setq lexical-binding (eq (car fun) 'closure))
+ (setq fun (byte-compile--reify-function fun))
+ (setq final-eval t))
+ ;; Expand macros.
+ (setq fun (byte-compile-preprocess fun))
+ (setq fun (byte-compile-top-level fun nil 'eval))
+ (if (symbolp form)
+ ;; byte-compile-top-level returns an *expression* equivalent to the
+ ;; `fun' expression, so we need to evaluate it, tho normally
+ ;; this is not needed because the expression is just a constant
+ ;; byte-code object, which is self-evaluating.
+ (setq fun (eval fun t)))
+ (if final-eval
+ (setq fun (eval fun t)))
+ (if macro (push 'macro fun))
+ (if (symbolp form) (fset form fun))
+ fun))))))))
(defun byte-compile-sexp (sexp)
"Compile and return SEXP."
@@ -2941,7 +3042,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
((and (memq arg vars)
;; Allow repetitions for unused args.
(not (string-match "\\`_" (symbol-name arg))))
- (byte-compile-warn "repeated variable %s in lambda-list" arg))
+ (byte-compile-warn-x
+ arg "repeated variable %s in lambda-list" arg))
(t
(push arg vars))))
(setq list (cdr list)))))
@@ -2984,7 +3086,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(defun byte-compile--warn-lexical-dynamic (var context)
(when (byte-compile-warning-enabled-p 'lexical-dynamic var)
- (byte-compile-warn
+ (byte-compile-warn-x
+ var
"`%s' lexically bound in %s here but declared dynamic in: %s"
var context
(mapconcat #'identity
@@ -3036,8 +3139,8 @@ for symbols generated by the byte compiler itself."
;; Check that the bit after the `interactive' spec is
;; just a list of symbols (i.e., modes).
(unless (seq-every-p #'symbolp (cdr (cdr int)))
- (byte-compile-warn "malformed interactive specc: %s"
- (prin1-to-string int)))
+ (byte-compile-warn-x int "malformed interactive specc: %s"
+ int))
(setq command-modes (cdr (cdr int)))
;; If the interactive spec is a call to `list', don't
;; compile it, because `call-interactively' looks at the
@@ -3049,16 +3152,16 @@ for symbols generated by the byte compiler itself."
(while (consp (cdr form))
(setq form (cdr form)))
(setq form (car form)))
- (when (or (not (eq (car-safe form) 'list))
- ;; For code using lexical-binding, form is not
- ;; valid lisp, but rather an intermediate form
- ;; which may include "calls" to
- ;; internal-make-closure (Bug#29988).
- lexical-binding)
- (setq int `(interactive ,newform)))))
+ (if (or (not (eq (car-safe form) 'list))
+ ;; For code using lexical-binding, form is not
+ ;; valid lisp, but rather an intermediate form
+ ;; which may include "calls" to
+ ;; internal-make-closure (Bug#29988).
+ lexical-binding)
+ (setq int `(interactive ,newform)))))
((cdr int) ; Invalid (interactive . something).
- (byte-compile-warn "malformed interactive spec: %s"
- (prin1-to-string int)))))
+ (byte-compile-warn-x int "malformed interactive spec: %s"
+ int))))
;; Process the body.
(let ((compiled
(byte-compile-top-level (cons 'progn body) nil 'lambda
@@ -3069,14 +3172,15 @@ for symbols generated by the byte compiler itself."
(and lexical-binding
(byte-compile-make-lambda-lexenv
arglistvars))
- reserved-csts)))
+ reserved-csts))
+ (bare-arglist arglist))
;; Build the actual byte-coded function.
(cl-assert (eq 'byte-code (car-safe compiled)))
(let ((out
(apply #'make-byte-code
(if lexical-binding
(byte-compile-make-args-desc arglist)
- arglist)
+ bare-arglist)
(append
;; byte-string, constants-vector, stack depth
(cdr compiled)
@@ -3084,7 +3188,7 @@ for symbols generated by the byte compiler itself."
(cond ((and lexical-binding arglist)
;; byte-compile-make-args-desc lost the args's names,
;; so preserve them in the docstring.
- (list (help-add-fundoc-usage doc arglist)))
+ (list (help-add-fundoc-usage doc bare-arglist)))
((or doc int)
(list doc)))
;; optionally, the interactive spec (and the modes the
@@ -3289,7 +3393,8 @@ for symbols generated by the byte compiler itself."
(setq byte-compile-noruntime-functions
(delq fn byte-compile-noruntime-functions))
;; Delegate the rest to the normal macro definition.
- (macroexpand `(declare-function ,fn ,file ,@args)))
+ (let ((print-symbols-bare t))
+ (macroexpand `(declare-function ,fn ,file ,@args))))
;; This is the recursive entry point for compiling each subform of an
@@ -3307,18 +3412,20 @@ for symbols generated by the byte compiler itself."
;;
(defun byte-compile-form (form &optional for-effect)
(let ((byte-compile--for-effect for-effect))
+ (push form byte-compile-form-stack)
(cond
((not (consp form))
(cond ((or (not (symbolp form)) (macroexp--const-symbol-p form))
(when (symbolp form)
(byte-compile-set-symbol-position form))
- (byte-compile-constant form))
+ (byte-compile-constant
+ (if (symbolp form) (bare-symbol form) form)))
((and byte-compile--for-effect byte-compile-delete-errors)
(when (symbolp form)
(byte-compile-set-symbol-position form))
(setq byte-compile--for-effect nil))
(t
- (byte-compile-variable-ref form))))
+ (byte-compile-variable-ref (bare-symbol form)))))
((symbolp (car form))
(let* ((fn (car form))
(handler (get fn 'byte-compile))
@@ -3341,20 +3448,20 @@ for symbols generated by the byte compiler itself."
(byte-compile-check-variable (cadr hook) nil))))
(when (and (byte-compile-warning-enabled-p 'suspicious)
(macroexp--const-symbol-p fn))
- (byte-compile-warn "`%s' called as a function" 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 "`%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 "."))))
+ (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 "."))))
(if (eq (car-safe (symbol-function (car form))) 'macro)
(byte-compile-report-error
(format "`%s' defined after use in %S (missing `require' of a library file?)"
@@ -3379,7 +3486,8 @@ for symbols generated by the byte compiler itself."
(setq byte-compile--for-effect nil))
((byte-compile-normal-call form)))
(if byte-compile--for-effect
- (byte-compile-discard))))
+ (byte-compile-discard))
+ (pop byte-compile-form-stack)))
(defun byte-compile-normal-call (form)
(when (and (symbolp (car form))
@@ -3394,7 +3502,8 @@ for symbols generated by the byte compiler itself."
(when (and byte-compile--for-effect (eq (car form) 'mapcar)
(byte-compile-warning-enabled-p 'mapcar 'mapcar))
(byte-compile-set-symbol-position 'mapcar)
- (byte-compile-warn
+ (byte-compile-warn-x
+ (car form)
"`mapcar' called for effect; use `mapc' or `dolist' instead"))
(byte-compile-push-constant (car form))
(mapc 'byte-compile-form (cdr form)) ; wasteful, but faster.
@@ -3530,11 +3639,13 @@ for symbols generated by the byte compiler itself."
(cond ((or (not (symbolp var)) (macroexp--const-symbol-p var))
(when (byte-compile-warning-enabled-p 'constants
(and (symbolp var) var))
- (byte-compile-warn (if (eq access-type 'let-bind)
- "attempt to let-bind %s `%s'"
- "variable reference to %s `%s'")
- (if (symbolp var) "constant" "nonvariable")
- (prin1-to-string var))))
+ (byte-compile-warn-x
+ var
+ (if (eq access-type 'let-bind)
+ "attempt to let-bind %s `%s'"
+ "variable reference to %s `%s'")
+ (if (symbolp var) "constant" "nonvariable")
+ var)))
((let ((od (get var 'byte-obsolete-variable)))
(and od
(not (memq var byte-compile-not-obsolete-vars))
@@ -3547,6 +3658,7 @@ for symbols generated by the byte compiler itself."
(byte-compile-warn-obsolete var))))
(defsubst byte-compile-dynamic-variable-op (base-op var)
+ (if (symbolp var) (setq var (bare-symbol var)))
(let ((tmp (assq var byte-compile-variables)))
(unless tmp
(setq tmp (list var))
@@ -3559,9 +3671,10 @@ for symbols generated by the byte compiler itself."
(push var byte-compile-bound-variables)
(byte-compile-dynamic-variable-op 'byte-varbind var))
-(defun byte-compile-free-vars-warn (var &optional assignment)
+(defun byte-compile-free-vars-warn (arg var &optional assignment)
"Warn if symbol VAR refers to a free variable.
VAR must not be lexically bound.
+ARG is a position argument, used by byte-compile-warn-x.
If optional argument ASSIGNMENT is non-nil, this is treated as an
assignment (i.e. `setq')."
(unless (or (not (byte-compile-warning-enabled-p 'free-vars var))
@@ -3573,9 +3686,9 @@ assignment (i.e. `setq')."
(let* ((varname (prin1-to-string var))
(desc (if assignment "assignment" "reference"))
(suggestions (help-uni-confusable-suggestions varname)))
- (byte-compile-warn "%s to free variable `%s'%s"
- desc varname
- (if suggestions (concat "\n " suggestions) "")))
+ (byte-compile-warn-x arg "%s to free variable `%s'%s"
+ desc var
+ (if suggestions (concat "\n " suggestions) "")))
(push var (if assignment
byte-compile-free-assignments
byte-compile-free-references))))
@@ -3588,7 +3701,7 @@ assignment (i.e. `setq')."
;; VAR is lexically bound
(byte-compile-stack-ref (cdr lex-binding))
;; VAR is dynamically bound
- (byte-compile-free-vars-warn var)
+ (byte-compile-free-vars-warn var var)
(byte-compile-dynamic-variable-op 'byte-varref var))))
(defun byte-compile-variable-set (var)
@@ -3599,7 +3712,7 @@ assignment (i.e. `setq')."
;; VAR is lexically bound.
(byte-compile-stack-set (cdr lex-binding))
;; VAR is dynamically bound.
- (byte-compile-free-vars-warn var t)
+ (byte-compile-free-vars-warn var var t)
(byte-compile-dynamic-variable-op 'byte-varset var))))
(defmacro byte-compile-get-constant (const)
@@ -3619,14 +3732,18 @@ assignment (i.e. `setq')."
(defun byte-compile-constant (const)
(if byte-compile--for-effect
(setq byte-compile--for-effect nil)
- (inline (byte-compile-push-constant const))))
+ (inline (byte-compile-push-constant
+ (if (symbolp const) (bare-symbol const) const)))))
;; Use this for a constant that is not the value of its containing form.
;; This ignores byte-compile--for-effect.
(defun byte-compile-push-constant (const)
(when (symbolp const)
- (byte-compile-set-symbol-position const))
- (byte-compile-out 'byte-constant (byte-compile-get-constant const)))
+ (byte-compile-set-symbol-position const)
+ (setq const (bare-symbol const)))
+ (byte-compile-out
+ 'byte-constant
+ (byte-compile-get-constant const)))
;; Compile those primitive ordinary functions
;; which have special byte codes just for speed.
@@ -3779,9 +3896,10 @@ If it is nil, then the handler is \"byte-compile-SYMBOL.\""
(defun byte-compile-subr-wrong-args (form n)
(byte-compile-set-symbol-position (car form))
- (byte-compile-warn "`%s' called with %d arg%s, but requires %s"
- (car form) (length (cdr form))
- (if (= 1 (length (cdr form))) "" "s") n)
+ (byte-compile-warn-x (car form)
+ "`%s' called with %d arg%s, but requires %s"
+ (car form) (length (cdr form))
+ (if (= 1 (length (cdr form))) "" "s") n)
;; Get run-time wrong-number-of-args error.
(byte-compile-normal-call form))
@@ -4090,7 +4208,8 @@ discarding."
(if (eq 'interactive (car-safe (car body))) (setq body (cdr body)))
(if (and (consp (car body))
(not (eq 'byte-code (car (car body)))))
- (byte-compile-warn
+ (byte-compile-warn-x
+ (nth 2 form)
"A quoted lambda form is the second argument of `fset'. This is probably
not what you want, as that lambda cannot be compiled. Consider using
the syntax #'(lambda (...) ...) instead.")))))
@@ -4175,10 +4294,11 @@ discarding."
(macroexp--const-symbol-p var t))
(byte-compile-warning-enabled-p 'constants
(and (symbolp var) var))
- (byte-compile-warn
+ (byte-compile-warn-x
+ var
"variable assignment to %s `%s'"
(if (symbolp var) "constant" "nonvariable")
- (prin1-to-string var)))))
+ var))))
(byte-compile-normal-call form)))
(defun byte-compile-quote (form)
@@ -4763,16 +4883,16 @@ binding slots have been popped."
(endtag (byte-compile-make-tag)))
(byte-compile-set-symbol-position 'condition-case)
(unless (symbolp var)
- (byte-compile-warn
- "`%s' is not a variable-name or nil (in condition-case)" var))
+ (byte-compile-warn-x
+ var "`%s' is not a variable-name or nil (in condition-case)" var))
(dolist (clause (reverse clauses))
(let ((condition (nth 1 clause)))
(unless (consp condition) (setq condition (list condition)))
(dolist (c condition)
(unless (and c (symbolp c))
- (byte-compile-warn
- "`%S' is not a condition name (in condition-case)" c))
+ (byte-compile-warn-x
+ c "`%S' is not a condition name (in condition-case)" c))
;; In reality, the `error-conditions' property is only required
;; for the argument to `signal', not to `condition-case'.
;;(unless (consp (get c 'error-conditions))
@@ -4823,7 +4943,8 @@ binding slots have been popped."
(defun byte-compile-save-excursion (form)
(if (and (eq 'set-buffer (car-safe (car-safe (cdr form))))
(byte-compile-warning-enabled-p 'suspicious 'set-buffer))
- (byte-compile-warn
+ (byte-compile-warn-x
+ form
"Use `with-current-buffer' rather than save-excursion+set-buffer"))
(byte-compile-out 'byte-save-excursion 0)
(byte-compile-body-do-effect (cdr form))
@@ -4864,8 +4985,10 @@ binding slots have been popped."
(when (and (symbolp (nth 1 form))
(not (string-match "[-*/:$]" (symbol-name (nth 1 form))))
(byte-compile-warning-enabled-p 'lexical (nth 1 form)))
- (byte-compile-warn "global/dynamic var `%s' lacks a prefix"
- (nth 1 form)))
+ (byte-compile-warn-x
+ (nth 1 form)
+ "global/dynamic var `%s' lacks a prefix"
+ (nth 1 form)))
(byte-compile-docstring-length-warn form)
(let ((fun (nth 0 form))
(var (nth 1 form))
@@ -4875,7 +4998,8 @@ binding slots have been popped."
(when (or (> (length form) 4)
(and (eq fun 'defconst) (null (cddr form))))
(let ((ncall (length (cdr form))))
- (byte-compile-warn
+ (byte-compile-warn-x
+ fun
"`%s' called with %d argument%s, but %s %s"
fun ncall
(if (= 1 ncall) "" "s")
@@ -4885,8 +5009,10 @@ binding slots have been popped."
(if (eq fun 'defconst)
(push var byte-compile-const-variables))
(when (and string (not (stringp string)))
- (byte-compile-warn "third arg to `%s %s' is not a string: %s"
- fun var string))
+ (byte-compile-warn-x
+ string
+ "third arg to `%s %s' is not a string: %s"
+ fun var string))
(byte-compile-form-do-effect
(if (cddr form) ; `value' provided
;; Quote with `quote' to prevent byte-compiling the body,
@@ -4906,7 +5032,8 @@ binding slots have been popped."
(macroexp-const-p (nth 5 form))
(memq (eval (nth 5 form)) '(t macro)) ; macro-p
(not (fboundp (eval (nth 1 form))))
- (byte-compile-warn
+ (byte-compile-warn-x
+ form
"The compiler ignores `autoload' except at top level. You should
probably put the autoload of the macro `%s' at top-level."
(eval (nth 1 form))))
@@ -4995,7 +5122,8 @@ binding slots have been popped."
(defun byte-compile-make-variable-buffer-local (form)
(if (and (eq (car-safe (car-safe (cdr-safe form))) 'quote)
(byte-compile-warning-enabled-p 'make-local))
- (byte-compile-warn
+ (byte-compile-warn-x
+ form
"`make-variable-buffer-local' not called at toplevel"))
(byte-compile-normal-call form))
(put 'make-variable-buffer-local
@@ -5099,24 +5227,26 @@ OP and OPERAND are as passed to `byte-compile-out'."
;;; call tree stuff
(defun byte-compile-annotate-call-tree (form)
- (let (entry)
+ (let ((current-form (byte-run-strip-symbol-positions
+ byte-compile-current-form))
+ (bare-car-form (byte-run-strip-symbol-positions (car form)))
+ entry)
;; annotate the current call
- (if (setq entry (assq (car form) byte-compile-call-tree))
- (or (memq byte-compile-current-form (nth 1 entry)) ;callers
+ (if (setq entry (assq bare-car-form byte-compile-call-tree))
+ (or (memq current-form (nth 1 entry)) ;callers
(setcar (cdr entry)
- (cons byte-compile-current-form (nth 1 entry))))
+ (cons current-form (nth 1 entry))))
(setq byte-compile-call-tree
- (cons (list (car form) (list byte-compile-current-form) nil)
+ (cons (list bare-car-form (list current-form) nil)
byte-compile-call-tree)))
;; annotate the current function
- (if (setq entry (assq byte-compile-current-form byte-compile-call-tree))
- (or (memq (car form) (nth 2 entry)) ;called
+ (if (setq entry (assq current-form byte-compile-call-tree))
+ (or (memq bare-car-form (nth 2 entry)) ;called
(setcar (cdr (cdr entry))
- (cons (car form) (nth 2 entry))))
+ (cons bare-car-form (nth 2 entry))))
(setq byte-compile-call-tree
- (cons (list byte-compile-current-form nil (list (car form)))
- byte-compile-call-tree)))
- ))
+ (cons (list current-form nil (list bare-car-form))
+ byte-compile-call-tree)))))
;; Renamed from byte-compile-report-call-tree
;; to avoid interfering with completion of byte-compile-file.
@@ -5141,14 +5271,15 @@ invoked interactively."
(set-buffer "*Call-Tree*")
(erase-buffer)
(message "Generating call tree... (sorting on %s)"
- byte-compile-call-tree-sort)
+ (remove-pos-from-symbol byte-compile-call-tree-sort))
(insert "Call tree for "
(cond ((null byte-compile-current-file) (or filename "???"))
((stringp byte-compile-current-file)
byte-compile-current-file)
(t (buffer-name byte-compile-current-file)))
" sorted on "
- (prin1-to-string byte-compile-call-tree-sort)
+ (prin1-to-string (remove-pos-from-symbol
+ byte-compile-call-tree-sort))
":\n\n")
(if byte-compile-call-tree-sort
(setq byte-compile-call-tree
@@ -5168,7 +5299,8 @@ invoked interactively."
('name
(lambda (x y) (string< (car x) (car y))))
(_ (error "`byte-compile-call-tree-sort': `%s' - unknown sort mode"
- byte-compile-call-tree-sort))))))
+ (remove-pos-from-symbol
+ byte-compile-call-tree-sort)))))))
(message "Generating call tree...")
(let ((rest byte-compile-call-tree)
(b (current-buffer))
@@ -5315,7 +5447,7 @@ already up-to-date."
(or (not (file-exists-p dest))
(file-newer-than-file-p source dest))))
(if (null (batch-byte-compile-file (car command-line-args-left)))
- (setq error t))))
+ (setq error t))))
(setq command-line-args-left (cdr command-line-args-left)))
(kill-emacs (if error 1 0))))