FileContentChecker implementation for detecting includes after namespace declarations.
| 47 | |
| 48 | |
| 49 | class IncludeAfterNamespaceChecker(FileContentChecker): |
| 50 | """FileContentChecker implementation for detecting includes after namespace declarations.""" |
| 51 | |
| 52 | def __init__(self): |
| 53 | self.violations: dict[str, list[tuple[int, str]]] = {} |
| 54 | |
| 55 | def should_process_file(self, file_path: str) -> bool: |
| 56 | """Check if file should be processed.""" |
| 57 | # Skip files matching skip patterns |
| 58 | if any(pattern in file_path for pattern in SKIP_PATTERNS): |
| 59 | return False |
| 60 | # Only check C++ files |
| 61 | return any( |
| 62 | file_path.endswith(ext) for ext in [".cpp", ".h", ".hpp", ".cc", ".ino"] |
| 63 | ) |
| 64 | |
| 65 | def check_file_content(self, file_content: FileContent) -> list[str]: |
| 66 | """Check file content for includes after namespace declarations.""" |
| 67 | # Check if the file has the allow directive |
| 68 | for line in file_content.lines: |
| 69 | if ALLOW_DIRECTIVE_PATTERN.search(line): |
| 70 | return [] # Return empty if directive is found |
| 71 | |
| 72 | namespace_started = False |
| 73 | violations: list[tuple[int, str]] = [] |
| 74 | |
| 75 | for i, line in enumerate(file_content.lines, 1): |
| 76 | # Check if we're entering a namespace |
| 77 | if NAMESPACE_PATTERN.match(line): |
| 78 | namespace_started = True |
| 79 | continue |
| 80 | |
| 81 | # Check for includes after namespace started |
| 82 | if namespace_started and INCLUDE_PATTERN.match(line): |
| 83 | # Skip if the line has a // nolint comment |
| 84 | if NOLINT_PATTERN.search(line): |
| 85 | continue |
| 86 | violations.append((i, line.rstrip("\n"))) |
| 87 | |
| 88 | if violations: |
| 89 | self.violations[file_content.path] = violations |
| 90 | |
| 91 | return [] # We collect violations internally |
| 92 | |
| 93 | |
| 94 | def main() -> None: |
no outgoing calls
no test coverage detected