**`lint --list-rules`** prints every registered check as `id description`, one per line, and exits — THE authoritative live listing; use it instead of any hardcoded rule list. analysis/check layer; built-in checks — **`unused-import`**: an import whose bound name has no word-boundary occurrence outside the imports → `Warning` ONLY when its declaring module is in the lint file set (verifiable); an out-of-scope NAMED import (stdlib, haxelib, module outside the linted paths) is an unverifiable `Info` advisory that `--fix` never deletes — so narrow-scope runs (`lint test/`) can't false-flag load-bearing imports; a wildcard (`import pkg.*;`) stays `Info`; a `using` is LIVE when its bound name is referenced (a static / type use such as `StringTools.fastCodeAt`) OR one of its extension methods appears as a `.method` member-access — for a known stdlib module (`StringTools` / `Lambda`, resolved via the `GrammarPlugin.knownExtensionMethods` seam, a table extracted from the installed std) a verified-unused `using` is a deletable `Warning`, while an UNKNOWN module stays an unverifiable `Info`; **`unused-local`**: a local `var`/`final` (`VarStmt`/`FinalStmt`) never referenced in its enclosing scope → `Warning` (conservative word-boundary text scan via `RefactorSupport.referencedInRange`; skips the plugin's `opaqueKinds` macro-reification subtrees so splice-injected uses are not false-flagged; params/`for`-iterators/`catch`-vars/fields out of scope); **`duplicate-import`**: an import/using whose (kind, module-path, alias) all match an earlier one in the file → `Warning` on the 2nd+ occurrence (distinct kinds — `import a.B` vs `using a.B` — and distinct aliases kept); **`--fix`** deletes the fixable subset in place (unused imports; unused locals with no initializer or a side-effect-free one; duplicate imports) via the DELETE verb, batched per file, canonical-gated. **NOT delete-only**: it also applies every rule's non-delete `fix()` — member-order is a whole-file canonical REORDER (one out-of-order member relocates ALL members, e.g. 149 relocations/10 files from ~10 findings, one file 239 diff lines) and `prefer-*` transforms (`prefer-single-quotes` `"x"`→`'x'`) apply too. These are canonical-gated on the project's `hxformat.json` — testing in `/tmp` (no config discovered) silently no-ops them, falsely looking delete-only; always test `--fix` on an in-tree file. `lint <dir> --fix` has a HUGE blast radius (one call rewrote 184 files) — scope with a specific file path and/or `--rule <id>`. Info hidden unless `--all`; report-only exit UNLESS `--fail-on <error\|warning\|info>` → exit non-zero when a finding at-or-above `<sev>` survives. **Inline suppression** is applied in `Linter.run` so BOTH the report and `--fix` honour it: a trailing `// noqa` (or `// noqa: <rule>,<rule>` for named rules) clears any finding whose source span COVERS its line — so a `noqa` the writer reflowed onto a continuation line still lands; `// CHECKSTYLE:OFF`…`// CHECKSTYLE:ON` clears a region by the finding's REPORT line (`anyparse.check.Suppression`, an `Entry.region` flag discriminates the two, string-aware comment scan, no parse). **`--format`** machine output via `anyparse.query.format.LintFormat`: `json` records / `checkstyle` XML (symmetric with the `checkstyle.json` the loaders consume). Builtins span the `unused-*` (`import`/`local`/`private`/`parameter`), `dead-code`/`empty-block`/`empty-statement`, structural-correctness (`identical-operands`, `self-assignment`, `duplicate-case`, `comparison-to-boolean`, `redundant-parens`, `redundant-else-after-return`, `collapsible-if`, `double-negation`, `swallowed-exception`, `assignment-in-condition`, `duplicate-ternary-branches`, `constant-condition`, `redundant-map-iter-key`), modernization `prefer-*` (`prefer-final`/`prefer-ternary-return`/`prefer-switch`/`prefer-bind`/`prefer-null-coalescing`/`prefer-array-literal`/`prefer-map-literal`/`prefer-interpolation`/`prefer-single-quotes`, `simplify-boolean-ternary`, `fold-adjacent-string-literals`) and project-style (`naming`, `missing-visibility`, `modifier-order`, `explicit-type`, `complexity`) families. The authoritative, current set is `Linter.builtins()` / the README check table — this line is NOT kept in lockstep, so don't trust a hardcoded count. **Project config `apqlint.json`** (apq-native, walk-up discovered like `checkstyle.json`/`hxformat.json`, in `anyparse.check.LintConfig`): per rule `"enabled":false` drops it from the default set (an explicit `--rule` still runs it), `"severity":"error|warning|info"` overrides the reported severity (remapped in `Linter.run` before report/`--fail-on`), any other key is a rule option (`complexity`'s `"max"`, precedence over a `checkstyle.json` threshold). Missing/malformed → no-op. Walk-up extracted to shared `anyparse.query.ConfigFinder.findUp`; `Severity.fromName` shared with `--fail-on`
0 commit comments