Improve errors & warnings due to fancy quoted vars (Bug#32939)

Add some hints to the message for byte compiler free & unused variable
warnings, and 'void-variable' errors where the variable has confusable
quote characters in it.
* lisp/help.el (uni-confusables), uni-confusables-regexp): New
constants.
(help-command-error-confusable-suggestions): New function, added to
`command-error-function'.
(help-uni-confusable-suggestions): New function.
* lisp/emacs-lisp/bytecomp.el (byte-compile-variable-ref):
* lisp/emacs-lisp/cconv.el (cconv--analyze-use): Use it.

* lisp/emacs-lisp/lisp-mode.el
(lisp--match-confusable-symbol-character): New function.
(lisp-fdefs): Use it to fontify confusable characters with
font-lock-warning-face when they occur in symbol names.
* doc/lispref/modes.texi (Faces for Font Lock):
* doc/lispref/objects.texi (Basic Char Syntax): Recommend backslash
escaping of confusable characters, and mention new fontification.
* etc/NEWS: Announce the new fontification behavior.
* test/lisp/emacs-lisp/lisp-mode-tests.el (lisp-fontify-confusables):
New test.
This commit is contained in:
Noam Postavsky 2018-03-10 18:12:55 -05:00
parent 85f586f3ce
commit b2790db049
8 changed files with 116 additions and 7 deletions

View file

@ -3428,7 +3428,10 @@ for symbols generated by the byte compiler itself."
(boundp var)
(memq var byte-compile-bound-variables)
(memq var byte-compile-free-references))
(byte-compile-warn "reference to free variable `%S'" var)
(let* ((varname (prin1-to-string var))
(suggestions (help-uni-confusable-suggestions varname)))
(byte-compile-warn "reference to free variable `%s'%s" varname
(if suggestions (concat "\n " suggestions) "")))
(push var byte-compile-free-references))
(byte-compile-dynamic-variable-op 'byte-varref var))))
@ -3444,7 +3447,10 @@ for symbols generated by the byte compiler itself."
(boundp var)
(memq var byte-compile-bound-variables)
(memq var byte-compile-free-assignments))
(byte-compile-warn "assignment to free variable `%s'" var)
(let* ((varname (prin1-to-string var))
(suggestions (help-uni-confusable-suggestions varname)))
(byte-compile-warn "assignment to free variable `%s'%s" varname
(if suggestions (concat "\n " suggestions) "")))
(push var byte-compile-free-assignments))
(byte-compile-dynamic-variable-op 'byte-varset var))))

View file

@ -591,8 +591,10 @@ FORM is the parent form that binds this var."
(eq ?_ (aref (symbol-name var) 0))
;; As a special exception, ignore "ignore".
(eq var 'ignored))
(byte-compile-warn "Unused lexical %s `%S'"
varkind var)))
(let ((suggestions (help-uni-confusable-suggestions (symbol-name var))))
(byte-compile-warn "Unused lexical %s `%S'%s"
varkind var
(if suggestions (concat "\n " suggestions) "")))))
;; If it's unused, there's no point converting it into a cons-cell, even if
;; it's captured and mutated.
(`(,binder ,_ t t ,_)

View file

@ -280,6 +280,19 @@ This will generate compile-time constants from BINDINGS."
`(face ,font-lock-warning-face
help-echo "This \\ has no effect"))))
(defun lisp--match-confusable-symbol-character (limit)
;; Match a confusable character within a Lisp symbol.
(catch 'matched
(while t
(if (re-search-forward uni-confusables-regexp limit t)
;; Skip confusables which are backslash escaped, or inside
;; strings or comments.
(save-match-data
(unless (or (eq (char-before (match-beginning 0)) ?\\)
(nth 8 (syntax-ppss)))
(throw 'matched t)))
(throw 'matched nil)))))
(let-when-compile
((lisp-fdefs '("defmacro" "defun"))
(lisp-vdefs '("defvar"))
@ -463,7 +476,10 @@ This will generate compile-time constants from BINDINGS."
(3 'font-lock-regexp-grouping-construct prepend))
(lisp--match-hidden-arg
(0 '(face font-lock-warning-face
help-echo "Hidden behind deeper element; move to another line?")))
help-echo "Hidden behind deeper element; move to another line?")))
(lisp--match-confusable-symbol-character
0 '(face font-lock-warning-face
help-echo "Confusable character"))
))
"Gaudy level highlighting for Emacs Lisp mode.")