Skip to content

Commit f0649ab

Browse files
S-H-GAMELINKSnobu
authored andcommitted
Make defined? (x;) return expression when using parse.y parser
Follow up [Bug #21029]. Currently, `defined? (x;)` returns `expression` when using Prism parser. See: - ruby#12949 - https://bugs.ruby-lang.org/issues/21029 However, `defined? (x;)` returns nil when using parse.y, as reported in bug ticket comment and test-all (when using parse.y parser) test result. This change adds a context flag to track trailing semicolons in defined? scope. When a trailing semicolon is detected within a defined? scope, the generated AST node is wrapped with NODE_BLOCK. This change ensures consistent behavior with `defined? (;x)` .
1 parent 54ec482 commit f0649ab

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

parse.y

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ struct lex_context {
314314
unsigned int in_argdef: 1;
315315
unsigned int in_def: 1;
316316
unsigned int in_class: 1;
317+
unsigned int has_trailing_semicolon: 1;
317318
BITFIELD(enum rb_parser_shareability, shareable_constant_value, 2);
318319
BITFIELD(enum rescue_context, in_rescue, 2);
319320
unsigned int cant_return: 1;
@@ -4041,6 +4042,7 @@ arg : asgn(arg_rhs)
40414042
{
40424043
p->ctxt.in_defined = $3.in_defined;
40434044
$$ = new_defined(p, $4, &@$);
4045+
p->ctxt.has_trailing_semicolon = $3.has_trailing_semicolon;
40444046
/*% ripper: defined!($:4) %*/
40454047
}
40464048
| def_endless_method(endless_arg)
@@ -4428,6 +4430,7 @@ primary : inline_primary
44284430
{
44294431
p->ctxt.in_defined = $4.in_defined;
44304432
$$ = new_defined(p, $5, &@$);
4433+
p->ctxt.has_trailing_semicolon = $4.has_trailing_semicolon;
44314434
/*% ripper: defined!($:5) %*/
44324435
}
44334436
| keyword_not '(' expr rparen
@@ -6706,7 +6709,14 @@ trailer : '\n'?
67066709
| ','
67076710
;
67086711

6709-
term : ';' {yyerrok;token_flush(p);}
6712+
term : ';'
6713+
{
6714+
yyerrok;
6715+
token_flush(p);
6716+
if (p->ctxt.in_defined) {
6717+
p->ctxt.has_trailing_semicolon = 1;
6718+
}
6719+
}
67106720
| '\n'
67116721
{
67126722
@$.end_pos = @$.beg_pos;
@@ -13013,6 +13023,9 @@ kwd_append(rb_node_kw_arg_t *kwlist, rb_node_kw_arg_t *kw)
1301313023
static NODE *
1301413024
new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
1301513025
{
13026+
int had_trailing_semicolon = p->ctxt.has_trailing_semicolon;
13027+
p->ctxt.has_trailing_semicolon = 0;
13028+
1301613029
NODE *n = expr;
1301713030
while (n) {
1301813031
if (nd_type_p(n, NODE_BEGIN)) {
@@ -13025,6 +13038,12 @@ new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
1302513038
break;
1302613039
}
1302713040
}
13041+
13042+
if (had_trailing_semicolon && !nd_type_p(expr, NODE_BLOCK)) {
13043+
NODE *block = NEW_BLOCK(expr, loc);
13044+
return NEW_DEFINED(block, loc);
13045+
}
13046+
1302813047
return NEW_DEFINED(n, loc);
1302913048
}
1303013049

0 commit comments

Comments
 (0)