Author: Zeyi Xu
Date: 2026-03-20T18:33:12+08:00
New Revision: 172c0bbfbd564166d0a1377b1476563f97935e11

URL: 
https://github.com/llvm/llvm-project/commit/172c0bbfbd564166d0a1377b1476563f97935e11
DIFF: 
https://github.com/llvm/llvm-project/commit/172c0bbfbd564166d0a1377b1476563f97935e11.diff

LOG: [clang-tidy] Fix alphabetical order check for multiline doc entries and 
whitespace handling (#186950)

The `check_alphabetical_order.py` script previously only scanned the
first line of each bullet point in `ReleaseNotes.rst`, causing sorting
failures when a `:doc:` tag was split across multiple lines.

Also, when it is sorting the last entry of a section, the script will
insert an unnecessary whitespace.

This PR fixes these two problems.

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py
    clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py 
b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py
index 6a200e36b2715..9493380bba8eb 100644
--- a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py
+++ b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py
@@ -202,7 +202,7 @@ def find_heading(lines: Sequence[str], title: str) -> 
Optional[int]:
 
 def extract_label(text: str) -> str:
     if m := DOC_LABEL_RN_RE.search(text):
-        return m.group("label")
+        return m.group("label").strip()
     return text
 
 
@@ -221,7 +221,7 @@ def _parse_bullet_blocks(lines: Sequence[str], start: int, 
end: int) -> BulletBl
     blocks: List[BulletItem] = []
     res = _scan_bullet_blocks(lines, first_bullet, n)
     for _, block in res.blocks_with_pos:
-        key: CheckLabel = extract_label(block[0])
+        key: CheckLabel = extract_label("".join(block))
         blocks.append((key, block))
 
     suffix: Lines = list(lines[res.next_index : n])
@@ -294,16 +294,24 @@ def _find_section_bounds(
         if (h_end := find_heading(lines, next_title)) is None:
             # Scan forward to the next heading-like underline.
             h_end = sec_start
-            while h_end + 1 < len(lines):
-                if lines[h_end].strip() and set(lines[h_end + 1].rstrip("\n")) 
== {"^"}:
+            while h_end < len(lines):
+                if (
+                    h_end + 1 < len(lines)
+                    and lines[h_end].strip()
+                    and set(lines[h_end + 1].rstrip("\n")) == {"^"}
+                ):
                     break
                 h_end += 1
         sec_end = h_end
     else:
         # Scan to end or until a heading underline is found.
         h_end = sec_start
-        while h_end + 1 < len(lines):
-            if lines[h_end].strip() and set(lines[h_end + 1].rstrip("\n")) == 
{"^"}:
+        while h_end < len(lines):
+            if (
+                h_end + 1 < len(lines)
+                and lines[h_end].strip()
+                and set(lines[h_end + 1].rstrip("\n")) == {"^"}
+            ):
                 break
             h_end += 1
         sec_end = h_end

diff  --git 
a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py 
b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py
index fa418e41ee8a8..09e23ce55e00a 100644
--- a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py
+++ b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py
@@ -109,6 +109,7 @@ def test_duplicate_detection_and_report(self) -> None:
               <clang-tidy/checks/bugprone/easily-swappable-parameters>` check 
by
               correcting a spelling mistake on its option
               ``NamePrefixSuffixSilenceDissimilarityTreshold``.
+
             """
         )
         self.assertEqual(report_str, expected_report)
@@ -161,7 +162,6 @@ def test_process_release_notes_with_unsorted_content(self) 
-> None:
 
                   Detect redundant parentheses.
 
-
                 """
             )
 
@@ -229,7 +229,6 @@ def 
test_process_release_notes_prioritizes_sorting_over_duplicates(self) -> None
                   exceptions from captures are now diagnosed, exceptions in 
the bodies of
                   lambdas that aren't actually invoked are not.
 
-
                 """
             )
             self.assertEqual(out, expected_out)
@@ -353,11 +352,52 @@ def test_release_notes_handles_nested_sub_bullets(self) 
-> None:
 
               - ``for`` loops are supported.
 
-
            """
         )
         self.assertEqual(out, expected_out)
 
+    def test_release_notes_handles_multiline_doc(self) -> None:
+        rn_text = textwrap.dedent(
+            """\
+            Changes in existing checks
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+            - Renamed :doc:`performance-faster-string-find
+              <clang-tidy/checks/performance/faster-string-find>` to
+              :doc:`performance-faster-string-operation
+              <clang-tidy/checks/performance/faster-string-operation>`.
+              The `performance-faster-string-find` name is kept as an alias.
+
+            - Renamed :doc:`hicpp-no-assembler 
<clang-tidy/checks/hicpp/no-assembler>`
+              to :doc:`portability-no-assembler
+              <clang-tidy/checks/portability/no-assembler>`. The 
`hicpp-no-assembler`
+              name is kept as an alias.
+
+            """
+        )
+
+        out = _mod.normalize_release_notes(rn_text.splitlines(True))
+
+        expected_out = textwrap.dedent(
+            """\
+            Changes in existing checks
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+            - Renamed :doc:`hicpp-no-assembler 
<clang-tidy/checks/hicpp/no-assembler>`
+              to :doc:`portability-no-assembler
+              <clang-tidy/checks/portability/no-assembler>`. The 
`hicpp-no-assembler`
+              name is kept as an alias.
+
+            - Renamed :doc:`performance-faster-string-find
+              <clang-tidy/checks/performance/faster-string-find>` to
+              :doc:`performance-faster-string-operation
+              <clang-tidy/checks/performance/faster-string-operation>`.
+              The `performance-faster-string-find` name is kept as an alias.
+
+            """
+        )
+        self.assertEqual(out, expected_out)
+
     def test_process_checks_list_normalizes_output(self) -> None:
         list_text = textwrap.dedent(
             """\


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to