Checker that verifies FL_IS_* macro users include the right is_*.h header.
| 98 | |
| 99 | |
| 100 | class IsHeaderIncludeChecker(FileContentChecker): |
| 101 | """Checker that verifies FL_IS_* macro users include the right is_*.h header.""" |
| 102 | |
| 103 | def __init__(self) -> None: |
| 104 | self.violations: dict[str, list[tuple[int, str]]] = {} |
| 105 | |
| 106 | def should_process_file(self, file_path: str) -> bool: |
| 107 | if not file_path.startswith(str(PLATFORMS_ROOT)): |
| 108 | return False |
| 109 | if not file_path.endswith((".cpp", ".h", ".hpp")): |
| 110 | return False |
| 111 | |
| 112 | file_name = Path(file_path).name |
| 113 | |
| 114 | # Skip is_*.h detection headers — they define FL_IS_* macros |
| 115 | if file_name.startswith("is_"): |
| 116 | return False |
| 117 | |
| 118 | # Skip compile_test files |
| 119 | if "compile_test" in file_name.lower(): |
| 120 | return False |
| 121 | |
| 122 | # Skip core_detection.h — it defines FL_IS_STM32_* core macros |
| 123 | if "core_detection" in file_name.lower(): |
| 124 | return False |
| 125 | |
| 126 | return True |
| 127 | |
| 128 | def check_file_content(self, file_content: FileContent) -> list[str]: |
| 129 | fl_is_macros = _extract_fl_is_macros_on_preprocessor_lines(file_content.lines) |
| 130 | if not fl_is_macros: |
| 131 | return [] |
| 132 | |
| 133 | included_names = _extract_included_filenames(file_content.lines) |
| 134 | has_is_platform = "is_platform.h" in included_names |
| 135 | |
| 136 | # Determine which headers are required |
| 137 | required_headers: dict[ |
| 138 | str, set[str] |
| 139 | ] = {} # header → set of FL_IS_* macros needing it |
| 140 | for macro in fl_is_macros: |
| 141 | header = _get_required_header(macro) |
| 142 | if header: |
| 143 | required_headers.setdefault(header, set()).add(macro) |
| 144 | |
| 145 | violations: list[tuple[int, str]] = [] |
| 146 | for header, macros in sorted(required_headers.items()): |
| 147 | if header in included_names or has_is_platform: |
| 148 | continue |
| 149 | macros_str = ", ".join(sorted(macros)) |
| 150 | message = ( |
| 151 | f"File uses {macros_str} but does not include '{header}' " |
| 152 | f"or 'is_platform.h'. Add: #include \"{header}\"" |
| 153 | ) |
| 154 | violations.append((0, message)) |
| 155 | |
| 156 | if violations: |
| 157 | self.violations[file_content.path] = violations |
no outgoing calls