MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / _cpp_rules

Function _cpp_rules

scripts/code_verify_rules.py:1440–2173  ·  view source on GitHub ↗

Run tree-sitter-backed C++/Qt rules on `src`. Returns one Finding per issue. `fence_mask[i]` is True when source line `i+1` sits inside a `// code-verify off` / `// code-verify on` fence and must be skipped. The rules implemented here mirror CLAUDE.md's "Common Mistakes" table and t

(src: bytes, path: Path, fence_mask: list[bool])

Source from the content-addressed store, hash-verified

1438
1439
1440def _cpp_rules(src: bytes, path: Path, fence_mask: list[bool]) -> list[Finding]:
1441 """Run tree-sitter-backed C++/Qt rules on `src`. Returns one Finding per
1442 issue. `fence_mask[i]` is True when source line `i+1` sits inside a
1443 `// code-verify off` / `// code-verify on` fence and must be skipped.
1444
1445 The rules implemented here mirror CLAUDE.md's "Common Mistakes" table
1446 and the NASA Power-of-Ten section:
1447
1448 qt-bare-emit bare `emit` outside strings/comments
1449 qt-uppercase-signal-slot Q_SIGNALS: / Q_SLOTS: section labels
1450 qt-invokable-void Q_INVOKABLE void f() (use `public slots:`)
1451 qt-header-member-init int m_foo = 0; in a header class body
1452 qt-disconnect-nullptr disconnect(..., nullptr) as the slot arg
1453 qt-direct-jsengine-call parseFunction.call(...) without guardedCall
1454 cxx-function-too-long function definition over 100 lines
1455 cxx-nesting-too-deep control-flow nesting > 3 levels
1456 cxx-goto-or-jmp goto / setjmp / longjmp
1457 cxx-while-loop `while (cond)` (use bounded `for` instead)
1458 doc-missing-brief-cpp .cpp function definition without /** @brief */
1459 doc-missing-brief-h header type-level definition without /** @brief */
1460 doc-verbose-brief doxygen block carries @param/@return/blank-`*`
1461 paragraphs or wraps past 6 lines (a brief may
1462 absorb an in-body why, but stays <=6 lines)
1463 cxx-inbody-comment comment inside a function body (functions are
1464 short; the @brief above + the code carry it)
1465 cxx-trivial-function function with an empty / only-Q_UNUSED / single
1466 constant-return body (dead-code candidate)
1467 cxx-scattered-constant file-scope static/constexpr/const declared after
1468 the first function (hoist to the top section)
1469 hotpath-allocation allocation/append on a known hotpath method
1470 keys-hardcoded-literal raw "busType" etc. literal where Keys:: belongs
1471 cxx-anonymous-namespace helpers/types defined inside `namespace { ... }`
1472 """
1473 if not HAS_TREE_SITTER:
1474 return []
1475
1476 out: list[Finding] = []
1477 tree = _CPP_PARSER.parse(src)
1478 root = tree.root_node
1479 is_header = path.suffix in {".h", ".hpp", ".hxx"}
1480
1481 def fenced(line: int) -> bool:
1482 idx = line - 1
1483 return 0 <= idx < len(fence_mask) and fence_mask[idx]
1484
1485 # ---- qt-bare-emit / qt-uppercase-signal-slot / cxx-goto / Q_INVOKABLE void
1486 # The fastest pass that catches text-level Qt mistakes is a token sweep
1487 # that respects strings/comments. We use a tiny per-line scan that
1488 # strips comments and string literals first.
1489 src_text = src.decode("utf-8", errors="replace")
1490 lines = src_text.split("\n")
1491 for i, raw in enumerate(lines, start=1):
1492 if fenced(i):
1493 continue
1494 scrubbed = _strip_strings_and_line_comments(raw)
1495 # Bare `emit` -- token must be word-isolated.
1496 if re.search(r"\bemit\b\s+[A-Za-z_]", scrubbed):
1497 out.append(

Callers 1

analyzeFunction · 0.85

Calls 15

fencedFunction · 0.85
_gather_while_conditionFunction · 0.85
_header_contract_namesFunction · 0.85
_walkFunction · 0.85
_has_function_ancestorFunction · 0.85
_function_nameFunction · 0.85
_line_ofFunction · 0.85
_function_body_linesFunction · 0.85
_max_nesting_depthFunction · 0.85
_previous_doxygen_briefFunction · 0.85

Tested by

no test coverage detected