Include zero-hit executable lines in coverage reports#219
Conversation
- Emit LCOV and JSON entries for executable lines with zero hits - Load source files to derive executable line maps when available - Fall back to existing hit-only reporting when source is unavailable
📝 WalkthroughWalkthroughThe LCOV and JSON coverage report output now includes all executable lines with their hit counts, not only lines with hits. It loads source code to identify executable lines and updates line totals accordingly, with fallback to original behavior if source loading fails. Changes
Sequence DiagramsequenceDiagram
participant Reporter as Coverage Reporter
participant SourceLoader as Source Loader
participant ExecDetector as Executable Line Detector
participant LCOVWriter as LCOV Output
participant JSONWriter as JSON Output
Reporter->>SourceLoader: Load source file
alt Source available
SourceLoader-->>Reporter: SourceLines, HasSource=true
Reporter->>ExecDetector: BuildExecutableLineFlags(SourceLines)
ExecDetector-->>Reporter: ExecutableFlags bitmap
Reporter->>LCOVWriter: Iterate all executable lines
loop For each executable line
LCOVWriter->>LCOVWriter: Emit DA:<line>,<hitcount>
LCOVWriter->>LCOVWriter: Track LinesHitCount
end
LCOVWriter->>LCOVWriter: Update LH: with LinesHitCount
Reporter->>JSONWriter: Iterate all executable lines
loop For each executable line
JSONWriter->>JSONWriter: Emit "s" entry with count
JSONWriter->>JSONWriter: Add "statementMap" range
end
else Source unavailable
SourceLoader-->>Reporter: HasSource=false
Reporter->>LCOVWriter: Emit only hit lines (legacy behavior)
Reporter->>JSONWriter: Emit only hit lines (legacy behavior)
end
Reporter->>Reporter: Free SourceLines
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Suite Timing
Measured on ubuntu-latest x64. |
Benchmark Results274 benchmarks Interpreted: 🟢 184 improved · 🔴 32 regressed · 58 unchanged · avg +3.8% arraybuffer.js — Interp: 🟢 13, 🔴 1 · avg +8.0% · Bytecode: 🟢 1, 🔴 4, 9 unch. · avg -0.8%
arrays.js — Interp: 🟢 19 · avg +7.1% · Bytecode: 🟢 8, 🔴 2, 9 unch. · avg +1.2%
async-await.js — Interp: 🟢 6 · avg +6.9% · Bytecode: 🔴 1, 5 unch. · avg -1.0%
classes.js — Interp: 🟢 31 · avg +8.7% · Bytecode: 🟢 2, 🔴 4, 25 unch. · avg +0.2%
closures.js — Interp: 🟢 10, 1 unch. · avg +4.7% · Bytecode: 🟢 1, 🔴 2, 8 unch. · avg -1.2%
collections.js — Interp: 🟢 3, 🔴 7, 2 unch. · avg -1.3% · Bytecode: 🟢 4, 🔴 2, 6 unch. · avg +0.4%
destructuring.js — Interp: 🟢 22 · avg +6.8% · Bytecode: 🟢 5, 🔴 8, 9 unch. · avg -0.1%
fibonacci.js — Interp: 🟢 5, 3 unch. · avg +0.9% · Bytecode: 🟢 4, 🔴 1, 3 unch. · avg +1.9%
for-of.js — Interp: 🔴 1, 6 unch. · avg -0.8% · Bytecode: 🟢 1, 🔴 1, 5 unch. · avg -1.0%
helpers/bench-module.js — Interp: 0 · Bytecode: 0
iterators.js — Interp: 🟢 7, 13 unch. · avg +1.2% · Bytecode: 🟢 6, 🔴 7, 7 unch. · avg -0.2%
json.js — Interp: 🟢 19, 1 unch. · avg +5.7% · Bytecode: 🟢 2, 🔴 4, 14 unch. · avg -1.4%
jsx.jsx — Interp: 🟢 15, 6 unch. · avg +3.4% · Bytecode: 🔴 11, 10 unch. · avg -2.0%
modules.js — Interp: 🟢 3, 6 unch. · avg +0.8% · Bytecode: 🟢 3, 6 unch. · avg +0.3%
numbers.js — Interp: 🟢 11 · avg +5.9% · Bytecode: 🟢 2, 🔴 2, 7 unch. · avg +0.0%
objects.js — Interp: 🟢 2, 🔴 2, 3 unch. · avg +1.8% · Bytecode: 🔴 2, 5 unch. · avg -1.6%
promises.js — Interp: 🔴 6, 6 unch. · avg -3.9% · Bytecode: 🔴 7, 5 unch. · avg -2.0%
regexp.js — Interp: 🟢 6, 🔴 2, 3 unch. · avg +1.5% · Bytecode: 🟢 2, 🔴 1, 8 unch. · avg +0.1%
strings.js — Interp: 🟢 4, 🔴 3, 4 unch. · avg -0.3% · Bytecode: 🔴 1, 10 unch. · avg -0.5%
typed-arrays.js — Interp: 🟢 8, 🔴 10, 4 unch. · avg +1.5% · Bytecode: 🟢 7, 🔴 4, 11 unch. · avg +0.9%
Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
Summary
Fixes #203
Testing
./build.pas testrunner && ./build/TestRunner tests.