branch: externals/relint commit 949595727098eb31fb0b3cb4ccbbc6489cb39e71 Author: Mattias EngdegÄrd <matti...@acm.org> Commit: Mattias EngdegÄrd <matti...@acm.org>
Grouped diagnostics, handle 'info' messages --- relint-test.el | 3 ++ relint.el | 119 ++++++++++++++++++++++++++++------------------ test/1.expected | 63 +++++++++++++++++++++++++ test/10.expected | 30 ++++++++++++ test/11.expected | 6 +++ test/13.expected | 3 ++ test/2.expected | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/3.expected | 30 ++++++++++++ test/4.expected | 15 ++++++ test/5.expected | 21 +++++++++ test/7.expected | 9 ++++ test/9.expected | 51 ++++++++++++++++++++ 12 files changed, 446 insertions(+), 45 deletions(-) diff --git a/relint-test.el b/relint-test.el index 86d1ba9148..d3470dc9c6 100644 --- a/relint-test.el +++ b/relint-test.el @@ -140,10 +140,13 @@ and a path." (relint-buffer buf) '(["In call to looking-at: Repetition of repetition" 20 28 28 "broken**regexp" 7 7 warning] + ["This is the inner expression" + 20 26 27 "broken**regexp" 5 6 info] ["In call to looking-at: Unescaped literal `^'" 50 nil nil "^^" 1 1 warning] ["In call to looking-at: Duplicated `g' inside character alternative" 82 105 105 "abcdef[gg]" 8 8 warning] + ["Previous occurrence here" 82 104 104 "abcdef[gg]" 7 7 info] ["In call to string-match: Unterminated character alternative" 125 126 128 "[xy" 0 2 error])))) (kill-buffer buf)))) diff --git a/relint.el b/relint.el index 82927d28f2..69f7856185 100644 --- a/relint.el +++ b/relint.el @@ -234,7 +234,8 @@ in case it occupies more than one position in the buffer." error-buffer (concat (format "%s:%s: " file loc-str) - (and (eq severity 'error) "error: ") + (cond ((eq severity 'error) "error: ") + ((eq severity 'info) "info: ")) message (cond ((and beg-idx end-idx (< beg-idx end-idx)) (format " (pos %d..%d)" beg-idx end-idx)) @@ -245,12 +246,13 @@ in case it occupies more than one position in the buffer." (defun relint--output-complaints (buffer file complaints error-buffer) (with-current-buffer buffer - (dolist (complaint complaints) - (relint--output-complaint error-buffer file complaint)))) + (dolist (group complaints) + (dolist (complaint group) + (relint--output-complaint error-buffer file complaint))))) (defvar relint--suppression-count) (defvar relint--complaints - ;; list of + ;; list of lists of ;; [MESSAGE EXPR-POS BEG-POS END-POS STRING BEG-IDX END-IDX SEVERITY] ;; with fields: ;; MESSAGE string of message @@ -263,30 +265,48 @@ in case it occupies more than one position in the buffer." ;; SEVERITY `error', `warning' or `info' ) -(defun relint--report (message expr-pos beg-pos end-pos - str beg-idx end-idx severity) +(defun relint--report-group (group) + (let* ((diag (car group)) + (message (aref diag 0)) + (expr-pos (aref diag 1)) + (beg-pos (aref diag 2))) (if (relint--suppression (or expr-pos beg-pos) message) (setq relint--suppression-count (1+ relint--suppression-count)) - (push (vector message expr-pos beg-pos end-pos str beg-idx end-idx severity) - relint--complaints))) + (push group relint--complaints)))) -(defun relint--report-at-path (start-pos path msg str beg-idx end-idx severity) - (let* ((expr-pos (relint--pos-from-start-pos-path start-pos path)) - (beg-pos (and beg-idx (relint--string-pos expr-pos beg-idx nil))) +(defsubst relint--make-diag (message expr-pos beg-pos end-pos + str beg-idx end-idx severity) + (vector message expr-pos beg-pos end-pos str beg-idx end-idx severity)) + +(defun relint--report-one (message expr-pos beg-pos end-pos + str beg-idx end-idx severity) + (relint--report-group + (list (relint--make-diag message expr-pos beg-pos end-pos + str beg-idx end-idx severity)))) + +(defun relint--diag-on-string (expr-pos string message beg-idx end-idx severity) + (let* ((beg-pos (and beg-idx (relint--string-pos expr-pos beg-idx nil))) (end-pos (and end-idx (relint--string-pos expr-pos end-idx t)))) - (relint--report msg expr-pos beg-pos end-pos str beg-idx end-idx severity))) + (relint--make-diag message expr-pos beg-pos end-pos + string beg-idx end-idx severity))) + +(defun relint--report-at-path (start-pos path msg str beg-idx end-idx severity) + (let ((expr-pos (relint--pos-from-start-pos-path start-pos path))) + (relint--report-group + (list (relint--diag-on-string + expr-pos str msg beg-idx end-idx severity))))) ;; FIXME: need a way to report a diagnostic for an interval-location ;; whose extent is a Lisp expression! (defun relint--warn-at (beg-pos end-pos message) - (relint--report message nil beg-pos end-pos nil nil nil 'warning)) + (relint--report-one message nil beg-pos end-pos nil nil nil 'warning)) (defun relint--warn (start-pos path message &optional str str-beg str-end) (relint--report-at-path start-pos path message str str-beg str-end 'warning)) (defun relint--err-at (pos message) - (relint--report message nil pos nil nil nil nil 'error)) + (relint--report-one message nil pos nil nil nil nil 'error)) (defun relint--escape-string (str escape-printable) (replace-regexp-in-string @@ -329,36 +349,42 @@ in case it occupies more than one position in the buffer." ((pred stringp) name) ((pred symbolp) (symbol-name name)))) -(defun relint--message-with-name (msg name) +(defun relint--message-with-context (msg name) (format "In %s: %s" (relint--expand-name name) msg)) -(defun relint--check-string (complaints string name pos path) - ;; FIXME: Compatibility hack: if given a list-of-lists, flatten it. - ;; We should move to the list-of-lists repr for our purposes too, - ;; to preserve diag clusters when sorting. - (when (consp (car complaints)) - (setq complaints (mapcar #'car complaints)) ;HACK! - ;;(setq complaints (apply #'append complaints)) - ) - (dolist (c complaints) - (let* ((beg (nth 0 c)) - (end (nth 1 c)) - (msg (nth 2 c)) - (severity (nth 3 c))) - (relint--report-at-path pos path (relint--message-with-name msg name) - string beg end severity)))) +(defun relint--string-complaints (complaints string name start-pos path) + (when complaints + (let ((expr-pos (relint--pos-from-start-pos-path start-pos path))) + (dolist (cg complaints) + (relint--report-group + (mapcar (lambda (c) + (let* ((beg (nth 0 c)) + (end (nth 1 c)) + (msg (nth 2 c)) + (severity (nth 3 c)) + ;; Only use message-with-context for non-info diags + (message (if (eq severity 'info) + msg + (relint--message-with-context msg name)))) + (relint--diag-on-string expr-pos string + message beg end severity))) + cg)))))) (defun relint--check-skip-set (skip-set name pos path) - (relint--check-string (xr-skip-set-lint skip-set) skip-set name pos path)) + (relint--string-complaints (xr-skip-set-lint skip-set) + skip-set name pos path)) (defun relint--check-re-string (re name pos path) - (relint--check-string (xr-lint re nil relint-xr-checks) re name pos path)) + (relint--string-complaints (xr-lint re nil relint-xr-checks) + re name pos path)) (defun relint--check-file-re-string (re name pos path) - (relint--check-string (xr-lint re 'file relint-xr-checks) re name pos path)) + (relint--string-complaints (xr-lint re 'file relint-xr-checks) + re name pos path)) -(defun relint--check-syntax-string (syn name pos path) - (relint--check-string (relint--syntax-string-lint syn) syn name pos path)) +(defun relint--check-syntax-string (syntax name pos path) + (relint--string-complaints (relint--syntax-string-lint syntax) + syntax name pos path)) (defconst relint--syntax-codes '((?- . whitespace) @@ -380,7 +406,8 @@ in case it occupies more than one position in the buffer." (?! . comment-delimiter))) (defun relint--syntax-string-lint (syntax) - "Check the syntax-skip string SYNTAX. Return list of complaints." + "Check the syntax-skip string SYNTAX. +Return list of complaint groups, each a list of (BEG END MESSAGE SEVERITY)." (let ((errs nil) (start (if (string-prefix-p "^" syntax) 1 0))) (when (member syntax '("" "^")) @@ -2584,9 +2611,10 @@ The keys are sorted numerically, in ascending order.") (cons (relint--sort-with-key ;; Sort by error position if available, expression position otherwise. - (lambda (c) - (let ((expr-pos (aref c 1)) - (error-pos (aref c 2))) + (lambda (g) + (let* ((c (car g)) + (expr-pos (aref c 1)) + (error-pos (aref c 2))) (or error-pos expr-pos))) complaints) relint--suppression-count)))) @@ -2741,23 +2769,24 @@ The buffer must be in emacs-lisp-mode." ;;;###autoload (defun relint-buffer (buffer) "Scan BUFFER for regexp errors. Return list of diagnostics. -Each element in the returned list has the form +Each element in the returned list is a vector having the form - (MESSAGE EXPR-POS BEG-POS END-POS STRING BEG-IDX END-IDX SEVERITY) + [MESSAGE EXPR-POS BEG-POS END-POS STRING BEG-IDX END-IDX SEVERITY] where MESSAGE the message string - EXPR-POS the location of the flawed expression or nil - BEG-POS, END-POS exact bounds in the buffer of the error, or nil + EXPR-POS the position of the flawed expression or nil + BEG-POS, END-POS exact bounds in the buffer (inclusive), or nil STRING nil or a string to which the message pertains - BEG-IDX, END-IDX bounds in STRING or nil + BEG-IDX, END-IDX bounds in STRING (inclusive) or nil SEVERITY `error', `warning' or `info' The intent is that BEG-POS..END-POS is the buffer range that corresponds to STRING at BEG-IDX..END-IDX, if such a location can be determined." - (car (relint--scan-buffer buffer))) + (let ((groups (car (relint--scan-buffer buffer)))) + (apply #'append groups))) ; flatten groups (defun relint-batch () "Scan elisp source files for regexp-related errors. diff --git a/test/1.expected b/test/1.expected index c0bac97f9d..f24933244c 100644 --- a/test/1.expected +++ b/test/1.expected @@ -1,15 +1,27 @@ 1.elisp:6:25-25: In bad-regexp: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +1.elisp:6:24-24: info: Previous occurrence here (pos 1) + "[AA]" + .^ 1.elisp:7:24-24: In bad-regex: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +1.elisp:7:23-23: info: Previous occurrence here (pos 1) + "[AA]" + .^ 1.elisp:8:21-21: In bad-re: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +1.elisp:8:20-20: info: Previous occurrence here (pos 1) + "[AA]" + .^ 1.elisp:9:26-26: In bad-pattern: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +1.elisp:9:25-25: info: Previous occurrence here (pos 1) + "[AA]" + .^ 1.elisp:11:30-30: In bad-regexps: Unescaped literal `+' (pos 0) "+a" ^ @@ -88,36 +100,63 @@ 1.elisp:31:40-40: In bad-font-lock-keywords (tag): Duplicated `x' inside character alternative (pos 2) "[xx]" ..^ +1.elisp:31:39-39: info: Previous occurrence here (pos 1) + "[xx]" + .^ 1.elisp:31:54-54: In bad-font-lock-keywords: Duplicated `y' inside character alternative (pos 2) "[yy]" ..^ +1.elisp:31:53-53: info: Previous occurrence here (pos 1) + "[yy]" + .^ 1.elisp:32:45-45: In more-font-lock-keywords-bad (tag): Duplicated `u' inside character alternative (pos 2) "[uu]" ..^ +1.elisp:32:44-44: info: Previous occurrence here (pos 1) + "[uu]" + .^ 1.elisp:32:59-59: In more-font-lock-keywords-bad: Duplicated `v' inside character alternative (pos 2) "[vv]" ..^ +1.elisp:32:58-58: info: Previous occurrence here (pos 1) + "[vv]" + .^ 1.elisp:33:39-39: In font-lock-add-keywords (tag): Duplicated `s' inside character alternative (pos 2) "[ss]" ..^ +1.elisp:33:38-38: info: Previous occurrence here (pos 1) + "[ss]" + .^ 1.elisp:33:53-53: In font-lock-add-keywords: Duplicated `t' inside character alternative (pos 2) "[tt]" ..^ +1.elisp:33:52-52: info: Previous occurrence here (pos 1) + "[tt]" + .^ 1.elisp:36:23-23: In bad-var-1: Unescaped literal `^' (pos 1) "a^" .^ 1.elisp:38:22-22: In bad-var-2: Duplicated `z' inside character alternative (pos 2) "[zz]" ..^ +1.elisp:38:21-21: info: Previous occurrence here (pos 1) + "[zz]" + .^ 1.elisp:40:24-26: In bad-var-3: Reversed range `o-O' matches nothing (pos 1..3) "[o-O]" .^^^ 1.elisp:46:28-28: In bad-custom-1: Duplicated `n' inside character alternative (pos 2) "[nn]" ..^ +1.elisp:46:27-27: info: Previous occurrence here (pos 1) + "[nn]" + .^ 1.elisp:50:28-28: In bad-custom-2: Duplicated `s' inside character alternative (pos 2) "[ss]" ..^ +1.elisp:50:27-27: info: Previous occurrence here (pos 1) + "[ss]" + .^ 1.elisp:57:9: In bad-custom-3-regexp: Unescaped literal `+' (pos 0) "+a+" ^ @@ -139,18 +178,33 @@ 1.elisp:73:35-35: In bad-custom-7: Duplicated `a' inside character alternative (pos 2) "[aa]" ..^ +1.elisp:73:34-34: info: Previous occurrence here (pos 1) + "[aa]" + .^ 1.elisp:80:9: In bad-custom-8: Duplicated `1' inside character alternative (pos 2) "[11]" ..^ +1.elisp:80:9: info: Previous occurrence here (pos 1) + "[11]" + .^ 1.elisp:80:9: In bad-custom-8: Duplicated `2' inside character alternative (pos 2) "[22]" ..^ +1.elisp:80:9: info: Previous occurrence here (pos 1) + "[22]" + .^ 1.elisp:85:9: In bad-custom-9-regexp: Duplicated `3' inside character alternative (pos 2) "[33]" ..^ +1.elisp:85:9: info: Previous occurrence here (pos 1) + "[33]" + .^ 1.elisp:89:9: In bad-custom-10: Duplicated `4' inside character alternative (pos 2) "[44]" ..^ +1.elisp:89:9: info: Previous occurrence here (pos 1) + "[44]" + .^ 1.elisp:93:11-11: In compilation-error-regexp-alist-alist (aa): Unescaped literal `^' (pos 1) "a^a" .^ @@ -166,6 +220,9 @@ 1.elisp:101:12-12: In define-generic-mode my-mode: Repetition of repetition (pos 2) "b++" ..^ +1.elisp:101:10-11: info: This is the inner expression (pos 0..1) + "b++" + ^^ 1.elisp:107:6-6: In call to syntax-propertize-rules: Unescaped literal `$' (pos 0) "$1$" ^ @@ -181,9 +238,15 @@ 1.elisp:116:50-50: In my-ts--font-lock-rules: Duplicated `5' inside character alternative (pos 2) "[55]" ..^ +1.elisp:116:49-49: info: Previous occurrence here (pos 1) + "[55]" + .^ 1.elisp:117:54-54: In my-ts-mode-font-lock-rules: Duplicated `6' inside character alternative (pos 2) "[66]" ..^ +1.elisp:117:53-53: info: Previous occurrence here (pos 1) + "[66]" + .^ 1.elisp:121:16-18: Suspect range `+-/' (pos 0..2) "+-/" ^^^ diff --git a/test/10.expected b/test/10.expected index 625e9f7b9c..7a0cffac96 100644 --- a/test/10.expected +++ b/test/10.expected @@ -1,33 +1,63 @@ 10.elisp:7:17-17: In test-1-regexp-list: Duplicated `a' inside character alternative (pos 2) "[aa]" ..^ +10.elisp:7:16-16: info: Previous occurrence here (pos 1) + "[aa]" + .^ 10.elisp:8:21-21: In test-1-regexp-list: Duplicated `b' inside character alternative (pos 2) "[bb]" ..^ +10.elisp:8:20-20: info: Previous occurrence here (pos 1) + "[bb]" + .^ 10.elisp:11:13-13: In test-2-regexp-alist: Duplicated `c' inside character alternative (pos 2) "[cc]" ..^ +10.elisp:11:12-12: info: Previous occurrence here (pos 1) + "[cc]" + .^ 10.elisp:12:5: In test-2-regexp-alist: Duplicated `d' inside character alternative (pos 2) "[dd]" ..^ +10.elisp:12:5: info: Previous occurrence here (pos 1) + "[dd]" + .^ 10.elisp:13:5: In test-2-regexp-alist: Duplicated `e' inside character alternative (pos 2) "[ee]" ..^ +10.elisp:13:5: info: Previous occurrence here (pos 1) + "[ee]" + .^ 10.elisp:14:5: In test-2-regexp-alist: Duplicated `f' inside character alternative (pos 2) "[ff]" ..^ +10.elisp:14:5: info: Previous occurrence here (pos 1) + "[ff]" + .^ 10.elisp:14:5: In test-2-regexp-alist: Duplicated `g' inside character alternative (pos 2) "[gg]" ..^ +10.elisp:14:5: info: Previous occurrence here (pos 1) + "[gg]" + .^ 10.elisp:15:13-13: In test-2-regexp-alist: Duplicated `h' inside character alternative (pos 2) "[hh]" ..^ +10.elisp:15:12-12: info: Previous occurrence here (pos 1) + "[hh]" + .^ 10.elisp:16:24-24: Single-character range `z-z' (pos 0) "z-z" ^ 10.elisp:20:9-9: In test-3-regexp-alist: Duplicated `i' inside character alternative (pos 2) "[ii]" ..^ +10.elisp:20:8-8: info: Previous occurrence here (pos 1) + "[ii]" + .^ 10.elisp:20:18-18: In test-3-regexp-alist: Duplicated `j' inside character alternative (pos 2) "[jj]" ..^ +10.elisp:20:17-17: info: Previous occurrence here (pos 1) + "[jj]" + .^ diff --git a/test/11.expected b/test/11.expected index c44a9f9e62..11f3cc1268 100644 --- a/test/11.expected +++ b/test/11.expected @@ -28,9 +28,15 @@ 11.elisp:16:4: In rx `regexp' form: Duplicated `1' inside character alternative (pos 2) "[11]" ..^ +11.elisp:16:4: info: Previous occurrence here (pos 1) + "[11]" + .^ 11.elisp:16:4: In rx `regex' form: Duplicated `2' inside character alternative (pos 2) "[22]" ..^ +11.elisp:16:4: info: Previous occurrence here (pos 1) + "[22]" + .^ 11.elisp:16:4: Duplicated character `3' (pos 1) "33" .^ diff --git a/test/13.expected b/test/13.expected index 0048c1d310..ee49469c16 100644 --- a/test/13.expected +++ b/test/13.expected @@ -24,6 +24,9 @@ 13.elisp:18:30-31: In call to re-search-forward: Repetition of repetition (pos 4) "$.x++" ....^ +13.elisp:18:27-29: info: This is the inner expression (pos 2..3) + "$.x++" + ..^^ 13.elisp:18:30-31: Ineffective string escape `\+' 13.elisp:19:16-17: Ineffective string escape `\q' 13.elisp:22:16-17: Ineffective string escape `\8' diff --git a/test/2.expected b/test/2.expected index ec000b61ec..b04c603598 100644 --- a/test/2.expected +++ b/test/2.expected @@ -1,84 +1,165 @@ 2.elisp:5:18-18: In call to looking-at: Duplicated `a' inside character alternative (pos 2) "[aa]" ..^ +2.elisp:5:17-17: info: Previous occurrence here (pos 1) + "[aa]" + .^ 2.elisp:6:25-25: In call to re-search-forward: Duplicated `b' inside character alternative (pos 2) "[bb]" ..^ +2.elisp:6:24-24: info: Previous occurrence here (pos 1) + "[bb]" + .^ 2.elisp:7:26-26: In call to re-search-backward: Duplicated `c' inside character alternative (pos 2) "[cc]" ..^ +2.elisp:7:25-25: info: Previous occurrence here (pos 1) + "[cc]" + .^ 2.elisp:8:29-29: In call to search-forward-regexp: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +2.elisp:8:28-28: info: Previous occurrence here (pos 1) + "[BB]" + .^ 2.elisp:9:29-29: In call to search-forward-regexp: Duplicated `C' inside character alternative (pos 2) "[CC]" ..^ +2.elisp:9:28-28: info: Previous occurrence here (pos 1) + "[CC]" + .^ 2.elisp:10:20-20: In call to string-match: Duplicated `d' inside character alternative (pos 2) "[dd]" ..^ +2.elisp:10:19-19: info: Previous occurrence here (pos 1) + "[dd]" + .^ 2.elisp:11:22-22: In call to string-match-p: Duplicated `e' inside character alternative (pos 2) "[ee]" ..^ +2.elisp:11:21-21: info: Previous occurrence here (pos 1) + "[ee]" + .^ 2.elisp:12:20-20: In call to looking-at-p: Duplicated `f' inside character alternative (pos 2) "[ff]" ..^ +2.elisp:12:19-19: info: Previous occurrence here (pos 1) + "[ff]" + .^ 2.elisp:13:20-20: In call to looking-back: Duplicated `g' inside character alternative (pos 2) "[gg]" ..^ +2.elisp:13:19-19: info: Previous occurrence here (pos 1) + "[gg]" + .^ 2.elisp:14:32-32: In call to replace-regexp-in-string: Duplicated `h' inside character alternative (pos 2) "[hh]" ..^ +2.elisp:14:31-31: info: Previous occurrence here (pos 1) + "[hh]" + .^ 2.elisp:15:28-28: In call to query-replace-regexp: Duplicated `j' inside character alternative (pos 2) "[jj]" ..^ +2.elisp:15:27-27: info: Previous occurrence here (pos 1) + "[jj]" + .^ 2.elisp:16:24-24: In call to posix-looking-at: Duplicated `k' inside character alternative (pos 2) "[kk]" ..^ +2.elisp:16:23-23: info: Previous occurrence here (pos 1) + "[kk]" + .^ 2.elisp:17:29-29: In call to posix-search-backward: Duplicated `l' inside character alternative (pos 2) "[ll]" ..^ +2.elisp:17:28-28: info: Previous occurrence here (pos 1) + "[ll]" + .^ 2.elisp:18:28-28: In call to posix-search-forward: Duplicated `m' inside character alternative (pos 2) "[mm]" ..^ +2.elisp:18:27-27: info: Previous occurrence here (pos 1) + "[mm]" + .^ 2.elisp:19:26-26: In call to posix-string-match: Duplicated `n' inside character alternative (pos 2) "[nn]" ..^ +2.elisp:19:25-25: info: Previous occurrence here (pos 1) + "[nn]" + .^ 2.elisp:20:37-37: In call to load-history-filename-element: Duplicated `o' inside character alternative (pos 2) "[oo]" ..^ +2.elisp:20:36-36: info: Previous occurrence here (pos 1) + "[oo]" + .^ 2.elisp:21:29-29: In call to kill-matching-buffers: Duplicated `p' inside character alternative (pos 2) "[pp]" ..^ +2.elisp:21:28-28: info: Previous occurrence here (pos 1) + "[pp]" + .^ 2.elisp:22:18-18: In call to keep-lines: Duplicated `q' inside character alternative (pos 2) "[qq]" ..^ +2.elisp:22:17-17: info: Previous occurrence here (pos 1) + "[qq]" + .^ 2.elisp:23:19-19: In call to flush-lines: Duplicated `r' inside character alternative (pos 2) "[rr]" ..^ +2.elisp:23:18-18: info: Previous occurrence here (pos 1) + "[rr]" + .^ 2.elisp:24:16-16: In call to how-many: Duplicated `s' inside character alternative (pos 2) "[ss]" ..^ +2.elisp:24:15-15: info: Previous occurrence here (pos 1) + "[ss]" + .^ 2.elisp:25:22-22: In call to split-string: Duplicated `t' inside character alternative (pos 2) "[tt]" ..^ +2.elisp:25:21-21: info: Previous occurrence here (pos 1) + "[tt]" + .^ 2.elisp:25:33-33: In call to split-string: Duplicated `u' inside character alternative (pos 2) "[uu]" ..^ +2.elisp:25:32-32: info: Previous occurrence here (pos 1) + "[uu]" + .^ 2.elisp:26:34-34: In call to split-string-and-unquote: Duplicated `v' inside character alternative (pos 2) "[vv]" ..^ +2.elisp:26:33-33: info: Previous occurrence here (pos 1) + "[vv]" + .^ 2.elisp:27:26-26: In call to string-trim-left: Duplicated `w' inside character alternative (pos 2) "[ww]" ..^ +2.elisp:27:25-25: info: Previous occurrence here (pos 1) + "[ww]" + .^ 2.elisp:28:27-27: In call to string-trim-right: Duplicated `x' inside character alternative (pos 2) "[xx]" ..^ +2.elisp:28:26-26: info: Previous occurrence here (pos 1) + "[xx]" + .^ 2.elisp:29:21-21: In call to string-trim: Duplicated `y' inside character alternative (pos 2) "[yy]" ..^ +2.elisp:29:20-20: info: Previous occurrence here (pos 1) + "[yy]" + .^ 2.elisp:29:28-28: In call to string-trim: Duplicated `z' inside character alternative (pos 2) "[zz]" ..^ +2.elisp:29:27-27: info: Previous occurrence here (pos 1) + "[zz]" + .^ 2.elisp:30:27-27: In call to directory-files: Unescaped literal `+' (pos 0) "+1" ^ @@ -112,63 +193,123 @@ 2.elisp:52:17-17: In call to f2: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +2.elisp:52:16-16: info: Previous occurrence here (pos 1) + "[BB]" + .^ 2.elisp:52:31-31: In call to f2: Duplicated `D' inside character alternative (pos 2) "[DD]" ..^ +2.elisp:52:30-30: info: Previous occurrence here (pos 1) + "[DD]" + .^ 2.elisp:52:45-45: In call to f2: Duplicated `F' inside character alternative (pos 2) "[FF]" ..^ +2.elisp:52:44-44: info: Previous occurrence here (pos 1) + "[FF]" + .^ 2.elisp:52:59-59: In call to f2: Duplicated `H' inside character alternative (pos 2) "[HH]" ..^ +2.elisp:52:58-58: info: Previous occurrence here (pos 1) + "[HH]" + .^ 2.elisp:52:73-73: In call to f2: Duplicated `J' inside character alternative (pos 2) "[JJ]" ..^ +2.elisp:52:72-72: info: Previous occurrence here (pos 1) + "[JJ]" + .^ 2.elisp:53:17-17: In call to s2: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +2.elisp:53:16-16: info: Previous occurrence here (pos 1) + "[BB]" + .^ 2.elisp:53:31-31: In call to s2: Duplicated `D' inside character alternative (pos 2) "[DD]" ..^ +2.elisp:53:30-30: info: Previous occurrence here (pos 1) + "[DD]" + .^ 2.elisp:53:45-45: In call to s2: Duplicated `F' inside character alternative (pos 2) "[FF]" ..^ +2.elisp:53:44-44: info: Previous occurrence here (pos 1) + "[FF]" + .^ 2.elisp:53:59-59: In call to s2: Duplicated `H' inside character alternative (pos 2) "[HH]" ..^ +2.elisp:53:58-58: info: Previous occurrence here (pos 1) + "[HH]" + .^ 2.elisp:53:73-73: In call to s2: Duplicated `J' inside character alternative (pos 2) "[JJ]" ..^ +2.elisp:53:72-72: info: Previous occurrence here (pos 1) + "[JJ]" + .^ 2.elisp:54:17-17: In call to m2: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +2.elisp:54:16-16: info: Previous occurrence here (pos 1) + "[BB]" + .^ 2.elisp:54:31-31: In call to m2: Duplicated `D' inside character alternative (pos 2) "[DD]" ..^ +2.elisp:54:30-30: info: Previous occurrence here (pos 1) + "[DD]" + .^ 2.elisp:54:45-45: In call to m2: Duplicated `F' inside character alternative (pos 2) "[FF]" ..^ +2.elisp:54:44-44: info: Previous occurrence here (pos 1) + "[FF]" + .^ 2.elisp:54:59-59: In call to m2: Duplicated `H' inside character alternative (pos 2) "[HH]" ..^ +2.elisp:54:58-58: info: Previous occurrence here (pos 1) + "[HH]" + .^ 2.elisp:54:73-73: In call to m2: Duplicated `J' inside character alternative (pos 2) "[JJ]" ..^ +2.elisp:54:72-72: info: Previous occurrence here (pos 1) + "[JJ]" + .^ 2.elisp:62:17-17: In call to f5: Duplicated `b' inside character alternative (pos 2) "[bb]" ..^ +2.elisp:62:16-16: info: Previous occurrence here (pos 1) + "[bb]" + .^ 2.elisp:62:24-24: In call to f5: Duplicated `c' inside character alternative (pos 2) "[cc]" ..^ +2.elisp:62:23-23: info: Previous occurrence here (pos 1) + "[cc]" + .^ 2.elisp:62:31-31: In call to f5: Duplicated `d' inside character alternative (pos 2) "[dd]" ..^ +2.elisp:62:30-30: info: Previous occurrence here (pos 1) + "[dd]" + .^ 2.elisp:65:26-26: In :regexp parameter: Duplicated `1' inside character alternative (pos 2) "[11]" ..^ +2.elisp:65:25-25: info: Previous occurrence here (pos 1) + "[11]" + .^ 2.elisp:66:20-20: In :regex parameter: Duplicated `2' inside character alternative (pos 2) "[22]" ..^ +2.elisp:66:19-19: info: Previous occurrence here (pos 1) + "[22]" + .^ 2.elisp:69:31-31: In call to sort-regexp-fields: Unescaped literal `$' (pos 3) "^.*$x" ...^ diff --git a/test/3.expected b/test/3.expected index d79ea7c7a8..69e9093b6e 100644 --- a/test/3.expected +++ b/test/3.expected @@ -7,33 +7,60 @@ 3.elisp:72:4: In call to looking-at: Duplicated `Q' inside character alternative (pos 2) "[QQ]" ..^ +3.elisp:72:4: info: Previous occurrence here (pos 1) + "[QQ]" + .^ 3.elisp:94:4: In call to looking-at: Unescaped literal `^' (pos 2) "^m^" ..^ 3.elisp:131:4: In another-bad-regexp-list: Duplicated `1' inside character alternative (pos 2) "[11]" ..^ +3.elisp:131:4: info: Previous occurrence here (pos 1) + "[11]" + .^ 3.elisp:132:4: In another-bad-regexp-list: Duplicated `2' inside character alternative (pos 2) "[22]" ..^ +3.elisp:132:4: info: Previous occurrence here (pos 1) + "[22]" + .^ 3.elisp:132:4: In another-bad-regexp-list: Duplicated `1' inside character alternative (pos 2) "[11]" ..^ +3.elisp:132:4: info: Previous occurrence here (pos 1) + "[11]" + .^ 3.elisp:133:4: In another-bad-regexp-list: Duplicated `3' inside character alternative (pos 2) "[33]" ..^ +3.elisp:133:4: info: Previous occurrence here (pos 1) + "[33]" + .^ 3.elisp:134:4: In another-bad-regexp-list: Duplicated `4' inside character alternative (pos 2) "[44]" ..^ +3.elisp:134:4: info: Previous occurrence here (pos 1) + "[44]" + .^ 3.elisp:135:4: In another-bad-regexp-list: Duplicated `5' inside character alternative (pos 2) "[55]" ..^ +3.elisp:135:4: info: Previous occurrence here (pos 1) + "[55]" + .^ 3.elisp:136:4: In another-bad-regexp-list: Duplicated `6' inside character alternative (pos 2) "[66]" ..^ +3.elisp:136:4: info: Previous occurrence here (pos 1) + "[66]" + .^ 3.elisp:137:4: In another-bad-regexp-list: Duplicated `7' inside character alternative (pos 2) "[77]" ..^ +3.elisp:137:4: info: Previous occurrence here (pos 1) + "[77]" + .^ 3.elisp:141:13-13: In call to looking-at: Unescaped literal `+' (pos 0) "+abcdefgh" ^ @@ -43,3 +70,6 @@ 3.elisp:164:4: In call to looking-at: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +3.elisp:164:4: info: Previous occurrence here (pos 1) + "[AA]" + .^ diff --git a/test/4.expected b/test/4.expected index a7d3a1d79e..baf20ca36c 100644 --- a/test/4.expected +++ b/test/4.expected @@ -13,9 +13,15 @@ 4.elisp:17:15: In call to looking-at: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +4.elisp:17:15: info: Previous occurrence here (pos 1) + "[AA]" + .^ 4.elisp:18:15: In call to looking-at: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +4.elisp:18:15: info: Previous occurrence here (pos 1) + "[BB]" + .^ 4.elisp:19:15: In call to looking-at: Unescaped literal `+' (pos 0) "+b" ^ @@ -37,15 +43,24 @@ 4.elisp:44:15: In call to looking-at: Repetition of repetition (pos 2) "b++" ..^ +4.elisp:44:15: info: This is the inner expression (pos 0..1) + "b++" + ^^ 4.elisp:45:15: In call to looking-at: Repetition of repetition (pos 2) "c++" ..^ +4.elisp:45:15: info: This is the inner expression (pos 0..1) + "c++" + ^^ 4.elisp:46:15: In call to looking-at: Unescaped literal `$' (pos 1) "a$b" .^ 4.elisp:47:15: In call to looking-at: Repetition of repetition (pos 2) "d++" ..^ +4.elisp:47:15: info: This is the inner expression (pos 0..1) + "d++" + ^^ 4.elisp:48:15: In call to looking-at: Unescaped literal `*' (pos 0) "*" ^ diff --git a/test/5.expected b/test/5.expected index d73b1beeac..eefd2bd66f 100644 --- a/test/5.expected +++ b/test/5.expected @@ -7,9 +7,15 @@ 5.elisp:21:4: In call to looking-at: Duplicated `A' inside character alternative (pos 2) "[AA]" ..^ +5.elisp:21:4: info: Previous occurrence here (pos 1) + "[AA]" + .^ 5.elisp:32:17: In call to looking-at: Duplicated `B' inside character alternative (pos 2) "[BB]" ..^ +5.elisp:32:17: info: Previous occurrence here (pos 1) + "[BB]" + .^ 5.elisp:37:17: In call to looking-at: Unescaped literal `+' (pos 0) "+a" ^ @@ -19,12 +25,21 @@ 5.elisp:46:15: In call to looking-at: Duplicated `C' inside character alternative (pos 2) "[CC]" ..^ +5.elisp:46:15: info: Previous occurrence here (pos 1) + "[CC]" + .^ 5.elisp:51:17: In call to looking-at: Duplicated `D' inside character alternative (pos 2) "[DD]" ..^ +5.elisp:51:17: info: Previous occurrence here (pos 1) + "[DD]" + .^ 5.elisp:59:15: In call to looking-at: Duplicated `E' inside character alternative (pos 2) "[EE]" ..^ +5.elisp:59:15: info: Previous occurrence here (pos 1) + "[EE]" + .^ 5.elisp:62:15: In call to looking-at: Unescaped literal `*' (pos 0) "*b" ^ @@ -34,6 +49,12 @@ 5.elisp:72:15: In call to looking-at: Duplicated `U' inside character alternative (pos 2) "[UU]" ..^ +5.elisp:72:15: info: Previous occurrence here (pos 1) + "[UU]" + .^ 5.elisp:75:15: In call to looking-at: Duplicated `V' inside character alternative (pos 2) "[VV]" ..^ +5.elisp:75:15: info: Previous occurrence here (pos 1) + "[VV]" + .^ diff --git a/test/7.expected b/test/7.expected index 994ef63bcb..7991b826e5 100644 --- a/test/7.expected +++ b/test/7.expected @@ -7,12 +7,21 @@ 7.elisp:24:15: In call to looking-at: Duplicated `*' inside character alternative (pos 2) "[**]" ..^ +7.elisp:24:15: info: Previous occurrence here (pos 1) + "[**]" + .^ 7.elisp:31:4: In call to looking-at: Unescaped literal `$' (pos 3) "!\"#$%" ....^ 7.elisp:34:15: In call to looking-at: Duplicated `X' inside character alternative (pos 2) "[XX]" ..^ +7.elisp:34:15: info: Previous occurrence here (pos 1) + "[XX]" + .^ 7.elisp:37:15: In call to looking-at: Duplicated `X' inside character alternative (pos 2) "[XX]" ..^ +7.elisp:37:15: info: Previous occurrence here (pos 1) + "[XX]" + .^ diff --git a/test/9.expected b/test/9.expected index 50f8ea7498..9157f027a1 100644 --- a/test/9.expected +++ b/test/9.expected @@ -1,39 +1,75 @@ 9.elisp:6:33-33: In page-delimiter: Duplicated `a' inside character alternative (pos 2) "[aa]" ..^ +9.elisp:6:32-32: info: Previous occurrence here (pos 1) + "[aa]" + .^ 9.elisp:7:37-37: In paragraph-separate: Duplicated `b' inside character alternative (pos 2) "[bb]" ..^ +9.elisp:7:36-36: info: Previous occurrence here (pos 1) + "[bb]" + .^ 9.elisp:8:34-34: In paragraph-start: Duplicated `c' inside character alternative (pos 2) "[cc]" ..^ +9.elisp:8:33-33: info: Previous occurrence here (pos 1) + "[cc]" + .^ 9.elisp:9:31-31: In sentence-end: Duplicated `d' inside character alternative (pos 2) "[dd]" ..^ +9.elisp:9:30-30: info: Previous occurrence here (pos 1) + "[dd]" + .^ 9.elisp:10:37-37: In comment-start-skip: Duplicated `e' inside character alternative (pos 2) "[ee]" ..^ +9.elisp:10:36-36: info: Previous occurrence here (pos 1) + "[ee]" + .^ 9.elisp:11:35-35: In comment-end-skip: Duplicated `f' inside character alternative (pos 2) "[ff]" ..^ +9.elisp:11:34-34: info: Previous occurrence here (pos 1) + "[ff]" + .^ 9.elisp:13:25-25: In sentence-end: Duplicated `g' inside character alternative (pos 2) "[gg]" ..^ +9.elisp:13:24-24: info: Previous occurrence here (pos 1) + "[gg]" + .^ 9.elisp:14:50-50: In paragraph-start: Duplicated `h' inside character alternative (pos 2) "[hh]" ..^ +9.elisp:14:49-49: info: Previous occurrence here (pos 1) + "[hh]" + .^ 9.elisp:16:32-32: In paragraph-separate: Duplicated `i' inside character alternative (pos 2) "[ii]" ..^ +9.elisp:16:31-31: info: Previous occurrence here (pos 1) + "[ii]" + .^ 9.elisp:17:28-28: In page-delimiter: Duplicated `j' inside character alternative (pos 2) "[jj]" ..^ +9.elisp:17:27-27: info: Previous occurrence here (pos 1) + "[jj]" + .^ 9.elisp:18:35-35: In comment-start-skip: Duplicated `k' inside character alternative (pos 2) "[kk]" ..^ +9.elisp:18:34-34: info: Previous occurrence here (pos 1) + "[kk]" + .^ 9.elisp:19:33-33: In comment-end-skip: Duplicated `l' inside character alternative (pos 2) "[ll]" ..^ +9.elisp:19:32-32: info: Previous occurrence here (pos 1) + "[ll]" + .^ 9.elisp:22:39-39: In treesit-sentence-type-regexp: Unescaped literal `+' (pos 0) "+0" ^ @@ -55,18 +91,33 @@ 9.elisp:44:40-40: In font-lock-keywords (tag): Duplicated `m' inside character alternative (pos 2) "[mm]" ..^ +9.elisp:44:39-39: info: Previous occurrence here (pos 1) + "[mm]" + .^ 9.elisp:45:34-34: In font-lock-keywords (tag): Duplicated `n' inside character alternative (pos 2) "[nn]" ..^ +9.elisp:45:33-33: info: Previous occurrence here (pos 1) + "[nn]" + .^ 9.elisp:46:56-56: In font-lock-keywords (tag): Duplicated `o' inside character alternative (pos 2) "[oo]" ..^ +9.elisp:46:55-55: info: Previous occurrence here (pos 1) + "[oo]" + .^ 9.elisp:52:9-9: In my-font-lock-keywords-2 (beta): Duplicated `q' inside character alternative (pos 2) "[qq]" ..^ +9.elisp:52:8-8: info: Previous occurrence here (pos 1) + "[qq]" + .^ 9.elisp:56:9: In font-lock-defaults (alpha): Duplicated `p' inside character alternative (pos 2) "[pp]" ..^ +9.elisp:56:9: info: Previous occurrence here (pos 1) + "[pp]" + .^ 9.elisp:62:23-23: In treesit-simple-indent-rules (a): Unescaped literal `+' (pos 0) "+e+" ^