Skip to content

Commit 3532e92

Browse files
committed
Use CRuby's helpers for node locations in the grammar
The grammar set where undef statements, list and hash literals and strings start, and unmarked the lone statement of an interpolation, inline. Those rules now read as CRuby's do, calling nd_set_first_loc, make_list, nd_set_loc and nd_unset_fl_newline, which RubyParserBase implements for our nodes. nd_set_first_loc was an empty stub until now, so the find and hash patterns that call it (Const(...) and Const[...]) now start at their constant, as in CRuby. Both parsers were regenerated with jay.
1 parent f1f877a commit 3532e92

3 files changed

Lines changed: 67 additions & 72 deletions

File tree

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

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,10 +2198,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
21982198
};
21992199
states[30] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
22002200
/*%%%*/
2201-
/* The statement starts at undef, not at the first name it undefines*/
2202-
if (((Node)yyVals[0+yyTop].value) instanceof BlockNode block) block.get(0).setLine(yyVals[yyTop - count + 1].start());
2203-
((Node)yyVals[0+yyTop].value).setLine(yyVals[yyTop - count + 1].start());
2204-
yyVal = ((Node)yyVals[0+yyTop].value);
2201+
yyVal = p.nd_set_first_loc(((Node)yyVals[0+yyTop].value), yyVals[yyTop - count + 1].start());
22052202
/*% %*/
22062203
/*% ripper: undef!($2) %*/
22072204
return yyVal;
@@ -4142,22 +4139,15 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
41424139
};
41434140
states[359] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
41444141
/*%%%*/
4145-
Integer position = yyVals[yyTop - count + 1].start();
4146-
if (((Node)yyVals[-1+yyTop].value) == null) {
4147-
yyVal = new ZArrayNode(position); /* zero length array */
4148-
} else {
4149-
yyVal = ((Node)yyVals[-1+yyTop].value);
4150-
((Node)yyVal).setLine(position); /* where it starts, not where its first element is */
4151-
}
4142+
yyVal = p.make_list(((Node)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
41524143
/*% %*/
41534144
/*% ripper: array!(escape_Qundef($2)) %*/
41544145
return yyVal;
41554146
};
41564147
states[360] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
41574148
/*%%%*/
4158-
yyVal = ((HashNode)yyVals[-1+yyTop].value);
4149+
yyVal = p.nd_set_loc(((HashNode)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
41594150
((HashNode)yyVal).setIsLiteral();
4160-
((HashNode)yyVal).setLine(yyVals[yyTop - count + 1].start());
41614151
/*% %*/
41624152
/*% ripper: hash!(escape_Qundef($2)) %*/
41634153
return yyVal;
@@ -5718,7 +5708,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
57185708
states[633] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
57195709
/*%%%*/
57205710
p.heredoc_dedent(((Node)yyVals[-1+yyTop].value));
5721-
if (((Node)yyVals[-1+yyTop].value) != null) ((Node)yyVals[-1+yyTop].value).setLine(yyVals[yyTop - count + 1].start()); /* where it starts, not where its contents end */
5711+
if (((Node)yyVals[-1+yyTop].value) != null) p.nd_set_loc(((Node)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
57225712
yyVal = ((Node)yyVals[-1+yyTop].value);
57235713
/*% %*/
57245714
/*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
@@ -5754,8 +5744,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
57545744
};
57555745
states[638] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
57565746
/*%%%*/
5757-
yyVal = ((ListNode)yyVals[-1+yyTop].value);
5758-
((Node)yyVal).setLine(yyVals[yyTop - count + 1].start());
5747+
yyVal = p.make_list(((ListNode)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
57595748
/*% %*/
57605749
/*% ripper: array!($3) %*/
57615750
return yyVal;
@@ -5788,8 +5777,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
57885777
};
57895778
states[643] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
57905779
/*%%%*/
5791-
yyVal = ((ListNode)yyVals[-1+yyTop].value);
5792-
((Node)yyVal).setLine(yyVals[yyTop - count + 1].start());
5780+
yyVal = p.make_list(((ListNode)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
57935781
/*% %*/
57945782
/*% ripper: array!($3) %*/
57955783
return yyVal;
@@ -5810,16 +5798,14 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
58105798
};
58115799
states[646] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
58125800
/*%%%*/
5813-
yyVal = ((ListNode)yyVals[-1+yyTop].value);
5814-
((Node)yyVal).setLine(yyVals[yyTop - count + 1].start());
5801+
yyVal = p.make_list(((ListNode)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
58155802
/*% %*/
58165803
/*% ripper: array!($3) %*/
58175804
return yyVal;
58185805
};
58195806
states[647] = (RubyParser p, Object yyVal, ProductionState[] yyVals, int yyTop, int count, int yychar) -> {
58205807
/*%%%*/
5821-
yyVal = ((ListNode)yyVals[-1+yyTop].value);
5822-
((Node)yyVal).setLine(yyVals[yyTop - count + 1].start());
5808+
yyVal = p.make_list(((ListNode)yyVals[-1+yyTop].value), yyVals[yyTop - count + 1].start());
58235809
/*% %*/
58245810
/*% ripper: array!($3) %*/
58255811
return yyVal;
@@ -5951,17 +5937,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
59515937
p.setHeredocLineIndent(-1);
59525938

59535939
/*%%%*/
5954-
if (((Node)yyVals[-1+yyTop].value) != null) {
5955-
/* A lone statement in an interpolation is not a line event of its own (MRI); the*/
5956-
/* string it is part of is. Several statements in one interpolation each remain one, and so*/
5957-
/* does a lone conditional, as MRI counts its branches.*/
5958-
/* MRI's compiler marks coverable lines from the newline flag, but newline_node marked*/
5959-
/* this one already, so undo that too (it was the last line newline_node marked).*/
5960-
if (!(((Node)yyVals[-1+yyTop].value) instanceof IfNode)) {
5961-
if (((Node)yyVals[-1+yyTop].value).isNewline()) p.uncoverLastLine();
5962-
((Node)yyVals[-1+yyTop].value).unsetNewline();
5963-
}
5964-
}
5940+
if (((Node)yyVals[-1+yyTop].value) != null) p.nd_unset_fl_newline(((Node)yyVals[-1+yyTop].value));
59655941
yyVal = p.newEvStrNode(yyVals[yyTop - count + 6].start(), ((Node)yyVals[-1+yyTop].value));
59665942
/*% %*/
59675943
/*% ripper: string_embexpr!($6) %*/
@@ -6884,7 +6860,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
68846860
return yyVal;
68856861
};
68866862
}
6887-
// line 4891 "parse.y"
6863+
// line 4867 "parse.y"
68886864

68896865
}
6890-
// line 15216 "-"
6866+
// line 15192 "-"

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

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,7 @@ stmt : keyword_alias fitem {
616616
}
617617
| keyword_undef undef_list {
618618
/*%%%*/
619-
// The statement starts at undef, not at the first name it undefines
620-
if ($2 instanceof BlockNode block) block.get(0).setLine(@1.start());
621-
$2.setLine(@1.start());
622-
$$ = $2;
619+
$$ = p.nd_set_first_loc($2, @1.start());
623620
/*% %*/
624621
/*% ripper: undef!($2) %*/
625622
}
@@ -2346,21 +2343,14 @@ primary : literal
23462343
}
23472344
| tLBRACK aref_args ']' {
23482345
/*%%%*/
2349-
Integer position = @1.start();
2350-
if ($2 == null) {
2351-
$$ = new ZArrayNode(position); /* zero length array */
2352-
} else {
2353-
$$ = $2;
2354-
$<Node>$.setLine(position); /* where it starts, not where its first element is */
2355-
}
2346+
$$ = p.make_list($2, @1.start());
23562347
/*% %*/
23572348
/*% ripper: array!(escape_Qundef($2)) %*/
23582349
}
23592350
| tLBRACE assoc_list '}' {
23602351
/*%%%*/
2361-
$$ = $2;
2352+
$$ = p.nd_set_loc($2, @1.start());
23622353
$<HashNode>$.setIsLiteral();
2363-
$<HashNode>$.setLine(@1.start());
23642354
/*% %*/
23652355
/*% ripper: hash!(escape_Qundef($2)) %*/
23662356
}
@@ -3830,7 +3820,7 @@ string : tCHAR {
38303820
string1 : tSTRING_BEG string_contents tSTRING_END {
38313821
/*%%%*/
38323822
p.heredoc_dedent($2);
3833-
if ($2 != null) $2.setLine(@1.start()); /* where it starts, not where its contents end */
3823+
if ($2 != null) p.nd_set_loc($2, @1.start());
38343824
$$ = $2;
38353825
/*% %*/
38363826
/*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
@@ -3869,8 +3859,7 @@ words_sep : ' ' {
38693859
// [!null] - ListNode
38703860
words : tWORDS_BEG words_sep word_list tSTRING_END {
38713861
/*%%%*/
3872-
$$ = $3;
3873-
$<Node>$.setLine(@1.start());
3862+
$$ = p.make_list($3, @1.start());
38743863
/*% %*/
38753864
/*% ripper: array!($3) %*/
38763865
};
@@ -3904,8 +3893,7 @@ word : string_content {
39043893

39053894
symbols : tSYMBOLS_BEG words_sep symbol_list tSTRING_END {
39063895
/*%%%*/
3907-
$$ = $3;
3908-
$<Node>$.setLine(@1.start());
3896+
$$ = p.make_list($3, @1.start());
39093897
/*% %*/
39103898
/*% ripper: array!($3) %*/
39113899
};
@@ -3926,17 +3914,15 @@ symbol_list : /* none */ {
39263914
// [!null] - ListNode
39273915
qwords : tQWORDS_BEG words_sep qword_list tSTRING_END {
39283916
/*%%%*/
3929-
$$ = $3;
3930-
$<Node>$.setLine(@1.start());
3917+
$$ = p.make_list($3, @1.start());
39313918
/*% %*/
39323919
/*% ripper: array!($3) %*/
39333920
};
39343921

39353922
// [!null] - ListNode
39363923
qsymbols : tQSYMBOLS_BEG words_sep qsym_list tSTRING_END {
39373924
/*%%%*/
3938-
$$ = $3;
3939-
$<Node>$.setLine(@1.start());
3925+
$$ = p.make_list($3, @1.start());
39403926
/*% %*/
39413927
/*% ripper: array!($3) %*/
39423928
};
@@ -4057,17 +4043,7 @@ string_content : tSTRING_CONTENT {
40574043
p.setHeredocLineIndent(-1);
40584044

40594045
/*%%%*/
4060-
if ($6 != null) {
4061-
// A lone statement in an interpolation is not a line event of its own (MRI); the
4062-
// string it is part of is. Several statements in one interpolation each remain one, and so
4063-
// does a lone conditional, as MRI counts its branches.
4064-
// MRI's compiler marks coverable lines from the newline flag, but newline_node marked
4065-
// this one already, so undo that too (it was the last line newline_node marked).
4066-
if (!($6 instanceof IfNode)) {
4067-
if ($6.isNewline()) p.uncoverLastLine();
4068-
$6.unsetNewline();
4069-
}
4070-
}
4046+
if ($6 != null) p.nd_unset_fl_newline($6);
40714047
$$ = p.newEvStrNode(@6.start(), $6);
40724048
/*% %*/
40734049
/*% ripper: string_embexpr!($6) %*/

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

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,53 @@ public Node newline_node(Node node, int line) {
507507
return node;
508508
}
509509

510+
/**
511+
* CRuby's nd_set_first_loc: the node starts at line. Our nodes only have a line, so that is what moves. An
512+
* undef_list is a BlockNode of UndefNodes here (one NODE_UNDEF in CRuby), so its first statement starts there
513+
* too.
514+
*/
515+
public Node nd_set_first_loc(Node node, int line) {
516+
if (node instanceof BlockNode block) block.get(0).setLine(line);
517+
node.setLine(line);
518+
519+
return node;
520+
}
521+
522+
/**
523+
* CRuby's nd_set_loc, for the line: the node starts at line.
524+
*/
525+
public Node nd_set_loc(Node node, int line) {
526+
node.setLine(line);
527+
528+
return node;
529+
}
530+
531+
/**
532+
* CRuby's make_list, for the line: a list literal starts at line, not at its first element.
533+
*/
534+
public Node make_list(Node list, int line) {
535+
if (list == null) return new ZArrayNode(line);
536+
537+
list.setLine(line);
538+
539+
return list;
540+
}
541+
542+
/**
543+
* CRuby's nd_unset_fl_newline, for the statements of a string interpolation: a lone statement there is not a
544+
* line event of its own; the string it is part of is. Several statements each remain one, and so does a lone
545+
* conditional, as MRI counts its branches.
546+
*
547+
* CRuby's compiler finds coverable lines from the newline flag, but JRuby marks them as it parses, and
548+
* newline_node marked this statement's line already (the last line it marked), so that is undone too.
549+
*/
550+
public void nd_unset_fl_newline(Node node) {
551+
if (node instanceof IfNode) return;
552+
553+
if (node.isNewline()) uncoverLastLine();
554+
node.unsetNewline();
555+
}
556+
510557
// This is the last node made in the AST unintuitively so so post-processing can occur here.
511558
public Node addRootNode(Node topOfAST) {
512559
int line;
@@ -2241,10 +2288,6 @@ public Node remove_begin(Node node) {
22412288
return node;
22422289
}
22432290

2244-
public void nd_set_first_loc(Node node, int line) {
2245-
// FIXME: IMPL
2246-
}
2247-
22482291
public RubyParserResult parse() throws IOException {
22492292
yyparse(lexer, runtime.getInstanceConfig().isDebug() ? new YYDebug() : null);
22502293

0 commit comments

Comments
 (0)