Check that every build file in src/fl/build/ includes required platform pre-headers before any .cpp.hpp or _build.cpp.hpp includes. Required pre-headers (in order): 1. platforms/new.h — placement new + __cxa_guard_* declarations 2. fl/system/arduino.h — Arduino.h trampoline + m
(src_dir: Path)
| 692 | |
| 693 | |
| 694 | def _check_build_file_preheaders(src_dir: Path) -> list[str]: |
| 695 | """ |
| 696 | Check that every build file in src/fl/build/ includes required platform pre-headers |
| 697 | before any .cpp.hpp or _build.cpp.hpp includes. |
| 698 | |
| 699 | Required pre-headers (in order): |
| 700 | 1. platforms/new.h — placement new + __cxa_guard_* declarations |
| 701 | 2. fl/system/arduino.h — Arduino.h trampoline + macro cleanup |
| 702 | |
| 703 | Returns: |
| 704 | list of violation strings |
| 705 | """ |
| 706 | violations: list[str] = [] |
| 707 | build_dir = src_dir / "fl" / "build" |
| 708 | if not build_dir.exists(): |
| 709 | return violations |
| 710 | |
| 711 | include_pattern = re.compile(r'^\s*#include\s+"([^"]+)"', re.MULTILINE) |
| 712 | |
| 713 | for build_file in sorted(build_dir.glob("*.cpp")): |
| 714 | content = build_file.read_text(encoding="utf-8") |
| 715 | rel_file = build_file.relative_to(PROJECT_ROOT).as_posix() |
| 716 | |
| 717 | includes = list(include_pattern.finditer(content)) |
| 718 | if not includes: |
| 719 | continue |
| 720 | |
| 721 | # Find the first .cpp.hpp include (the implementation include) |
| 722 | first_impl_line: int | None = None |
| 723 | for match in includes: |
| 724 | if match.group(1).endswith(".cpp.hpp"): |
| 725 | first_impl_line = _get_line_number(content, match.start()) |
| 726 | break |
| 727 | |
| 728 | if first_impl_line is None: |
| 729 | violations.append( |
| 730 | f"{rel_file}: Build file has no .cpp.hpp includes — this file serves no purpose." |
| 731 | ) |
| 732 | continue |
| 733 | |
| 734 | # Check each required pre-header appears before the first impl include |
| 735 | for pre_header in REQUIRED_PRE_HEADERS: |
| 736 | found = False |
| 737 | for match in includes: |
| 738 | if match.group(1) == pre_header: |
| 739 | pre_line = _get_line_number(content, match.start()) |
| 740 | if pre_line < first_impl_line: |
| 741 | found = True |
| 742 | else: |
| 743 | violations.append( |
| 744 | f"{rel_file}:{pre_line}: Pre-header '{pre_header}' must appear " |
| 745 | f"BEFORE first .cpp.hpp include (line {first_impl_line})." |
| 746 | ) |
| 747 | found = True # Don't also report missing |
| 748 | break |
| 749 | if not found: |
| 750 | violations.append( |
| 751 | f"{rel_file}: Missing required pre-header '#include \"{pre_header}\"'. " |
no test coverage detected