FileContentChecker implementation for detecting 'using namespace' in headers.
| 22 | |
| 23 | |
| 24 | class UsingNamespaceChecker(FileContentChecker): |
| 25 | """FileContentChecker implementation for detecting 'using namespace' in headers.""" |
| 26 | |
| 27 | def __init__(self): |
| 28 | self.violations: dict[str, list[tuple[int, str]]] = {} |
| 29 | |
| 30 | def should_process_file(self, file_path: str) -> bool: |
| 31 | """Check if file should be processed (only PROJECT_ROOT/src/fl/ header files).""" |
| 32 | # Fast normalized path check |
| 33 | normalized_path = file_path.replace("\\", "/") |
| 34 | |
| 35 | # Must be in /src/fl/ subdirectory |
| 36 | if "/src/fl/" not in normalized_path: |
| 37 | return False |
| 38 | |
| 39 | # Must NOT be in examples or tests (examples/*/src/fl/ should not match) |
| 40 | if "/examples/" in normalized_path or "/tests/" in normalized_path: |
| 41 | return False |
| 42 | |
| 43 | # Only check header files |
| 44 | return any(file_path.endswith(ext) for ext in [".h", ".hpp", ".hxx", ".hh"]) |
| 45 | |
| 46 | def check_file_content(self, file_content: FileContent) -> list[str]: |
| 47 | """Check file content for 'using namespace' declarations.""" |
| 48 | violations: list[tuple[int, str]] = [] |
| 49 | file_content.content.splitlines(keepends=True) |
| 50 | |
| 51 | for line_num, line in enumerate(file_content.lines, 1): |
| 52 | # Remove comments to avoid false positives |
| 53 | line_clean = re.sub(r"//.*$", "", line) |
| 54 | line_clean = re.sub(r"/\*.*?\*/", "", line_clean) |
| 55 | |
| 56 | # Look for 'using namespace' declarations |
| 57 | # Match patterns like: |
| 58 | # - using namespace std; |
| 59 | # - using namespace foo::bar; |
| 60 | # But not: |
| 61 | # - using std::vector; (using declaration, not namespace) |
| 62 | if re.search(r"\busing\s+namespace\s+\w+(?:::\w+)*\s*;", line_clean): |
| 63 | # Skip macro definitions |
| 64 | if re.search(r"#define\s+\w+.*using\s+namespace", line_clean): |
| 65 | continue |
| 66 | |
| 67 | # Skip conditional using statements that are part of API design |
| 68 | # Look at previous few lines for #if statements |
| 69 | is_conditional = False |
| 70 | for i in range(max(0, line_num - 6), line_num - 1): |
| 71 | if i < len(file_content.lines): |
| 72 | prev_line = file_content.lines[i].strip() |
| 73 | if re.search(r"#if\s+.*FORCE_USE_NAMESPACE", prev_line): |
| 74 | is_conditional = True |
| 75 | break |
| 76 | |
| 77 | if not is_conditional: |
| 78 | violations.append((line_num, line.strip())) |
| 79 | |
| 80 | if violations: |
| 81 | self.violations[file_content.path] = violations |
no outgoing calls
no test coverage detected