diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index 3254a4dba81..91926e05794 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -448,6 +448,9 @@ Symbols * Creating Symbols:: How symbols are kept unique. * Symbol Properties:: Each symbol has a property list for recording miscellaneous information. +* Shorthands:: Properly organize your symbol names but + type less of them. +* Symbols with Position:: Symbol variants containing integer positions Symbol Properties diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi index c6b3397ae11..4cc8b89234d 100644 --- a/doc/lispref/streams.texi +++ b/doc/lispref/streams.texi @@ -326,6 +326,16 @@ For example: @end group @end example @end defun +@end defun + +@defun read-positioning-symbols &optional stream +This function reads one textual expression from @var{stream}, like +@code{read} does, but additionally positions the read symbols to the +positions in @var{stream} where they occurred. Only the symbol +@code{nil} is not positioned, this for efficiency reasons. +@xref{Symbols with Position}. This function is used by the byte +compiler. +@end defun @defvar standard-input This variable holds the default input stream---the stream that diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index a951e9be8ae..f3a9e586e36 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -23,15 +23,15 @@ otherwise. @end defun @menu -* Symbol Components:: Symbols have names, values, function definitions +* Symbol Components:: Symbols have names, values, function definitions and property lists. -* Definitions:: A definition says how a symbol will be used. -* Creating Symbols:: How symbols are kept unique. -* Symbol Properties:: Each symbol has a property list +* Definitions:: A definition says how a symbol will be used. +* Creating Symbols:: How symbols are kept unique. +* Symbol Properties:: Each symbol has a property list for recording miscellaneous information. -* Shorthands:: Properly organize your symbol names but +* Shorthands:: Properly organize your symbol names but type less of them. - +* Symbols with Position:: Symbol variants containing integer positions @end menu @node Symbol Components @@ -432,8 +432,8 @@ symbol's property list cell (@pxref{Symbol Components}), in the form of a property list (@pxref{Property Lists}). @menu -* Symbol Plists:: Accessing symbol properties. -* Standard Properties:: Standard meanings of symbol properties. +* Symbol Plists:: Accessing symbol properties. +* Standard Properties:: Standard meanings of symbol properties. @end menu @node Symbol Plists @@ -751,3 +751,69 @@ those names. @item Symbol forms whose names start with @samp{#_} are not transformed. @end itemize + +@node Symbols with Position +@section Symbols with Position +@cindex symbols with position + +A @dfn{symbol with position} is a symbol, the @dfn{bare symbol}, +together with an unsigned integer called the @dfn{position}. These +objects are intended for use by the byte compiler, which records in +them the position of each symbol occurrence and uses those positions +in warning and error messages. + +The printed representation of a symbol with position uses the hash +notation outlined in @ref{Printed Representation}. It looks like +@samp{#}. It has no read syntax. You can cause +just the bare symbol to be printed by binding the variable +@code{print-symbols-bare} to non-@code{nil} around the print +operation. The byte compiler does this before writing its output to +the compiled Lisp file. + +For most purposes, when the flag variable +@code{symbols-with-pos-enabled} is non-@code{nil}, symbols with +positions behave just as bare symbols do. For example, @samp{(eq +# foo)} has a value @code{t} when that variable +is set (but nil when it isn't set). Most of the time in Emacs this +variable is @code{nil}, but the byte compiler binds it to @code{t} +when it runs. + +Typically, symbols with position are created by the byte compiler +calling the reader function @code{read-positioning-symbols} +(@pxref{Input Functions}). One can also be created with the function +@code{position-symbol}. + +@defvar symbols-with-pos-enabled +When this variable is non-@code{nil}, symbols with position behave +like the contained bare symbol. Emacs runs a little more slowly in +this case. +@end defvar + +@defvar print-symbols-bare +When bound to non-nil, the Lisp printer prints only the bare symbol of +a symbol with position, ignoring the position. +@end defvar + +@defun symbol-with-pos-p symbol. +This function returns @code{t} if @var{symbol} is a symbol with +position, @code{nil} otherwise. +@end defun + +@defun bare-symbol symbol +This function returns the bare symbol contained in @var{symbol}, or +@var{symbol} itself if it is already a bare symbol. For any other +type of object, it throws an error. +@end defun + +@defun symbol-with-pos-pos symbol +This function returns the position, a number, from a symbol with +position. For any other type of object, it throws an error. +@end defun + +@defun position-symbol sym pos +Make a new symbol with position. @var{sym} is either a bare symbol or +a symbol with position, and supplies the symbol part of the new +object. @var{pos} is either an integer which becomes the number part +of the new object, or a symbol with position whose position is used. +Emacs throws an error if either argument is invalid. +@end defun diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index fd61751cb50..b7c3461a4d7 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -191,12 +191,20 @@ will throw a warning when it encounters this symbol." (not (string-match "cedet" (macroexp-file-name))) ) (make-obsolete-overload oldfnalias newfn when) - (byte-compile-warn - "%s: `%s' obsoletes overload `%s'" - (macroexp-file-name) - newfn - (with-suppressed-warnings ((obsolete semantic-overload-symbol-from-function)) - (semantic-overload-symbol-from-function oldfnalias))))) + (if (fboundp 'byte-compile-warn-x) + (byte-compile-warn-x + newfn + "%s: `%s' obsoletes overload `%s'" + (macroexp-file-name) + newfn + (with-suppressed-warnings ((obsolete semantic-overload-symbol-from-function)) + (semantic-overload-symbol-from-function oldfnalias))) + (byte-compile-warn + "%s: `%s' obsoletes overload `%s'" + (macroexp-file-name) + newfn + (with-suppressed-warnings ((obsolete semantic-overload-symbol-from-function)) + (semantic-overload-symbol-from-function oldfnalias)))))) (defun semantic-varalias-obsolete (oldvaralias newvar when) "Make OLDVARALIAS an alias for variable NEWVAR. @@ -209,10 +217,14 @@ will throw a warning when it encounters this symbol." (error ;; Only throw this warning when byte compiling things. (when (macroexp-compiling-p) - (byte-compile-warn - "variable `%s' obsoletes, but isn't alias of `%s'" - newvar oldvaralias) - )))) + (if (fboundp 'byte-compile-warn-x) + (byte-compile-warn-x + newvar + "variable `%s' obsoletes, but isn't alias of `%s'" + newvar oldvaralias) + (byte-compile-warn + "variable `%s' obsoletes, but isn't alias of `%s'" + newvar oldvaralias)))))) ;;; Help debugging ;; diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 41d2126dbcf..587819f36ed 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1309,20 +1309,21 @@ Called with arguments (STRING POSITION FILL LEVEL). STRING is a message describing the problem. POSITION is a buffer position where the problem was detected. FILL is a prefix as in `warning-fill-prefix'. LEVEL is the level of the -problem (`:warning' or `:error'). POSITION, FILL and LEVEL may be -nil.") +problem (`:warning' or `:error'). FILL and LEVEL may be nil.") (defun byte-compile-log-warning (string &optional fill level) "Log a byte-compilation warning. STRING, FILL and LEVEL are as described in `byte-compile-log-warning-function', which see." (funcall byte-compile-log-warning-function - string nil + string + (or (byte-compile--warning-source-offset) + (point)) fill level)) -(defun byte-compile--log-warning-for-byte-compile (string &optional - _position +(defun byte-compile--log-warning-for-byte-compile (string _position + &optional fill level) "Log a message STRING in `byte-compile-log-buffer'. @@ -2653,8 +2654,11 @@ list that represents a doc string reference. (put 'require 'byte-hunk-handler 'byte-compile-file-form-require) (defun byte-compile-file-form-require (form) - (let ((args (mapcar 'eval (cdr form))) - hist-new prov-cons) + (let* ((args (mapcar 'eval (cdr form))) + ;; The following is for the byte-compile-warn in + ;; `do-after-load-evaluation' (in subr.el). + (byte-compile-form-stack (cons (car args) byte-compile-form-stack)) + hist-new prov-cons) (apply 'require args) ;; Record the functions defined by the require in `byte-compile-new-defuns'. diff --git a/lisp/keymap.el b/lisp/keymap.el index 3e9189fba45..ce566fd8afc 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -462,18 +462,19 @@ If MESSAGE (and interactively), message the result." (keywordp (car args)) (not (eq (car args) :menu))) (unless (memq (car args) '(:full :keymap :parent :suppress :name :prefix)) - (byte-compile-warn "Invalid keyword: %s" (car args))) + (byte-compile-warn-x (car args) "Invalid keyword: %s" (car args))) (setq args (cdr args)) (when (null args) - (byte-compile-warn "Uneven number of keywords in %S" form)) + (byte-compile-warn-x form "Uneven number of keywords in %S" form)) (setq args (cdr args))) ;; Bindings. (while args - (let ((key (pop args))) + (let* ((wargs args) + (key (pop args))) (when (and (stringp key) (not (key-valid-p key))) - (byte-compile-warn "Invalid `kbd' syntax: %S" key))) + (byte-compile-warn-x wargs "Invalid `kbd' syntax: %S" key))) (when (null args) - (byte-compile-warn "Uneven number of key bindings in %S" form)) + (byte-compile-warn-x form "Uneven number of key bindings in %S" form)) (setq args (cdr args))) form)