Skip to content

Commit d174e99

Browse files
committed
Make each arm of a ternary a line event
MRI parses the arms of a ternary as statements, so each is a line event of its own: in x = y.size ?\n 1 : 2, the arm on the second line is counted by line coverage and reported to line tracing. JRuby parsed them as plain expressions, so that line read nil.
1 parent 0f34fae commit d174e99

3 files changed

Lines changed: 19 additions & 4 deletions

File tree

‎core/src/main/java/org/jruby/parser/RubyParser.java‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3716,7 +3716,8 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
37163716
states[286] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
37173717
/*%%%*/
37183718
p.value_expr(((Node)yyVals[-5+yyTop].value));
3719-
yyVal = p.new_if(yyVals[yyTop - count + 1].start(), ((Node)yyVals[-5+yyTop].value), ((Node)yyVals[-3+yyTop].value), ((Node)yyVals[0+yyTop].value));
3719+
/* Each arm of a ternary is a statement of its own for line events, as in MRI.*/
3720+
yyVal = p.new_if(yyVals[yyTop - count + 1].start(), ((Node)yyVals[-5+yyTop].value), p.newline_node(((Node)yyVals[-3+yyTop].value), yyVals[yyTop - count + 3].start()), p.newline_node(((Node)yyVals[0+yyTop].value), yyVals[yyTop - count + 6].start()));
37203721
/*% %*/
37213722
/*% ripper: ifop!($1, $3, $6) %*/
37223723
return yyVal;
@@ -6883,7 +6884,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
68836884
return yyVal;
68846885
};
68856886
}
6886-
// line 4890 "parse.y"
6887+
// line 4891 "parse.y"
68876888

68886889
}
6889-
// line 15215 "-"
6890+
// line 15216 "-"

‎core/src/main/java/org/jruby/parser/RubyParser.y‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,8 @@ arg : lhs '=' lex_ctxt arg_rhs {
19451945
| arg '?' arg opt_nl ':' arg {
19461946
/*%%%*/
19471947
p.value_expr($1);
1948-
$$ = p.new_if(@1.start(), $1, $3, $6);
1948+
// Each arm of a ternary is a statement of its own for line events, as in MRI.
1949+
$$ = p.new_if(@1.start(), $1, p.newline_node($3, @3.start()), p.newline_node($6, @6.start()));
19491950
/*% %*/
19501951
/*% ripper: ifop!($1, $3, $6) %*/
19511952
}

‎test/jruby/test_coverage.rb‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,19 @@ class UndefCoverage
419419
RUBY
420420
end
421421

422+
def test_ternary_arms_are_line_events
423+
assert_equal [1, 1, 1, 1, 0, 1, 1, nil], line_coverage(<<~'RUBY')
424+
y = [1]
425+
x = y.size ?
426+
1 : 2
427+
if y.empty? ?
428+
y.first :
429+
y.last
430+
z = 1
431+
end
432+
RUBY
433+
end
434+
422435
private
423436

424437
def with_source(source)

0 commit comments

Comments
 (0)