Checker that enforces FL_NOEXCEPT on functions in src/fl/ and src/platforms/. Supersedes the former NoexceptFlChecker, NoexceptEsp32Checker, and NoexceptPlatformsChecker — all consolidated into this single class.
| 218 | |
| 219 | |
| 220 | class NoexceptFunctionChecker(FileContentChecker): |
| 221 | """Checker that enforces FL_NOEXCEPT on functions in src/fl/ and src/platforms/. |
| 222 | |
| 223 | Supersedes the former NoexceptFlChecker, NoexceptEsp32Checker, and |
| 224 | NoexceptPlatformsChecker — all consolidated into this single class. |
| 225 | """ |
| 226 | |
| 227 | def __init__(self) -> None: |
| 228 | self.violations: dict[str, list[tuple[int, str]]] = {} |
| 229 | |
| 230 | def should_process_file(self, file_path: str) -> bool: |
| 231 | normalized = file_path.replace("\\", "/") |
| 232 | # Must be in src/fl/ or src/platforms/ (accept both absolute and relative) |
| 233 | in_fl = "/src/fl/" in normalized or normalized.startswith("src/fl/") |
| 234 | in_platforms = "platforms/" in normalized |
| 235 | if not in_fl and not in_platforms: |
| 236 | return False |
| 237 | # Only check header files — .cpp.hpp implementation files have too many |
| 238 | # variable declarations and function calls that look like declarations to |
| 239 | # regex. Use the AST-based refactor tool for .cpp.hpp files. |
| 240 | if normalized.endswith(".cpp.hpp") or normalized.endswith(".cpp"): |
| 241 | return False |
| 242 | if not normalized.endswith((".h", ".hpp")): |
| 243 | return False |
| 244 | # Skip the noexcept macro definition itself |
| 245 | if normalized.endswith("noexcept.h") or normalized.endswith( |
| 246 | "fl/stl/noexcept.h" |
| 247 | ): |
| 248 | return False |
| 249 | if "compile_test" in normalized or "ASM_2_C_SHIM" in normalized: |
| 250 | return False |
| 251 | if "/third_party/" in normalized: |
| 252 | return False |
| 253 | return True |
| 254 | |
| 255 | def check_file_content(self, file_content: FileContent) -> list[str]: |
| 256 | if "(" not in file_content.content: |
| 257 | return [] |
| 258 | |
| 259 | violations: list[tuple[int, str]] = [] |
| 260 | in_multiline_comment = False |
| 261 | |
| 262 | for line_number, line in enumerate(file_content.lines, 1): |
| 263 | stripped = line.strip() |
| 264 | |
| 265 | if "/*" in stripped: |
| 266 | in_multiline_comment = True |
| 267 | if "*/" in stripped: |
| 268 | in_multiline_comment = False |
| 269 | continue |
| 270 | if in_multiline_comment: |
| 271 | continue |
| 272 | if stripped.startswith("//"): |
| 273 | continue |
| 274 | |
| 275 | code = stripped.split("//")[0].strip() |
| 276 | if not code or "(" not in code: |
| 277 | continue |
no outgoing calls