Skip to content

refactor(checker): reshape Checker trait (default predicates, is_primitive(&Node), narrow bounds) #520

@dekobon

Description

@dekobon

Summary

The Checker trait (src/checker.rs:168-231) is a ~13-method mega-trait
with no default bodies for the trivial predicates, making "add a language"
a copy-paste ritual and embedding signature inconsistencies. 2.0 is the
natural window to reshape it (it is #[doc(hidden)] and already slated for
reconsideration per STABILITY.md). Three related cleanups:

(a) Default bodies for the "almost always false/empty" predicates

is_comment, is_useful_comment, is_func_space, is_func,
is_closure, is_call, is_non_arg, is_string, is_else_if,
is_primitive are all required (no defaults). Concretely this forces
pure-boilerplate stubs: PreprocCode (src/checker.rs:233-271) and
CcommentCode (:273-311) are almost entirely false-returning, and
BashCode::is_closure (:1407) is a forced stub. is_primitive,
is_closure, is_useful_comment, is_non_arg have an obviously-safe
false default — a new language can't be told by the compiler that false
is correct.

Fix: give those predicates -> false defaults (deletes hundreds of
stub lines). Optionally split into CommentClassifier / SpaceClassifier
/ OperandClassifier sub-traits.

(b) is_primitive(id: u16) breaks the &Node convention

src/checker.rs:178fn is_primitive(_id: u16) -> bool;. Every other
predicate takes &Node. The sole caller already has the &Node
(src/metrics/halstead.rs:382 does T::is_primitive(node.kind_id())).
Passing a bare u16 where the rest of the trait passes a domain type is
the "two same-typed primitives" footgun (AGENTS.md) and forecloses
primitive checks that need children/text.

Fix: fn is_primitive(_node: &Node) -> bool with default false.

(c) Narrow count_specific_ancestors from ParserTrait to Checker

src/node.rs:237count_specific_ancestors<T: ParserTrait> instantiates
the full 15-associated-type ParserTrait purely to call
T::Checker::is_else_if. Callers pass PythonParser etc.
(src/metrics/cognitive.rs:421, loc.rs:1014).

Fix: bound on <C: Checker> and call C::is_else_if; callers pass
PythonCode. Internal (pub(crate)), so fixable anytime, but belongs with
the trait reshape.

Why it matters for 2.x

Default bodies and the is_primitive signature change are best landed with
the #[doc(hidden)]-trait fate decision already on the 2.0 roadmap (#505).

Part of #505. Label: enhancement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions