[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/xr e2455fd4bd 15/18: Add info-level messages for many w
From: |
ELPA Syncer |
Subject: |
[elpa] externals/xr e2455fd4bd 15/18: Add info-level messages for many warnings |
Date: |
Thu, 1 Aug 2024 13:00:01 -0400 (EDT) |
branch: externals/xr
commit e2455fd4bd946208f96048115cdd41e74e03b764
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>
Add info-level messages for many warnings
---
xr-test.el | 448 ++++++++++++++++++++++++++++++++++++++++---------------------
xr.el | 270 ++++++++++++++++++++++---------------
2 files changed, 461 insertions(+), 257 deletions(-)
diff --git a/xr-test.el b/xr-test.el
index 66b5eca117..62e7970834 100644
--- a/xr-test.el
+++ b/xr-test.el
@@ -425,45 +425,65 @@
((4 5 "Escaped non-special character `a'" warning))
((8 9 "Escaped non-special character `%'" warning)))))
(should (equal (xr-lint "a?+b+?\\(?:c*\\)*d\\{3\\}+e*?\\{2,5\\}")
- '(((2 2 "Repetition of option" warning))
- ((14 14 "Repetition of repetition" warning))
- ((25 31 "Repetition of repetition" warning)))))
+ '(((2 2 "Repetition of option" warning)
+ (0 1 "This is the inner expression" info))
+ ((14 14 "Repetition of repetition" warning)
+ (6 13 "This is the inner expression" info))
+ ((25 31 "Repetition of repetition" warning)
+ (22 24 "This is the inner expression" info)))))
(should (equal (xr-lint "\\(?:a+\\)?")
nil))
(should (equal (xr-lint "\\(a*\\)*\\(b+\\)*\\(c*\\)?\\(d+\\)?")
- '(((6 6 "Repetition of repetition" warning))
- ((13 13 "Repetition of repetition" warning))
- ((20 20 "Optional repetition" warning)))))
+ '(((6 6 "Repetition of repetition" warning)
+ (0 5 "This is the inner expression" info))
+ ((13 13 "Repetition of repetition" warning)
+ (7 12 "This is the inner expression" info))
+ ((20 20 "Optional repetition" warning)
+ (14 19 "This is the inner expression" info)))))
(should (equal (xr-lint "\\(a?\\)+\\(b?\\)?")
- '(((6 6 "Repetition of option" warning))
- ((13 13 "Optional option" warning)))))
+ '(((6 6 "Repetition of option" warning)
+ (0 5 "This is the inner expression" info))
+ ((13 13 "Optional option" warning)
+ (7 12 "This is the inner expression" info)))))
(should (equal (xr-lint "\\(e*\\)\\{3\\}")
- '(((6 10 "Repetition of repetition" warning)))))
+ '(((6 10 "Repetition of repetition" warning)
+ (0 5 "This is the inner expression" info)))))
(should (equal (xr-lint "\\(a?\\)\\{4,7\\}")
- '(((6 12 "Repetition of option" warning)))))
+ '(((6 12 "Repetition of option" warning)
+ (0 5 "This is the inner expression" info)))))
(should (equal (xr-lint "\\(?:a?b+c?d*\\)*")
- '(((14 14 "Repetition of effective repetition" warning)))))
+ '(((14 14 "Repetition of effective repetition" warning)
+ (0 13 "This expression contains a repetition" info)))))
(should (equal (xr-lint "\\(a?b+c?d*\\)*")
- '(((12 12 "Repetition of effective repetition" warning)))))
+ '(((12 12 "Repetition of effective repetition" warning)
+ (0 11 "This expression contains a repetition" info)))))
(should (equal (xr-lint "a*\\|b+\\|\\(?:a\\)*")
- '(((8 15 "Duplicated alternative branch" warning)))))
+ '(((8 15 "Duplicated alternative branch" warning)
+ (0 1 "Previous occurrence here" info)))))
(should (equal (xr-lint "a\\{,\\}")
'(((1 5 "Uncounted repetition" warning)))))
(should (equal (xr-lint "a\\{\\}")
'(((1 4 "Implicit zero repetition" warning)))))
(should (equal (xr-lint "\\'*\\<?\\(?:$\\)+")
- '(((2 2 "Repetition of zero-width assertion" warning))
- ((5 5 "Optional zero-width assertion" warning))
- ((13 13 "Repetition of zero-width assertion" warning)))))
+ '(((2 2 "Repetition of zero-width assertion" warning)
+ (0 1 "Zero-width assertion here" info))
+ ((5 5 "Optional zero-width assertion" warning)
+ (3 4 "Zero-width assertion here" info))
+ ((13 13 "Repetition of zero-width assertion" warning)
+ (6 12 "Zero-width assertion here" info)))))
(should
(equal
(xr-lint "\\b\\{2\\}\\(a\\|\\|b\\)\\{,8\\}")
- '(((2 6 "Repetition of zero-width assertion" warning))
- ((17 22 "Repetition of expression matching an empty string"
warning)))))
+ '(((2 6 "Repetition of zero-width assertion" warning)
+ (0 1 "Zero-width assertion here" info))
+ ((17 22 "Repetition of expression matching an empty string" warning)
+ (7 16 "This expression matches an empty string" info)))))
(should (equal (xr-lint "\\(?:\\`\\)*")
- '(((8 8 "Repetition of zero-width assertion" warning)))))
+ '(((8 8 "Repetition of zero-width assertion" warning)
+ (0 7 "Zero-width assertion here" info)))))
(should (equal (xr-lint "\\(?:\\`\\)\\{3,4\\}")
- '(((8 14 "Repetition of zero-width assertion" warning)))))
+ '(((8 14 "Repetition of zero-width assertion" warning)
+ (0 7 "Zero-width assertion here" info)))))
))
(ert-deftest xr-lint-char-alt ()
@@ -472,22 +492,30 @@
nil))
(should
(equal (xr-lint "a[\\\\[]b[d-g.d-g]c")
- '(((3 3 "Duplicated `\\' inside character alternative" warning))
- ((12 14 "Duplicated `d-g' inside character alternative"
warning)))))
+ '(((3 3 "Duplicated `\\' inside character alternative" warning)
+ (2 2 "Previous occurrence here" info))
+ ((12 14 "Duplicated `d-g' inside character alternative" warning)
+ (8 10 "Previous occurrence here" info)))))
(should (equal (xr-lint "[]-Qa-fz-t]")
'(((1 3 "Reversed range `]-Q' matches nothing" warning))
((7 9 "Reversed range `z-t' matches nothing" warning)))))
(should (equal (xr-lint "[z-a][^z-a]")
nil))
(should (equal (xr-lint "[^A-FFGI-LI-Mb-da-eg-ki-ns-t33-7]")
- '(((5 5 "Character `F' included in range `A-F'" warning))
- ((10 12 "Ranges `I-L' and `I-M' overlap" warning))
- ((16 18 "Ranges `a-e' and `b-d' overlap" warning))
- ((22 24 "Ranges `g-k' and `i-n' overlap" warning))
+ '(((5 5 "Character `F' included in range `A-F'" warning)
+ (2 4 "Previous occurrence here" info))
+ ((10 12 "Ranges `I-L' and `I-M' overlap" warning)
+ (7 9 "Previous occurrence here" info))
+ ((16 18 "Ranges `a-e' and `b-d' overlap" warning)
+ (13 15 "Previous occurrence here" info))
+ ((22 24 "Ranges `g-k' and `i-n' overlap" warning)
+ (19 21 "Previous occurrence here" info))
((25 27 "Two-character range `s-t'" warning))
- ((29 31 "Range `3-7' includes character `3'" warning)))))
+ ((29 31 "Range `3-7' includes character `3'" warning)
+ (28 28 "Previous occurrence here" info)))))
(should (equal (xr-lint "[a[:digit:]b[:punct:]c[:digit:]]")
- '(((22 30 "Duplicated character class `[:digit:]'"
warning)))))
+ '(((22 30 "Duplicated character class `[:digit:]'" warning)
+ (2 10 "Previous occurrence here" info)))))
(should (equal (xr-lint "[0-9[|]*/]")
'(((4 4 "Suspect `[' in char alternative" warning)))))
(should (equal (xr-lint "[^][-].]")
@@ -507,10 +535,12 @@
;; the gap 80..3fff7f is excluded.
(should (equal (xr-lint "[\x70-\x8f∃]") nil))
(should (equal (xr-lint "[\x70-\x8f\x7e-å]")
- '(((4 6 "Ranges `\x70-\\x7f' and `\x7e-å' overlap"
warning)))))
+ '(((4 6 "Ranges `\x70-\\x7f' and `\x7e-å' overlap" warning)
+ (1 3 "Previous occurrence here" info)))))
(should
(equal (xr-lint "[\x70-\x8få-\x82]")
- '(((4 6 "Ranges `å-\\x82' and `\\x80-\\x8f' overlap" warning)))))
+ '(((4 6 "Ranges `å-\\x82' and `\\x80-\\x8f' overlap" warning)
+ (1 3 "Previous occurrence here" info)))))
(should
(equal (xr-lint "[A-z]")
'(((1 3 "Range `A-z' between upper and lower case includes symbols"
@@ -562,73 +592,91 @@
(should
(equal
(xr-lint "\\(?:a*b?\\)*\\(c\\|d\\|\\)+\\(^\\|e\\)*\\(?:\\)*")
- '(((10 10 "Repetition of expression matching an empty string" warning))
- ((21 21 "Repetition of expression matching an empty string"
warning)))))
+ '(((10 10 "Repetition of expression matching an empty string" warning)
+ (0 9 "This expression matches an empty string" info))
+ ((21 21 "Repetition of expression matching an empty string" warning)
+ (11 20 "This expression matches an empty string" info)))))
(should
(equal
(xr-lint "\\(?:a*?b??\\)+?")
- '(((12 13 "Repetition of expression matching an empty string"
warning)))))
+ '(((12 13 "Repetition of expression matching an empty string" warning)
+ (0 11 "This expression matches an empty string" info)))))
(should
(equal (xr-lint "\\(?:a*b?\\)?")
- '(((10 10 "Optional expression matching an empty string"
- warning)))))))
+ '(((10 10 "Optional expression matching an empty string" warning)
+ (0 9 "This expression matches an empty string" info)))))))
(ert-deftest xr-lint-branch-subsumption ()
(let ((text-quoting-style 'grave))
(should
(equal (xr-lint "a.cde*f?g\\|g\\|abcdefg")
- '(((14 20 "Branch matches subset of a previous branch" warning)))))
+ '(((14 20 "Branch matches subset of a previous branch" warning)
+ (0 8 "This is the superset branch" info)))))
(should
(equal (xr-lint "abcd\\|e\\|[aA].[^0-9z]d")
- '(((9 21 "Branch matches superset of a previous branch"
warning)))))
+ '(((9 21 "Branch matches superset of a previous branch" warning)
+ (0 3 "This is the subset branch" info)))))
(should
(equal (xr-lint "\\(?:\\(a\\)\\|.\\)\\(?:a\\|\\(.\\)\\)")
- '(((21 25 "Branch matches superset of a previous branch"
warning)))))
+ '(((21 25 "Branch matches superset of a previous branch" warning)
+ (18 18 "This is the subset branch" info)))))
(should
(equal (xr-lint ".\\|\n\\|\r")
- '(((6 6 "Branch matches subset of a previous branch" warning)))))
+ '(((6 6 "Branch matches subset of a previous branch" warning)
+ (0 0 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^mM]\\|[^a-zA-Z]")
- '(((7 15 "Branch matches subset of a previous branch" warning)))))
+ '(((7 15 "Branch matches subset of a previous branch" warning)
+ (0 4 "This is the superset branch" info)))))
(should (equal (xr-lint "[^mM]\\|[^A-LN-Z]")
nil))
(should (equal (xr-lint "[ab]\\|[^bcd]")
nil))
(should
(equal (xr-lint "[ab]\\|[^cd]")
- '(((6 10 "Branch matches superset of a previous branch"
warning)))))
+ '(((6 10 "Branch matches superset of a previous branch" warning)
+ (0 3 "This is the subset branch" info)))))
(should (equal (xr-lint ".\\|[a\n]")
nil))
(should
(equal (xr-lint "ab?c+\\|a?b*c*")
- '(((7 12 "Branch matches superset of a previous branch"
warning)))))
+ '(((7 12 "Branch matches superset of a previous branch" warning)
+ (0 4 "This is the subset branch" info)))))
(should
(equal (xr-lint "\\(?:[aA]\\|b\\)\\|a")
- '(((15 15 "Branch matches subset of a previous branch" warning)))))
+ '(((15 15 "Branch matches subset of a previous branch" warning)
+ (0 12 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\(?:a\\|b\\)\\|[abc]")
- '(((12 16 "Branch matches superset of a previous branch"
warning)))))
+ '(((12 16 "Branch matches superset of a previous branch" warning)
+ (0 9 "This is the subset branch" info)))))
(should
(equal (xr-lint "\\(?:a\\|b\\)\\|\\(?:[abd]\\|[abc]\\)")
- '(((12 29 "Branch matches superset of a previous branch"
warning)))))
+ '(((12 29 "Branch matches superset of a previous branch" warning)
+ (0 9 "This is the subset branch" info)))))
(should
(equal (xr-lint "ab\\|abc?")
- '(((4 7 "Branch matches superset of a previous branch" warning)))))
+ '(((4 7 "Branch matches superset of a previous branch" warning)
+ (0 1 "This is the subset branch" info)))))
(should
(equal (xr-lint "abc\\|abcd*e?")
- '(((5 11 "Branch matches superset of a previous branch"
warning)))))
+ '(((5 11 "Branch matches superset of a previous branch" warning)
+ (0 2 "This is the subset branch" info)))))
(should (equal (xr-lint "[a[:digit:]]\\|[a\n]")
nil))
(should
(equal (xr-lint "[a[:ascii:]]\\|[a\n]")
- '(((14 17 "Branch matches subset of a previous branch" warning)))))
+ '(((14 17 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:alnum:]]\\|[[:alpha:]]")
- '(((13 23 "Branch matches subset of a previous branch" warning)))))
+ '(((13 23 "Branch matches subset of a previous branch" warning)
+ (0 10 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:alnum:]%]\\|[[:alpha:]%]")
- '(((14 25 "Branch matches subset of a previous branch" warning)))))
+ '(((14 25 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should (equal (xr-lint "[[:xdigit:]%]\\|[[:alpha:]%]")
nil))
(should (equal (xr-lint "[[:alnum:]]\\|[^[:alpha:]]")
@@ -637,13 +685,16 @@
nil))
(should
(equal (xr-lint "[[:digit:]]\\|[^[:punct:]]")
- '(((13 24 "Branch matches superset of a previous branch"
warning)))))
+ '(((13 24 "Branch matches superset of a previous branch" warning)
+ (0 10 "This is the subset branch" info)))))
(should
(equal (xr-lint "[^[:digit:]]\\|[[:punct:]]")
- '(((14 24 "Branch matches subset of a previous branch" warning)))))
+ '(((14 24 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^[:digit:]]\\|[^[:xdigit:]]")
- '(((14 26 "Branch matches subset of a previous branch" warning)))))
+ '(((14 26 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should (equal (xr-lint "[^[:print:]]\\|[[:ascii:]]")
nil))
(should (equal (xr-lint "[[:print:]]\\|[^[:ascii:]]")
@@ -652,144 +703,203 @@
nil))
(should
(equal (xr-lint "[[:digit:][:cntrl:]]\\|[[:ascii:]]")
- '(((22 32 "Branch matches superset of a previous branch"
warning)))))
+ '(((22 32 "Branch matches superset of a previous branch" warning)
+ (0 19 "This is the subset branch" info)))))
(should
(equal (xr-lint "[[:alpha:]]\\|A")
- '(((13 13 "Branch matches subset of a previous branch" warning)))))
+ '(((13 13 "Branch matches subset of a previous branch" warning)
+ (0 10 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:alpha:]]\\|[A-E]")
- '(((13 17 "Branch matches subset of a previous branch" warning)))))
+ '(((13 17 "Branch matches subset of a previous branch" warning)
+ (0 10 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:alpha:]3-7]\\|[A-E46]")
- '(((16 22 "Branch matches subset of a previous branch" warning)))))
+ '(((16 22 "Branch matches subset of a previous branch" warning)
+ (0 13 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^[:alpha:]]\\|[123]")
- '(((14 18 "Branch matches subset of a previous branch" warning)))))
+ '(((14 18 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should
(equal (xr-lint "[!-@]\\|[[:digit:]]")
- '(((7 17 "Branch matches subset of a previous branch" warning)))))
+ '(((7 17 "Branch matches subset of a previous branch" warning)
+ (0 4 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^a-z]\\|[[:digit:]]")
- '(((8 18 "Branch matches subset of a previous branch" warning)))))
+ '(((8 18 "Branch matches subset of a previous branch" warning)
+ (0 5 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^[:punct:]]\\|[a-z]")
- '(((14 18 "Branch matches subset of a previous branch" warning)))))
+ '(((14 18 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:space:]]\\|[ \t\f]")
- '(((13 17 "Branch matches subset of a previous branch" warning)))))
+ '(((13 17 "Branch matches subset of a previous branch" warning)
+ (0 10 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:word:]]\\|[a-gH-P2357]")
- '(((12 23 "Branch matches subset of a previous branch" warning)))))
+ '(((12 23 "Branch matches subset of a previous branch" warning)
+ (0 9 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^[:space:]]\\|[a-gH-P2357]")
- '(((14 25 "Branch matches subset of a previous branch" warning)))))
+ '(((14 25 "Branch matches subset of a previous branch" warning)
+ (0 11 "This is the superset branch" info)))))
(should
(equal (xr-lint "[^z-a]\\|[^0-9[:space:]]")
- '(((8 22 "Branch matches subset of a previous branch" warning)))))
+ '(((8 22 "Branch matches subset of a previous branch" warning)
+ (0 5 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\(?:.\\|\n\\)\\|a")
- '(((12 12 "Branch matches subset of a previous branch" warning)))))
+ '(((12 12 "Branch matches subset of a previous branch" warning)
+ (0 9 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\s-\\| ")
- '(((5 5 "Branch matches subset of a previous branch" warning)))))
+ '(((5 5 "Branch matches subset of a previous branch" warning)
+ (0 2 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\S-\\|x")
- '(((5 5 "Branch matches subset of a previous branch" warning)))))
+ '(((5 5 "Branch matches subset of a previous branch" warning)
+ (0 2 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\cl\\|å")
- '(((5 5 "Branch matches subset of a previous branch" warning)))))
+ '(((5 5 "Branch matches subset of a previous branch" warning)
+ (0 2 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\Ca\\|ü")
- '(((5 5 "Branch matches subset of a previous branch" warning)))))
+ '(((5 5 "Branch matches subset of a previous branch" warning)
+ (0 2 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\w\\|[^z-a]")
- '(((4 9 "Branch matches superset of a previous branch" warning)))))
+ '(((4 9 "Branch matches superset of a previous branch" warning)
+ (0 1 "This is the subset branch" info)))))
(should
(equal (xr-lint "\\W\\|[^z-a]")
- '(((4 9 "Branch matches superset of a previous branch" warning)))))
+ '(((4 9 "Branch matches superset of a previous branch" warning)
+ (0 1 "This is the subset branch" info)))))
(should
(equal (xr-lint "\\w\\|a")
- '(((4 4 "Branch matches subset of a previous branch" warning)))))
+ '(((4 4 "Branch matches subset of a previous branch" warning)
+ (0 1 "This is the superset branch" info)))))
(should
(equal (xr-lint "\\W\\|\f")
- '(((4 4 "Branch matches subset of a previous branch" warning)))))
+ '(((4 4 "Branch matches subset of a previous branch" warning)
+ (0 1 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:punct:]]\\|!")
- '(((13 13 "Branch matches subset of a previous branch" warning)))))
+ '(((13 13 "Branch matches subset of a previous branch" warning)
+ (0 10 "This is the superset branch" info)))))
(should
(equal (xr-lint "[[:ascii:]]\\|[^α-ω]")
- '(((13 18 "Branch matches superset of a previous branch"
warning)))))
+ '(((13 18 "Branch matches superset of a previous branch" warning)
+ (0 10 "This is the subset branch" info)))))
(should
(equal (xr-lint "[^a-f]\\|[h-z]")
- '(((8 12 "Branch matches subset of a previous branch" warning)))))
+ '(((8 12 "Branch matches subset of a previous branch" warning)
+ (0 5 "This is the superset branch" info)))))
(should
(equal (xr-lint "[0-9]\\|\\S(")
- '(((7 9 "Branch matches superset of a previous branch" warning)))))
+ '(((7 9 "Branch matches superset of a previous branch" warning)
+ (0 4 "This is the subset branch" info)))))
(should
(equal (xr-lint "a+\\|[ab]+")
- '(((4 8 "Branch matches superset of a previous branch" warning)))))
+ '(((4 8 "Branch matches superset of a previous branch" warning)
+ (0 1 "This is the subset branch" info)))))
(should
(equal (xr-lint "[ab]?\\|a?")
- '(((7 8 "Branch matches subset of a previous branch" warning)))))
+ '(((7 8 "Branch matches subset of a previous branch" warning)
+ (0 4 "This is the superset branch" info)))))
))
(ert-deftest xr-lint-subsumed-repetition ()
(let ((text-quoting-style 'grave))
(should
(equal (xr-lint "\\(?:a.c\\|def\\)+\\(?:abc\\)*")
- '(((15 24 "Repetition subsumed by preceding repetition"
warning)))))
+ '(((15 24 "Repetition subsumed by preceding repetition" warning)
+ (0 14 "Subsuming repetition here" info)))))
;; Exhaustive test of all possible combinations.
(should
(equal (xr-lint "[ab]+a?,a?[ab]+,[ab]+a*,a*[ab]+")
- '(((5 6 "Repetition subsumed by preceding repetition" warning))
- ((10 14 "Repetition subsumes preceding repetition" warning))
- ((21 22 "Repetition subsumed by preceding repetition" warning))
- ((26 30 "Repetition subsumes preceding repetition" warning)))))
+ '(((5 6 "Repetition subsumed by preceding repetition" warning)
+ (0 4 "Subsuming repetition here" info))
+ ((10 14 "Repetition subsumes preceding repetition" warning)
+ (8 9 "Subsumed repetition here" info))
+ ((21 22 "Repetition subsumed by preceding repetition" warning)
+ (16 20 "Subsuming repetition here" info))
+ ((26 30 "Repetition subsumes preceding repetition" warning)
+ (24 25 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "[ab]*a?,a?[ab]*,[ab]*a*,a*[ab]*")
- '(((5 6 "Repetition subsumed by preceding repetition" warning))
- ((10 14 "Repetition subsumes preceding repetition" warning))
- ((21 22 "Repetition subsumed by preceding repetition" warning))
- ((26 30 "Repetition subsumes preceding repetition" warning)))))
+ '(((5 6 "Repetition subsumed by preceding repetition" warning)
+ (0 4 "Subsuming repetition here" info))
+ ((10 14 "Repetition subsumes preceding repetition" warning)
+ (8 9 "Subsumed repetition here" info))
+ ((21 22 "Repetition subsumed by preceding repetition" warning)
+ (16 20 "Subsuming repetition here" info))
+ ((26 30 "Repetition subsumes preceding repetition" warning)
+ (24 25 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "a+a?,a?a+,a+a*,a*a+,a*a?,a?a*,a*a*")
- '(((2 3 "Repetition subsumed by preceding repetition" warning))
- ((7 8 "Repetition subsumes preceding repetition" warning))
- ((12 13 "Repetition subsumed by preceding repetition" warning))
- ((17 18 "Repetition subsumes preceding repetition" warning))
- ((22 23 "Repetition subsumed by preceding repetition" warning))
- ((27 28 "Repetition subsumes preceding repetition" warning))
- ((32 33 "Repetition subsumed by preceding repetition"
warning)))))
+ '(((2 3 "Repetition subsumed by preceding repetition" warning)
+ (0 1 "Subsuming repetition here" info))
+ ((7 8 "Repetition subsumes preceding repetition" warning)
+ (5 6 "Subsumed repetition here" info))
+ ((12 13 "Repetition subsumed by preceding repetition" warning)
+ (10 11 "Subsuming repetition here" info))
+ ((17 18 "Repetition subsumes preceding repetition" warning)
+ (15 16 "Subsumed repetition here" info))
+ ((22 23 "Repetition subsumed by preceding repetition" warning)
+ (20 21 "Subsuming repetition here" info))
+ ((27 28 "Repetition subsumes preceding repetition" warning)
+ (25 26 "Subsumed repetition here" info))
+ ((32 33 "Repetition subsumed by preceding repetition" warning)
+ (30 31 "Subsuming repetition here" info)))))
(should
(equal (xr-lint "[ab]+a??,a??[ab]+,[ab]+a*?,a*?[ab]+")
- '(((5 7 "Repetition subsumed by preceding repetition" warning))
- ((12 16 "Repetition subsumes preceding repetition" warning))
- ((23 25 "Repetition subsumed by preceding repetition" warning))
- ((30 34 "Repetition subsumes preceding repetition" warning)))))
+ '(((5 7 "Repetition subsumed by preceding repetition" warning)
+ (0 4 "Subsuming repetition here" info))
+ ((12 16 "Repetition subsumes preceding repetition" warning)
+ (9 11 "Subsumed repetition here" info))
+ ((23 25 "Repetition subsumed by preceding repetition" warning)
+ (18 22 "Subsuming repetition here" info))
+ ((30 34 "Repetition subsumes preceding repetition" warning)
+ (27 29 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "[ab]*a??,a??[ab]*,[ab]*a*?,a*?[ab]*")
- '(((5 7 "Repetition subsumed by preceding repetition" warning))
- ((12 16 "Repetition subsumes preceding repetition" warning))
- ((23 25 "Repetition subsumed by preceding repetition" warning))
- ((30 34 "Repetition subsumes preceding repetition" warning)))))
+ '(((5 7 "Repetition subsumed by preceding repetition" warning)
+ (0 4 "Subsuming repetition here" info))
+ ((12 16 "Repetition subsumes preceding repetition" warning)
+ (9 11 "Subsumed repetition here" info))
+ ((23 25 "Repetition subsumed by preceding repetition" warning)
+ (18 22 "Subsuming repetition here" info))
+ ((30 34 "Repetition subsumes preceding repetition" warning)
+ (27 29 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "a+a??,a??a+,a+a*?,a*?a+,a*a??,a??a*,a*a*?,a*?a*")
- '(((2 4 "Repetition subsumed by preceding repetition" warning))
- ((9 10 "Repetition subsumes preceding repetition" warning))
- ((14 16 "Repetition subsumed by preceding repetition" warning))
- ((21 22 "Repetition subsumes preceding repetition" warning))
- ((26 28 "Repetition subsumed by preceding repetition" warning))
- ((33 34 "Repetition subsumes preceding repetition" warning))
- ((38 40 "Repetition subsumed by preceding repetition" warning))
- ((45 46 "Repetition subsumes preceding repetition" warning)))))
+ '(((2 4 "Repetition subsumed by preceding repetition" warning)
+ (0 1 "Subsuming repetition here" info))
+ ((9 10 "Repetition subsumes preceding repetition" warning)
+ (6 8 "Subsumed repetition here" info))
+ ((14 16 "Repetition subsumed by preceding repetition" warning)
+ (12 13 "Subsuming repetition here" info))
+ ((21 22 "Repetition subsumes preceding repetition" warning)
+ (18 20 "Subsumed repetition here" info))
+ ((26 28 "Repetition subsumed by preceding repetition" warning)
+ (24 25 "Subsuming repetition here" info))
+ ((33 34 "Repetition subsumes preceding repetition" warning)
+ (30 32 "Subsumed repetition here" info))
+ ((38 40 "Repetition subsumed by preceding repetition" warning)
+ (36 37 "Subsuming repetition here" info))
+ ((45 46 "Repetition subsumes preceding repetition" warning)
+ (42 44 "Subsumed repetition here" info)))))
(should (equal (xr-lint "[ab]+?a?,a?[ab]+?,[ab]+?a*,a*[ab]+?")
nil))
@@ -799,32 +909,49 @@
(should
(equal (xr-lint "a+?a?,a?a+?,a+?a*,a*a+?,a*?a?,a?a*?,a*?a*,a*a*?")
- '(((39 40 "Repetition subsumes preceding repetition" warning))
- ((44 46 "Repetition subsumed by preceding repetition"
warning)))))
+ '(((39 40 "Repetition subsumes preceding repetition" warning)
+ (36 38 "Subsumed repetition here" info))
+ ((44 46 "Repetition subsumed by preceding repetition" warning)
+ (42 43 "Subsuming repetition here" info)))))
(should
(equal (xr-lint "[ab]+?a??,a??[ab]+?,[ab]+?a*?,a*?[ab]+?")
- '(((6 8 "Repetition subsumed by preceding repetition" warning))
- ((13 18 "Repetition subsumes preceding repetition" warning))
- ((26 28 "Repetition subsumed by preceding repetition" warning))
- ((33 38"Repetition subsumes preceding repetition" warning)))))
+ '(((6 8 "Repetition subsumed by preceding repetition" warning)
+ (0 5 "Subsuming repetition here" info))
+ ((13 18 "Repetition subsumes preceding repetition" warning)
+ (10 12 "Subsumed repetition here" info))
+ ((26 28 "Repetition subsumed by preceding repetition" warning)
+ (20 25 "Subsuming repetition here" info))
+ ((33 38"Repetition subsumes preceding repetition" warning)
+ (30 32 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "[ab]*?a??,a??[ab]*?,[ab]*?a*?,a*?[ab]*?")
- '(((6 8 "Repetition subsumed by preceding repetition" warning))
- ((13 18 "Repetition subsumes preceding repetition" warning))
- ((26 28 "Repetition subsumed by preceding repetition" warning))
- ((33 38 "Repetition subsumes preceding repetition" warning)))))
+ '(((6 8 "Repetition subsumed by preceding repetition" warning)
+ (0 5 "Subsuming repetition here" info))
+ ((13 18 "Repetition subsumes preceding repetition" warning)
+ (10 12 "Subsumed repetition here" info))
+ ((26 28 "Repetition subsumed by preceding repetition" warning)
+ (20 25 "Subsuming repetition here" info))
+ ((33 38 "Repetition subsumes preceding repetition" warning)
+ (30 32 "Subsumed repetition here" info)))))
(should
(equal (xr-lint "a+?a??,a??a+?,a+?a*?,a*?a+?,a*?a??,a??a*?,a*?a*?")
- '(((3 5 "Repetition subsumed by preceding repetition" warning))
- ((10 12 "Repetition subsumes preceding repetition" warning))
- ((17 19 "Repetition subsumed by preceding repetition" warning))
- ((24 26 "Repetition subsumes preceding repetition" warning))
- ((31 33 "Repetition subsumed by preceding repetition" warning))
- ((38 40 "Repetition subsumes preceding repetition" warning))
- ((45 47 "Repetition subsumed by preceding repetition"
warning)))))
+ '(((3 5 "Repetition subsumed by preceding repetition" warning)
+ (0 2 "Subsuming repetition here" info))
+ ((10 12 "Repetition subsumes preceding repetition" warning)
+ (7 9 "Subsumed repetition here" info))
+ ((17 19 "Repetition subsumed by preceding repetition" warning)
+ (14 16 "Subsuming repetition here" info))
+ ((24 26 "Repetition subsumes preceding repetition" warning)
+ (21 23 "Subsumed repetition here" info))
+ ((31 33 "Repetition subsumed by preceding repetition" warning)
+ (28 30 "Subsuming repetition here" info))
+ ((38 40 "Repetition subsumes preceding repetition" warning)
+ (35 37 "Subsumed repetition here" info))
+ ((45 47 "Repetition subsumed by preceding repetition" warning)
+ (42 44 "Subsuming repetition here" info)))))
))
(ert-deftest xr-lint-wrapped-subsumption ()
@@ -832,56 +959,70 @@
(should
(equal
(xr-lint "\\(?:a*x[ab]+\\)*")
- '(((14 14
- "Last item in repetition subsumes first item (wrapped)"
warning)))))
+ '(((0 14
+ "Last item in repetition subsumes first item (wrapped)" warning)))))
(should
(equal
(xr-lint "\\([ab]*xya?\\)+")
- '(((13 13
- "First item in repetition subsumes last item (wrapped)"
warning)))))
+ '(((0 13
+ "First item in repetition subsumes last item (wrapped)" warning)))))
(should
(equal
(xr-lint "\\(?3:a*xa*\\)\\{7\\}")
- '(((12 16
- "Last item in repetition subsumes first item (wrapped)"
warning)))))
+ '(((0 16
+ "Last item in repetition subsumes first item (wrapped)" warning)))))
))
(ert-deftest xr-lint-bad-anchor ()
(let ((text-quoting-style 'grave))
(should (equal (xr-lint "a\\(?:^\\)")
- '(((1 7 "Line-start anchor follows non-newline" warning)))))
+ '(((1 7 "Line-start anchor follows non-newline" warning)
+ (0 0 "This matches a non-newline at the end" info)))))
(should (equal (xr-lint "a?\\(?:^\\)")
- '(((2 8 "Line-start anchor follows non-newline" warning)))))
+ '(((2 8 "Line-start anchor follows non-newline" warning)
+ (0 1 "This matches a non-newline at the end" info)))))
(should (equal (xr-lint "a\\(?:^\\|b\\)")
- '(((1 10 "Line-start anchor follows non-newline"
warning)))))
+ '(((1 10 "Line-start anchor follows non-newline" warning)
+ (0 0 "This matches a non-newline at the end" info)))))
(should (equal (xr-lint "a?\\(?:^\\|b\\)")
nil))
(should (equal (xr-lint "\\(?:$\\)a")
- '(((7 7 "Non-newline follows end-of-line anchor"
warning)))))
+ '(((7 7 "Non-newline follows end-of-line anchor" warning)
+ (0 6 "This matches at the end of a line" info)))))
(should (equal (xr-lint "\\(?:$\\)\\(\n\\|a\\)")
- '(((7 14 "Non-newline follows end-of-line anchor"
warning)))))
+ '(((7 14 "Non-newline follows end-of-line anchor" warning)
+ (0 6 "This matches at the end of a line" info)))))
(should (equal (xr-lint "\\(?:$\\|b\\)a")
- '(((10 10 "Non-newline follows end-of-line anchor"
warning)))))
+ '(((10 10 "Non-newline follows end-of-line anchor" warning)
+ (0 9 "This matches at the end of a line" info)))))
(should (equal (xr-lint "\\(?:$\\|b\\)\\(\n\\|a\\)")
nil))
(should (equal (xr-lint "\\(?3:$\\)[ab]\\(?2:^\\)")
- '(((8 11 "Non-newline follows end-of-line anchor" warning))
- ((12 19 "Line-start anchor follows non-newline"
warning)))))
+ '(((8 11 "Non-newline follows end-of-line anchor" warning)
+ (0 7 "This matches at the end of a line" info))
+ ((12 19 "Line-start anchor follows non-newline" warning)
+ (8 11 "This matches a non-newline at the end" info)))))
(should (equal (xr-lint ".\\(?:^$\\).")
- '(((1 8 "Line-start anchor follows non-newline" warning))
- ((9 9 "Non-newline follows end-of-line anchor"
warning)))))
+ '(((1 8 "Line-start anchor follows non-newline" warning)
+ (0 0 "This matches a non-newline at the end" info))
+ ((9 9 "Non-newline follows end-of-line anchor" warning)
+ (1 8 "This matches at the end of a line" info)))))
(should
(equal (xr-lint "\\'b")
- '(((2 2 "Non-empty pattern follows end-of-text anchor" warning)))))
+ '(((2 2 "Non-empty pattern follows end-of-text anchor" warning)
+ (0 1 "This matches at the end of the text" info)))))
(should
(equal (xr-lint "\\'b?")
- '(((2 3 "Non-empty pattern follows end-of-text anchor" warning)))))
- (should (equal (xr-lint "\\(?:a\\|\\'\\)b")
- '(((11 11
- "Non-empty pattern follows end-of-text anchor"
warning)))))
+ '(((2 3 "Non-empty pattern follows end-of-text anchor" warning)
+ (0 1 "This matches at the end of the text" info)))))
+ (should (equal
+ (xr-lint "\\(?:a\\|\\'\\)b")
+ '(((11 11 "Non-empty pattern follows end-of-text anchor" warning)
+ (0 10 "This matches at the end of the text" info)))))
(should
(equal (xr-lint "\\'\\(a\\|b?\\)")
- '(((2 10 "Non-empty pattern follows end-of-text anchor"
warning)))))
+ '(((2 10 "Non-empty pattern follows end-of-text anchor" warning)
+ (0 1 "This matches at the end of the text" info)))))
(should (equal (xr-lint "\\(?:a\\|\\'\\)b?")
nil))
))
@@ -955,9 +1096,12 @@
'(((7 9 "Ranges `A-F' and `D-K' overlap" warning))
((10 12 "Two-element range `M-N'" warning))
((14 16 "Range `3-7' includes character `3'" warning))
- ((17 17 "Duplicated character `!'" warning))
+ ((17 18 "Duplicated character `!'" warning))
((17 18 "Unnecessarily escaped `!'" warning))
((19 19 "Character `b' included in range `a-z'"
warning)))))
+ (should (equal (xr-skip-set-lint "0a\\--\\\\n")
+ '(((2 6 "Range `--\\' includes character `0'" warning)))))
+
(should (equal (xr-skip-set-lint "!-\\$")
'(((2 3 "Unnecessarily escaped `$'" warning)))))
(should (equal (xr-skip-set-lint "[^a-z]")
diff --git a/xr.el b/xr.el
index e6fa327d5d..9c763a3376 100644
--- a/xr.el
+++ b/xr.el
@@ -126,12 +126,17 @@ END is nil if unknown."
(xr--error idx (1+ i)
"No character class `[:%s:]'"
(symbol-name sym)))
- (if (memq sym classes)
- (xr--warn
- warnings idx (1+ i)
- (format-message
- "Duplicated character class `[:%s:]'" sym))
- (push sym classes))
+ (let ((prev (assq sym classes)))
+ (if prev
+ (let* ((prev-beg (cdr prev))
+ (prev-end (1+ (xr--string-search
+ ":]" string prev-beg))))
+ (xr--warn
+ warnings idx (1+ i)
+ (format-message
+ "Duplicated character class `[:%s:]'" sym)
+ prev-beg prev-end "Previous occurrence here"))
+ (push (cons sym idx) classes)))
(setq idx (+ i 2))
t)))))
;; character range
@@ -259,12 +264,13 @@ END is nil if unknown."
;; Duplicate character: drop it and warn.
((and (eq (aref a 0) (aref a 1))
(eq (aref b 0) (aref b 1)))
- (xr--warn
- warnings (aref b 2) (aref b 2)
- (xr--escape-string
- (format-message
- "Duplicated `%c' inside character alternative"
- (aref this 0)))))
+ (xr--warn warnings
+ (aref b 2) (aref b 2)
+ (xr--escape-string
+ (format-message
+ "Duplicated `%c' inside character alternative"
+ (aref this 0)))
+ (aref a 2) (aref a 2) "Previous occurrence here"))
;; Duplicate range: drop it and warn.
((and (eq (aref a 0) (aref b 0))
(eq (aref a 1) (aref b 1)))
@@ -273,7 +279,8 @@ END is nil if unknown."
(xr--escape-string
(format-message
"Duplicated `%c-%c' inside character alternative"
- (aref b 0) (aref b 1)))))
+ (aref b 0) (aref b 1)))
+ (aref a 2) (+ (aref a 2) 2) "Previous occurrence here"))
;; Character in range: drop it and warn.
((eq (aref a 0) (aref a 1))
(when (eq a this)
@@ -283,7 +290,8 @@ END is nil if unknown."
(xr--escape-string
(format-message
"Range `%c-%c' includes character `%c'"
- (aref b 0) (aref b 1) (aref a 0)))))
+ (aref b 0) (aref b 1) (aref a 0)))
+ (aref a 2) (aref a 2) "Previous occurrence here"))
;; Same but other way around.
((eq (aref b 0) (aref b 1))
(when (eq b this)
@@ -293,7 +301,8 @@ END is nil if unknown."
(xr--escape-string
(format-message
"Character `%c' included in range `%c-%c'"
- (aref b 0) (aref a 0) (aref a 1)))))
+ (aref b 0) (aref a 0) (aref a 1)))
+ (aref a 2) (+ (aref a 2) 2) "Previous occurrence here"))
;; Overlapping ranges: merge and warn.
(t
(let ((this-end (aref this 1)))
@@ -303,7 +312,8 @@ END is nil if unknown."
(xr--escape-string
(format-message "Ranges `%c-%c' and `%c-%c' overlap"
(aref this 0) this-end
- (aref next 0) (aref next 1)))))))
+ (aref next 0) (aref next 1)))
+ (aref a 2) (+ (aref a 2) 2) "Previous occurrence here"))))
(setcdr s (cddr s)))
;; No overlap.
(setq s (cdr s)))))
@@ -341,8 +351,8 @@ END is nil if unknown."
(null chars)
(null ranges))
(if negated
- (list 'not (car classes))
- (car classes)))
+ (list 'not (caar classes))
+ (caar classes)))
;; [^\n]: nonl.
((and negated
(equal chars '(?\n))
@@ -360,7 +370,7 @@ END is nil if unknown."
(list (apply #'concat (nreverse ranges))))
(and chars
(list (apply #'string (nreverse chars))))
- (nreverse classes)))))
+ (nreverse (mapcar #'car classes))))))
(if negated
(list 'not set)
set))))))))
@@ -579,6 +589,8 @@ like (* (* X) ... (* X))."
(last (car (last operands)))
(subsumption (xr--adjacent-subsumption last first)))
(when subsumption
+ ;; FIXME: add info about first and last item.
+ ;; How do we get their locations?
(xr--warn
warnings beg end
(if (eq subsumption 'b-subsumes-a)
@@ -680,29 +692,38 @@ like (* (* X) ... (* X))."
(memq inner-op '(one-or-more +?)))))
(let ((outer-opt (eq operator-char ??))
(inner-opt (memq inner-op '(opt ??))))
- (xr--warn warnings idx end-idx
- (if outer-opt
- (if inner-opt
- "Optional option"
- "Optional repetition")
- (if inner-opt
- "Repetition of option"
- "Repetition of repetition")))))
+ (xr--warn warnings
+ idx end-idx
+ (if outer-opt
+ (if inner-opt
+ "Optional option"
+ "Optional repetition")
+ (if inner-opt
+ "Repetition of option"
+ "Repetition of repetition"))
+ (cadr locations) (1- idx)
+ "This is the inner expression")))
((memq operand xr--zero-width-assertions)
- (xr--warn warnings idx end-idx
- (if (eq operator-char ??)
- "Optional zero-width assertion"
- "Repetition of zero-width assertion")))
+ (xr--warn warnings
+ idx end-idx
+ (if (eq operator-char ??)
+ "Optional zero-width assertion"
+ "Repetition of zero-width assertion")
+ (cadr locations) (1- idx)
+ "Zero-width assertion here"))
((and (xr--matches-empty-p operand)
;; Rejecting repetition of the empty string
;; suppresses some false positives.
(not (equal operand "")))
- (xr--warn warnings idx end-idx
- (concat
- (if (eq operator-char ??)
- "Optional expression"
- "Repetition of expression")
- " matching an empty string")))
+ (xr--warn warnings
+ idx end-idx
+ (concat
+ (if (eq operator-char ??)
+ "Optional expression"
+ "Repetition of expression")
+ " matching an empty string")
+ (cadr locations) (1- idx)
+ "This expression matches an empty string"))
((and (memq operator-char '(?* ?+))
(consp operand)
(memq (car operand) '(seq group))
@@ -717,12 +738,15 @@ like (* (* X) ... (* X))."
(memq (caar nonzero-items)
'( opt zero-or-more one-or-more
+? *? ?? >=)))))
- (xr--warn warnings idx end-idx
- "Repetition of effective repetition"))))
+ (xr--warn warnings
+ idx end-idx
+ "Repetition of effective repetition"
+ (cadr locations) (1- idx)
+ "This expression contains a repetition"))))
;; (* (* X) ... (* X)) etc: wrap-around subsumption
(unless (eq operator-char ??)
(xr--check-wrap-around-repetition
- operand idx end-idx warnings)))
+ operand (cadr locations) end-idx warnings)))
(setq idx (1+ end-idx))
(setq sequence (cons (xr--postfix operator-char lazy operand)
(cdr sequence)))
@@ -863,7 +887,7 @@ like (* (* X) ... (* X))."
(when warnings
(when (or (not upper) (>= upper 2))
(xr--check-wrap-around-repetition
- operand item-start (1- idx) warnings))
+ operand (cadr locations) (1- idx) warnings))
(cond
((and (consp operand)
@@ -884,21 +908,28 @@ like (* (* X) ... (* X))."
(and (eq (car operand) 'group)
(memq (caadr operand)
'(opt ??))))))
- (xr--warn warnings item-start (1- idx)
- (if inner-opt
- "Repetition of option"
- "Repetition of repetition"))))
+ (xr--warn warnings
+ item-start (1- idx)
+ (if inner-opt
+ "Repetition of option"
+ "Repetition of repetition")
+ (cadr locations) (1- item-start)
+ "This is the inner expression")))
((memq operand xr--zero-width-assertions)
- (xr--warn warnings item-start (1- idx)
- "Repetition of zero-width assertion"))
+ (xr--warn warnings
+ item-start (1- idx)
+ "Repetition of zero-width assertion"
+ (cadr locations) (1- item-start)
+ "Zero-width assertion here"))
((and (xr--matches-empty-p operand)
;; Rejecting repetition of the empty string
;; suppresses some false positives.
(not (equal operand "")))
(xr--warn
warnings item-start (1- idx)
- "Repetition of expression matching an empty
string"))))
-
+ "Repetition of expression matching an empty string"
+ (cadr locations) (1- item-start)
+ "This expression matches an empty string"))))
(setq sequence (cons (xr--repeat lower upper operand)
(cdr sequence)))
(pop locations))))))
@@ -979,9 +1010,9 @@ like (* (* X) ... (* X))."
;; Note that we do not warn about \], since the symmetry with \[
;; makes it unlikely to be a serious error.
(xr--warn warnings item-start (1+ item-start)
- (format-message "Escaped non-special character
`%s'"
- (xr--escape-string
- (char-to-string next-char))))))))
+ (format-message "Escaped non-special character `%s'"
+ (xr--escape-string
+ (char-to-string next-char))))))))
;; nonspecial character
(t
@@ -998,10 +1029,15 @@ like (* (* X) ... (* X))."
(prev-item (cadr sequence))
(subsumption (xr--adjacent-subsumption prev-item item)))
(when subsumption
- (xr--warn warnings (car locations) (1- idx)
- (if (eq subsumption 'a-subsumes-b)
- "Repetition subsumed by preceding repetition"
- "Repetition subsumes preceding repetition")))
+ (xr--warn warnings
+ (car locations) (1- idx)
+ (if (eq subsumption 'a-subsumes-b)
+ "Repetition subsumed by preceding repetition"
+ "Repetition subsumes preceding repetition")
+ (cadr locations) (1- (car locations))
+ (if (eq subsumption 'a-subsumes-b)
+ "Subsuming repetition here"
+ "Subsumed repetition here")))
;; Check for anchors conflicting with previous/next character.
;; To avoid false positives, we require that at least one
@@ -1013,26 +1049,33 @@ like (* (* X) ... (* X))."
(or (eq prev-eol 'always)
(eq this-nonl 'always)))
(xr--warn
- warnings (car locations) (1- idx)
- "Non-newline follows end-of-line anchor")))))
+ warnings
+ (car locations) (1- idx)
+ "Non-newline follows end-of-line anchor"
+ (cadr locations) (1- (car locations))
+ "This matches at the end of a line")))))
(let ((this-bol (xr--starts-with-sym 'bol item)))
(when this-bol
(let ((prev-nonl (xr--ends-with-nonl prev-item)))
(when (and prev-nonl
(or (eq prev-nonl 'always)
(eq this-bol 'always)))
- (xr--warn
- warnings (car locations) (1- idx)
- "Line-start anchor follows non-newline")))))
+ (xr--warn warnings
+ (car locations) (1- idx)
+ "Line-start anchor follows non-newline"
+ (cadr locations) (1- (car locations))
+ "This matches a non-newline at the end")))))
(let ((prev-eos (xr--ends-with-sym 'eos prev-item)))
(when prev-eos
(let ((this-nonempty (xr--matches-nonempty item)))
(when (and this-nonempty
(or (eq prev-eos 'always)
(eq this-nonempty 'always)))
- (xr--warn
- warnings (car locations) (1- idx)
- "Non-empty pattern follows end-of-text anchor")))))
+ (xr--warn warnings
+ (car locations) (1- idx)
+ "Non-empty pattern follows end-of-text anchor"
+ (cadr locations) (1- (car locations))
+ "This matches at the end of the text")))))
;; FIXME: We don't complain about non-empty followed by
;; bos because it may be the start of unmatchable.
@@ -1667,25 +1710,42 @@ A-SETS and B-SETS are arguments to `any'."
(let ((pos xr--idx)
(seq (xr--parse-seq warnings purpose checks)))
(when warnings
- (cond
- ((member seq alternatives)
- (xr--warn warnings pos (1- xr--idx)
- "Duplicated alternative branch"))
- ((xr--some (lambda (branch) (xr--superset-p seq branch))
- alternatives)
- (xr--warn warnings pos (1- xr--idx)
- "Branch matches superset of a previous branch"))
- ((xr--some (lambda (branch) (xr--superset-p branch seq))
- alternatives)
- (xr--warn warnings pos (1- xr--idx)
- "Branch matches subset of a previous branch"))
- ((and (eq checks 'all)
- (xr--char-alt-equivalent-p (car alternatives))
- (xr--char-alt-equivalent-p seq))
+ (let ((alts alternatives)
+ (locs locations))
+ (while
+ (and alts
+ (let ((branch (car alts)))
+ (cond
+ ((xr--superset-p seq branch)
+ (let ((duplicate (equal seq branch)))
+ (xr--warn
+ warnings
+ pos (1- xr--idx)
+ (if duplicate
+ "Duplicated alternative branch"
+ "Branch matches superset of a previous branch")
+ (cadr locs) (- (car locs) 3)
+ (if duplicate
+ "Previous occurrence here"
+ "This is the subset branch"))
+ nil))
+ ((xr--superset-p branch seq)
+ (xr--warn warnings
+ pos (1- xr--idx)
+ "Branch matches subset of a previous branch"
+ (cadr locs) (- (car locs) 3)
+ "This is the superset branch")
+ nil)
+ (t t))))
+ (setq locs (cdr locs))
+ (setq alts (cdr alts))))
+ (when (and (eq checks 'all)
+ (xr--char-alt-equivalent-p (car alternatives))
+ (xr--char-alt-equivalent-p seq))
(xr--warn
warnings (nth 1 locations) (1- xr--idx)
"Or-pattern more efficiently expressed as character alternative"))
- ))
+ )
(push seq alternatives)))
(if (cdr alternatives)
;; Simplify (or nonl "\n") to anything
@@ -1717,6 +1777,16 @@ A-SETS and B-SETS are arguments to `any'."
;;
;; Ambiguities in the above are resolved greedily left-to-right.
+(defun xr--skip-set-warn (warnings string start is-range format &rest args)
+ (let* ((beg start)
+ (end (if is-range (+ beg 2) beg)))
+ (when (eq (aref string beg) ?\\)
+ (setq end (1+ end)))
+ (when (and is-range (eq (aref string end) ?\\))
+ (setq end (1+ end)))
+ (xr--warn warnings beg end
+ (xr--escape-string (apply #'format-message format args)))))
+
(defun xr--parse-skip-set (string warnings)
;; An ad-hoc check, but one that catches lots of mistakes.
@@ -1864,46 +1934,36 @@ A-SETS and B-SETS are arguments to `any'."
;; Duplicate character: drop it and warn.
((and (eq (aref a 0) (aref a 1))
(eq (aref b 0) (aref b 1)))
- (xr--warn warnings (aref b 2) (aref b 2)
- (xr--escape-string
- (format-message
- "Duplicated character `%c'" (aref this 0)))))
+ (xr--skip-set-warn warnings string (aref b 2) nil
+ "Duplicated character `%c'" (aref this
0)))
;; Duplicate range: drop it and warn.
((and (eq (aref a 0) (aref b 0))
(eq (aref a 1) (aref b 1)))
- (xr--warn warnings (aref b 2) (+ (aref b 2) 2)
- (xr--escape-string
- (format-message
- "Duplicated range `%c-%c'"
- (aref b 0) (aref b 1)))))
+ (xr--skip-set-warn warnings string (aref b 2) t
+ "Duplicated range `%c-%c'"
+ (aref b 0) (aref b 1)))
;; Character in range: drop it and warn.
((eq (aref a 0) (aref a 1))
(when (eq a this)
(setcar s next))
- (xr--warn warnings (aref b 2) (+ (aref b 2) 2)
- (xr--escape-string
- (format-message
- "Range `%c-%c' includes character `%c'"
- (aref b 0) (aref b 1) (aref a 0)))))
+ (xr--skip-set-warn warnings string (aref b 2) t
+ "Range `%c-%c' includes character `%c'"
+ (aref b 0) (aref b 1) (aref a 0)))
;; Same but other way around.
((eq (aref b 0) (aref b 1))
(when (eq b this)
(setcar s next))
- (xr--warn warnings (aref b 2) (aref b 2)
- (xr--escape-string
- (format-message
- "Character `%c' included in range `%c-%c'"
- (aref b 0) (aref a 0) (aref a 1)))))
+ (xr--skip-set-warn warnings string (aref b 2) nil
+ "Character `%c' included in range `%c-%c'"
+ (aref b 0) (aref a 0) (aref a 1)))
;; Overlapping ranges: merge and warn.
(t
(let ((this-end (aref this 1)))
(aset this 1 (max (aref this 1) (aref next 1)))
- (xr--warn warnings (aref b 2) (+ (aref b 2) 2)
- (xr--escape-string
- (format-message
- "Ranges `%c-%c' and `%c-%c' overlap"
- (aref this 0) this-end
- (aref next 0) (aref next 1)))))))
+ (xr--skip-set-warn warnings string (aref b 2) t
+ "Ranges `%c-%c' and `%c-%c' overlap"
+ (aref this 0) this-end
+ (aref next 0) (aref next 1)))))
(setcdr s (cddr s)))
;; No overlap.
(setq s (cdr s)))))
- [elpa] externals/xr 90cd77a251 11/18: Use ranges in warnings, (continued)
- [elpa] externals/xr 90cd77a251 11/18: Use ranges in warnings, ELPA Syncer, 2024/08/01
- [elpa] externals/xr f81b5de888 12/18: Extract diagnostics sorting to a function, ELPA Syncer, 2024/08/01
- [elpa] externals/xr 345b626abf 17/18: NEWS entry for upcoming version 2.0, ELPA Syncer, 2024/08/01
- [elpa] externals/xr ab11e4229d 03/18: Move version history to separate NEWS file, ELPA Syncer, 2024/08/01
- [elpa] externals/xr cbb39a2f52 06/18: Performance hack: speed up xr--superset-p for strings, ELPA Syncer, 2024/08/01
- [elpa] externals/xr 548990e952 04/18: Simplify: make second arg to xr--escape-string optional, ELPA Syncer, 2024/08/01
- [elpa] externals/xr ee9870ea83 08/18: Signal new `xr-parse-error` for parsing errors, ELPA Syncer, 2024/08/01
- [elpa] externals/xr a003438b44 01/18: Check xr-lint `purpose` argument for validity., ELPA Syncer, 2024/08/01
- [elpa] externals/xr 14b639fc1e 10/18: Diagnostics now carry a range, not a single string offset, ELPA Syncer, 2024/08/01
- [elpa] externals/xr 6a708ef75a 14/18: Group diagnostics that belong together, ELPA Syncer, 2024/08/01
- [elpa] externals/xr e2455fd4bd 15/18: Add info-level messages for many warnings,
ELPA Syncer <=
- [elpa] externals/xr 51c053d443 16/18: Require Emacs 27 or newer, ELPA Syncer, 2024/08/01
- [elpa] externals/xr 817916a07b 13/18: Add severity field (warning or error) to diagnostics, ELPA Syncer, 2024/08/01
- [elpa] externals/xr c5da86864b 18/18: Github CI: ignore changes to NEWS in actions, ELPA Syncer, 2024/08/01