QML semantic rules. Line-based: tree-sitter doesn't have a published QML grammar, and the existing tokenizer in code-verify.py already tracks the structure we need.
(src: str, path: Path, fence_mask: list[bool])
| 3112 | |
| 3113 | |
| 3114 | def _qml_rules(src: str, path: Path, fence_mask: list[bool]) -> list[Finding]: |
| 3115 | """QML semantic rules. Line-based: tree-sitter doesn't have a published |
| 3116 | QML grammar, and the existing tokenizer in code-verify.py already |
| 3117 | tracks the structure we need.""" |
| 3118 | out: list[Finding] = [] |
| 3119 | if path.suffix != ".qml": |
| 3120 | return out |
| 3121 | |
| 3122 | file_allows_pixel = path.name in _FONT_PIXEL_OK_FILES |
| 3123 | |
| 3124 | for i, raw in enumerate(src.split("\n"), start=1): |
| 3125 | if i - 1 < len(fence_mask) and fence_mask[i - 1]: |
| 3126 | continue |
| 3127 | # Strip trailing comment -- still a flat scan, but enough to avoid |
| 3128 | # complaining about comment text. |
| 3129 | line = _strip_line_comments(raw) |
| 3130 | |
| 3131 | # qml-font-pixel: `font.pixelSize:` / `font.family:` outside the |
| 3132 | # dashboard whitelist. JS function bodies inside QML still match, |
| 3133 | # but those very rarely set fonts. |
| 3134 | if not file_allows_pixel: |
| 3135 | if re.search( |
| 3136 | r"\bfont\.(pixelSize|pointSize|family|bold|italic" |
| 3137 | r"|weight|capitalization)\s*:", |
| 3138 | line, |
| 3139 | ): |
| 3140 | out.append( |
| 3141 | Finding( |
| 3142 | i, |
| 3143 | "qml-font-pixel", |
| 3144 | "use `font: Cpp_Misc_CommonFonts.uiFont` (or another " |
| 3145 | "helper) instead of individual `font.*` sub-properties", |
| 3146 | ) |
| 3147 | ) |
| 3148 | |
| 3149 | # qml-bus-type-int: `busType: <integer>` or `BusType: <int>`. The |
| 3150 | # property name on a `Source` is `busType`; the C++ enum is |
| 3151 | # `SerialStudio.BusType.UART`. Reject literal ints. |
| 3152 | m = re.search(r"\bbusType\s*:\s*(-?\d+)\b", line) |
| 3153 | if m: |
| 3154 | out.append( |
| 3155 | Finding( |
| 3156 | i, |
| 3157 | "qml-bus-type-int", |
| 3158 | f"hardcoded busType `{m.group(1)}` -- use " |
| 3159 | f"`SerialStudio.BusType.<NAME>`", |
| 3160 | ) |
| 3161 | ) |
| 3162 | |
| 3163 | return out |
| 3164 | |
| 3165 | |
| 3166 | # --------------------------------------------------------------------------- |
no test coverage detected