aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2023-09-19 15:18:11 +0200
committerMattias EngdegÄrd2023-09-19 15:21:03 +0200
commitb03338c70d81f2cba9c8a0b4fefbf83ef7a346e0 (patch)
tree28ebf04f4dbfbf5b021d018216df6fe85b8110f5
parent321f2e1e4d4b2f209b072dc891cc89cbab19f032 (diff)
downloademacs-b03338c70d81f2cba9c8a0b4fefbf83ef7a346e0.tar.gz
emacs-b03338c70d81f2cba9c8a0b4fefbf83ef7a346e0.zip
Warn about duplicated :tag strings in defcustom choices
It is bad user experience when two menu items have identical labels. * lisp/emacs-lisp/bytecomp.el (bytecomp--check-cus-type): Add check. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-defcustom-type): Add test case.
-rw-r--r--lisp/emacs-lisp/bytecomp.el9
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el5
2 files changed, 12 insertions, 2 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 1474acc1638..387d7ef4de1 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -5272,7 +5272,8 @@ FORM is used to provide location, `bytecomp--cus-function' and
5272 (unless tail 5272 (unless tail
5273 (bytecomp--cus-warn type "`%s' without any types inside" head)) 5273 (bytecomp--cus-warn type "`%s' without any types inside" head))
5274 (let ((clauses tail) 5274 (let ((clauses tail)
5275 (constants nil)) 5275 (constants nil)
5276 (tags nil))
5276 (while clauses 5277 (while clauses
5277 (let* ((ty (car clauses)) 5278 (let* ((ty (car clauses))
5278 (ty-head (car-safe ty))) 5279 (ty-head (car-safe ty)))
@@ -5291,6 +5292,12 @@ FORM is used to provide location, `bytecomp--cus-function' and
5291 (bytecomp--cus-warn 5292 (bytecomp--cus-warn
5292 ty "duplicated value in `%s': `%S'" head val)) 5293 ty "duplicated value in `%s': `%S'" head val))
5293 (push val constants))) 5294 (push val constants)))
5295 (let ((tag (and (consp ty) (plist-get (cdr ty) :tag))))
5296 (when (stringp tag)
5297 (when (member tag tags)
5298 (bytecomp--cus-warn
5299 ty "duplicated :tag string in `%s': %S" head tag))
5300 (push tag tags)))
5294 (bytecomp--check-cus-type ty)) 5301 (bytecomp--check-cus-type ty))
5295 (setq clauses (cdr clauses))))) 5302 (setq clauses (cdr clauses)))))
5296 ((eq head 'cons) 5303 ((eq head 'cons)
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index a335a7fa1f8..e644417c3d4 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -1875,7 +1875,7 @@ EXPECTED-POINT BINDINGS (MODES \\='\\='(ruby-mode js-mode python-mode)) \
1875(FIXTURE-FN \\='#\\='electric-pair-mode))" fill-column))) 1875(FIXTURE-FN \\='#\\='electric-pair-mode))" fill-column)))
1876 1876
1877(ert-deftest bytecomp-test-defcustom-type () 1877(ert-deftest bytecomp-test-defcustom-type ()
1878 (cl-flet ((dc (type) `(defcustom mytest nil "doc" :type ',type))) 1878 (cl-flet ((dc (type) `(defcustom mytest nil "doc" :type ',type :group 'test)))
1879 (bytecomp--with-warning-test 1879 (bytecomp--with-warning-test
1880 (rx "type should not be quoted") (dc ''integer)) 1880 (rx "type should not be quoted") (dc ''integer))
1881 (bytecomp--with-warning-test 1881 (bytecomp--with-warning-test
@@ -1891,6 +1891,9 @@ EXPECTED-POINT BINDINGS (MODES \\='\\='(ruby-mode js-mode python-mode)) \
1891 (rx "duplicated value in `choice': `a'") 1891 (rx "duplicated value in `choice': `a'")
1892 (dc '(choice (const a) (const b) (const a)))) 1892 (dc '(choice (const a) (const b) (const a))))
1893 (bytecomp--with-warning-test 1893 (bytecomp--with-warning-test
1894 (rx "duplicated :tag string in `choice': \"X\"")
1895 (dc '(choice (const :tag "X" a) (const :tag "Y" b) (other :tag "X" c))))
1896 (bytecomp--with-warning-test
1894 (rx "`cons' requires 2 type specs, found 1") 1897 (rx "`cons' requires 2 type specs, found 1")
1895 (dc '(cons :tag "a" integer))) 1898 (dc '(cons :tag "a" integer)))
1896 (bytecomp--with-warning-test 1899 (bytecomp--with-warning-test