Run the clang-query FL_NOEXCEPT ratchet used by default C++ lint.
(file_path: str | None = None)
| 561 | |
| 562 | |
| 563 | def run_noexcept_ast_check(file_path: str | None = None) -> CheckerResults: |
| 564 | """Run the clang-query FL_NOEXCEPT ratchet used by default C++ lint.""" |
| 565 | from ci.tools.check_noexcept import ( |
| 566 | DEFAULT_BASELINE, |
| 567 | NoexceptCheckError, |
| 568 | diff_against_baseline, |
| 569 | find_missing_noexcept, |
| 570 | load_baseline, |
| 571 | ) |
| 572 | |
| 573 | results = CheckerResults() |
| 574 | |
| 575 | scope = "all" |
| 576 | rel_file: str | None = None |
| 577 | if file_path is not None: |
| 578 | rel_file = os.path.relpath(str(Path(file_path).resolve()), PROJECT_ROOT) |
| 579 | rel_file = rel_file.replace("\\", "/") |
| 580 | if rel_file.startswith("src/fl/"): |
| 581 | scope = "fl" |
| 582 | elif rel_file.startswith("src/platforms/"): |
| 583 | scope = "platforms" |
| 584 | elif rel_file.startswith("src/third_party/"): |
| 585 | scope = "third_party" |
| 586 | else: |
| 587 | # Outside owned src scopes — nothing to check for this file. |
| 588 | return results |
| 589 | |
| 590 | try: |
| 591 | hits = find_missing_noexcept(scope) |
| 592 | except NoexceptCheckError as exc: |
| 593 | results.add_violation("ci/tools/check_noexcept.py", 0, str(exc)) |
| 594 | return results |
| 595 | |
| 596 | if rel_file is not None: |
| 597 | hits = [hit for hit in hits if hit.path == rel_file] |
| 598 | |
| 599 | new_hits, _stale = diff_against_baseline(hits, load_baseline(DEFAULT_BASELINE)) |
| 600 | for hit in new_hits: |
| 601 | abs_path = str(PROJECT_ROOT / hit.path) |
| 602 | results.add_violation( |
| 603 | abs_path, hit.line, f"Missing FL_NOEXCEPT: {hit.line_text}" |
| 604 | ) |
| 605 | |
| 606 | return results |
| 607 | |
| 608 | |
| 609 | @dataclass(frozen=True) |
no test coverage detected