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
Only build the parser's per-line coverage array when lines are being …
…counted

The parser grew and filled its array of starting line counts for every
parse made while coverage was set up, including Coverage.start(methods:
true), where CoverageData#prepareCoverage never looks at it, and
oneshot_lines, where it starts from an empty list instead. The file is
still registered with Coverage in every mode so that it appears in the
result.
  • Loading branch information
sferik committed Sep 14, 2026
commit 34ecb4a4222dd3bc67ff09c01297abe304c9bb4a
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/ext/coverage/CoverageData.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ public synchronized Map<String, FileCoverage> resetCoverage() {
* when lines are being measured.
*
* @param filename the file just parsed
* @param startingLines the initial per-line counts computed by the parser (-1 for lines without code)
* @param startingLines the initial per-line counts computed by the parser (-1 for lines without code); only
* consulted when lines are being counted
* @return the file's entry, or null when coverage is not set up or the file has no name
*/
public synchronized FileCoverage prepareCoverage(String filename, int[] startingLines) {
Expand Down
16 changes: 14 additions & 2 deletions core/src/main/java/org/jruby/parser/RubyParserBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -2416,13 +2416,24 @@ public boolean isCoverageEnabled() {
return runtime.isCoverageEnabled() && !isEval() || runtime.getCoverageData().isEvalCovered();
}

/**
* Does this parse need the per-line array of starting counts? Only when lines are being counted: methods mode
* has no use for it and oneshot_lines starts from an empty list (see CoverageData#prepareCoverage).
*/
private boolean isLineCountingEnabled() {
if (!isCoverageEnabled()) return false;

CoverageData data = runtime.getCoverageData();
return data.isLinesEnabled() && !data.isOneshot();
}

/**
* Zero out coverable lines as they're encountered
*/
public void coverLine(int i) {
// We had an overflow so we cannot mark whatever line this is as covered.
if (i < 0) return;
if (isCoverageEnabled()) {
if (isLineCountingEnabled()) {
growCoverageLines(i);
coverage[i] = 0;
}
Expand Down Expand Up @@ -2452,7 +2463,8 @@ public void growCoverageLines(int i) {
public CoverageData finishCoverage(String file, int lines) {
if (!isCoverageEnabled()) return null;

growCoverageLines(lines);
// the file is registered with Coverage in every mode; the line array is only filled in when lines are counted
if (isLineCountingEnabled()) growCoverageLines(lines);
CoverageData data = runtime.getCoverageData();
data.prepareCoverage(file, coverage);
return data;
Expand Down