Skip to content

Commit 7d1969d

Browse files
committed
Make defined? (x;) return expression when using parse.y parser
Follow up [Bug #21029]. Currently, `defined? (x;)` returns `expression` when using Prism parser. See: - #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 a02dcbf commit 7d1969d

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy