Skip to main content

Module boilerplate

Module boilerplate 

Source
Expand description

Boilerplate classification: recognising units whose duplication is expected rather than a finding.

Some code is duplicated because the language leaves no other way to write it. A getter, a delegating wrapper and a run of macro invocations are all genuine clones by every similarity measure, and reporting them crowds out the duplication a reader can act on. This module names those shapes so presentation can decide what to do with them.

§What this is not

Classification is syntactic and conservative. It reads the unit’s IR subtree and nothing else: no name heuristics, no path guesses, no attempt to infer intent. Branching is where behaviour — and therefore the interesting kind of duplication — lives, so a unit that branches is classified only when the branch is a single guard and the body holds nothing else: that unit chooses an answer rather than working one out. Handing an error upwards is not branching at all: it leaves the unit with one path, and the caller with the same one it would have had.

The classification is recorded, never acted on here: a classified unit is still analysed, still verified and still grouped. Whether a category is excluded from reports, ranked down or shown as-is is a presentation decision, so a user can always see what was set aside and why.

§Where the counting stops

Every rule below is a function of what the body counts, and that is a coarse reading: how many calls, not which; how many locals, not what they hold. The labelled corpora have reached the end of it. Bodies ruled opposite ways come out counted identically, and not in far-apart projects — one logging library declares a helper that takes a time point, converts it and hands the result to a call, and declares an overload that takes the current time, and hands that to a call. The first is copied into two sinks and is duplication worth removing; the second wraps its own sibling and is not. Two statements each, one delegation each, the same counts.

Nor is it only the far apart that collide. An XML parser declares four integer parsers and two floating-point ones next to each other, each a guard on one call’s result; the integer ones repeat a policy about how a leading 0x is spelled and the floating-point ones repeat nothing, and the policy lives inside an argument expression. Counted, all six are the same body.

So a rule reaching further than these does not buy coverage at the cost of accuracy — it trades a lookalike for a real finding, one for one. The categories here are the shapes no confirmed duplication was found in, and reaching past them needs something these counts do not carry: which callee is called, where a local’s value goes, or what an argument holds. Another bound on the same numbers will not do it. The boilerplate-screen example prints the counts for every labelled unit, which is how a proposed rule is weighed against what it would cost before it is written.

Structs§

BoilerplateCounts
What a unit’s body contains, counted over its whole subtree.

Enums§

Boilerplate
A recognised boilerplate shape.

Constants§

BOILERPLATE_VERSION
Version of the classification rules.

Functions§

classify
Classify a unit by the shape of its body, or return None when it does something a reader would want to see duplicated.
counts
Count what a unit’s subtree contains, excluding the unit node itself.