Skip to main content

Module ruby_instrumenter

Module ruby_instrumenter 

Source
Expand description

Supercov-owned Ruby obligation discovery.

Prism (Ruby’s own parser) supplies syntax and exact byte ranges. Supercov owns the denominator: every statement, method, decision and branch obligation is decided here, ahead of the run, from source alone.

Alongside the shared CoverageManifest this module emits a probe plan for the stdlib-only Ruby runtime. The runtime reads Ruby’s Coverage module for lines, and proves everything else two ways at once, so that either interpreter generation can pick its own:

  • Ruby 3.4+ reads line events only. Asking Coverage for branches and methods too made every sample rebuild both tables for every loaded file (7 ms per sample with 550 files, five samples per test), which was 80% of the runtime’s cost. Instead, the statement that starts a branch body or a method body proves the branch, the method and the decision outcome it witnesses (the implied map), and what has no such statement — an else-less or modifier if, a ternary, &., a case without else, an empty body — gets a probe. Probes also prove what Coverage never sees: the operands of &&/|| for MC/DC, ||=, loop entry, rescue flow and a second statement on a line.
  • Ruby 3.3 cannot apply the insertions (it does not cover code compiled by a load hook), so it keeps asking Coverage for branches and methods and proves those obligations by matching its keys in the untouched source; the probe-only remainder is declared unmeasured.

No insertion contains a newline, so line numbers, backtraces and the stdlib line table stay exact.

Structs§

BranchKeyPlan
CaseClausePlan
CaseNoMatchPlan
CasePlan
case clauses are tested in order, so a clause was missed exactly when a later clause (or the implicit else) was selected. The runtime derives that per phase from the selected counts.
DerivedLogical
Edit
One text insertion the runtime applies to the original source before compiling it. Offsets are bytes into the original file; the runtime applies insertions from the end of the file backwards, so offsets stay valid.
HandlerTarget
ImpliedPlan
What observing one obligation also proves: the branch body it starts, the method it opens, the single-condition decision outcome it witnesses. Keyed by the statement (or decision outcome) whose hit implies the rest, so the runtime pays one hash lookup per first sighting and nothing per execution.
LoopTarget
MethodKeyPlan
PlanSpan
RubyFileObligations
RubyFilePlan
RubyProbePlan
StdlibDecision
StdlibKey
A Coverage branch key: the group type (if, case, &., while), the branch type (then, else, when, in, body) and the branch span in post-insertion coordinates.

Enums§

ConditionTree
Short-circuit structure of a decision. Leaves are condition indexes.
KeyKind
A source span in one-based lines and zero-based byte columns, the units Ruby’s Coverage module reports. Serialized as [[line, col], [line, col]]. What a stdlib key’s span names.
ProbeTarget
What a probe call reports. The runtime looks the key up and records the obligations named here.
RubyInstrumenterError

Constants§

BEGIN_BODY_LIMITATION
RACTOR_BLOCK_LIMITATION
A Ractor.new block cannot call the probes: a non-main Ractor cannot read the receiver global, so a probe there raises where the untouched program ran. Nothing is inserted inside one; what only a probe could prove there is unmeasured and declared at the block.
RUBY_PROBE_PLAN_VERSION
RUBY_PROBE_RECEIVER
Global the runtime binds its probe receiver to. Chosen to be unpronounceable in application code.

Functions§

apply_edits
Apply a plan’s edits to the original source the way the runtime does.
build_ruby_obligations
Build the complete obligation manifest and probe plan for one Ruby file. next_probe numbers probes uniquely across the whole project.