Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c19d83e
Implement method coverage
sferik Sep 14, 2026
c7cf3b8
Do not leave a method coverage counter pending when a define_method c…
sferik Sep 14, 2026
90d08e4
Count method coverage for the initialize of Java subclasses
sferik Sep 14, 2026
34ecb4a
Only build the parser's per-line coverage array when lines are being …
sferik Sep 14, 2026
032c5fc
Use a plain list for a file's method coverage entries
sferik Sep 14, 2026
86e4423
Do the method coverage hand-off from one place per interpreted method…
sferik Sep 15, 2026
15e85ab
Rewrite the method coverage comments in plain, compact English
sferik Sep 15, 2026
664db68
Count method coverage for methods defined by an eval
sferik Sep 16, 2026
107c4ad
Set the line and source span of blocks that follow command arguments
sferik Sep 16, 2026
8ba51d8
Encode the operand of the method coverage instruction
sferik Sep 16, 2026
533a68a
Report whether a line was actually counted
sferik Sep 16, 2026
9f9b455
Keep the unknown span marker out of method coverage keys
sferik Sep 16, 2026
caf18c6
Key a method coverage entry by the name it was defined under
sferik Sep 16, 2026
9894de3
Detach method coverage counters when measurement stops
sferik Sep 16, 2026
b9ee86c
Let the super-forwarding scan skip the method coverage instructions
sferik Sep 16, 2026
a12ddd6
Clear a method coverage counter atomically
sferik Sep 16, 2026
102a76f
Build the coverage result outside the CoverageData lock
sferik Sep 16, 2026
f2756ad
Keep method registration off the lock when methods are not measured
sferik Sep 16, 2026
3f3421c
Read and clear the coverage counts in one step
sferik Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Report whether a line was actually counted
IRRuntimeHelpers.coverLine promised "true if the line was counted" but
returned true as soon as coverage was running, before CoverageData
decided whether it had anywhere to put the count. CoverageData.coverLine
gives up silently on a negative line, an untracked file, a file with no
line counts, and a line past the end of them.

Both callers now act on that answer: the interpreter and the indy
coverage site disarm a oneshot probe once the line is counted, so a
probe whose line had nowhere to go disarmed itself and lost the line for
good. It now stays armed, which is what the caller already assumed.
  • Loading branch information
sferik committed Sep 16, 2026
commit 533a68ad869541e6b9c62b38a290bfa73d2b5514
34 changes: 19 additions & 15 deletions core/src/main/java/org/jruby/ext/coverage/CoverageData.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,35 @@ public Map<String, FileCoverage> getCoverage() {
/**
* Update coverage data for the given file and line number.
*
* @param filename
* @param line
* @param filename the file the line belongs to
* @param line zero-based line number
* @return true if the line was counted. False if there is nowhere to count it: a negative line, an
* untracked file, a file with no line counts, or a line past the end of them.
*/
public synchronized void coverLine(String filename, int line) {
public synchronized boolean coverLine(String filename, int line) {
Map<String, FileCoverage> coverage = this.coverage;

if (coverage == null) return false;

// negative lines are not included in coverage
if (line < 0) return;
if (line < 0) return false;

if (coverage != null) {
FileCoverage file = coverage.get(filename);
FileCoverage file = coverage.get(filename);

if (file == null) return;
if (file == null) return false;

IntList lines = file.getLines();
IntList lines = file.getLines();

if (lines == null) return;
if (lines == null) return false;

if (isOneshot()) {
lines.add(line);
} else {
if (lines.size() <= line) return;
lines.set(line, lines.get(line) + 1);
}
if (isOneshot()) {
lines.add(line);
} else {
if (lines.size() <= line) return false;
lines.set(line, lines.get(line) + 1);
}

return true;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,9 +720,7 @@ public static boolean coverLine(ThreadContext context, String filename, int line

if (!data.isRunning()) return false;

data.coverLine(filename, line);

return true;
return data.coverLine(filename, line);
}

@JIT @Interp
Expand Down