mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
* [ruby/prism] Accept a newline after the defined? keyword
[Bug #21197]
22be955ce9
* Fix a compilation error
Co-authored-by: Stan Lo <stan001212@gmail.com>
---------
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
Co-authored-by: Stan Lo <stan001212@gmail.com>
This commit is contained in:
parent
fd8a67fc8c
commit
1e3d24a0f4
5 changed files with 73 additions and 13 deletions
|
@ -664,13 +664,37 @@ module Prism
|
|||
# defined?(a)
|
||||
# ^^^^^^^^^^^
|
||||
def visit_defined_node(node)
|
||||
builder.keyword_cmd(
|
||||
:defined?,
|
||||
token(node.keyword_loc),
|
||||
token(node.lparen_loc),
|
||||
[visit(node.value)],
|
||||
token(node.rparen_loc)
|
||||
)
|
||||
# Very weird circumstances here where something like:
|
||||
#
|
||||
# defined?
|
||||
# (1)
|
||||
#
|
||||
# gets parsed in Ruby as having only the `1` expression but in parser
|
||||
# it gets parsed as having a begin. In this case we need to synthesize
|
||||
# that begin to match parser's behavior.
|
||||
if node.lparen_loc && node.keyword_loc.join(node.lparen_loc).slice.include?("\n")
|
||||
builder.keyword_cmd(
|
||||
:defined?,
|
||||
token(node.keyword_loc),
|
||||
nil,
|
||||
[
|
||||
builder.begin(
|
||||
token(node.lparen_loc),
|
||||
visit(node.value),
|
||||
token(node.rparen_loc)
|
||||
)
|
||||
],
|
||||
nil
|
||||
)
|
||||
else
|
||||
builder.keyword_cmd(
|
||||
:defined?,
|
||||
token(node.keyword_loc),
|
||||
token(node.lparen_loc),
|
||||
[visit(node.value)],
|
||||
token(node.rparen_loc)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# if foo then bar else baz end
|
||||
|
|
|
@ -1615,8 +1615,23 @@ module Prism
|
|||
# defined?(a)
|
||||
# ^^^^^^^^^^^
|
||||
def visit_defined_node(node)
|
||||
expression = visit(node.value)
|
||||
|
||||
# Very weird circumstances here where something like:
|
||||
#
|
||||
# defined?
|
||||
# (1)
|
||||
#
|
||||
# gets parsed in Ruby as having only the `1` expression but in Ripper it
|
||||
# gets parsed as having a parentheses node. In this case we need to
|
||||
# synthesize that node to match Ripper's behavior.
|
||||
if node.lparen_loc && node.keyword_loc.join(node.lparen_loc).slice.include?("\n")
|
||||
bounds(node.lparen_loc.join(node.rparen_loc))
|
||||
expression = on_paren(on_stmts_add(on_stmts_new, expression))
|
||||
end
|
||||
|
||||
bounds(node.location)
|
||||
on_defined(visit(node.value))
|
||||
on_defined(expression)
|
||||
end
|
||||
|
||||
# if foo then bar else baz end
|
||||
|
|
|
@ -19557,18 +19557,27 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|||
pm_token_t lparen;
|
||||
pm_token_t rparen;
|
||||
pm_node_t *expression;
|
||||
|
||||
context_push(parser, PM_CONTEXT_DEFINED);
|
||||
bool newline = accept1(parser, PM_TOKEN_NEWLINE);
|
||||
|
||||
if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
|
||||
lparen = parser->previous;
|
||||
expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1));
|
||||
|
||||
if (parser->recovering) {
|
||||
if (newline && accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
||||
expression = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, NULL, &parser->previous);
|
||||
lparen = not_provided(parser);
|
||||
rparen = not_provided(parser);
|
||||
} else {
|
||||
accept1(parser, PM_TOKEN_NEWLINE);
|
||||
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
|
||||
rparen = parser->previous;
|
||||
expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1));
|
||||
|
||||
if (parser->recovering) {
|
||||
rparen = not_provided(parser);
|
||||
} else {
|
||||
accept1(parser, PM_TOKEN_NEWLINE);
|
||||
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
|
||||
rparen = parser->previous;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lparen = not_provided(parser);
|
||||
|
|
3
test/prism/errors/defined_empty.txt
Normal file
3
test/prism/errors/defined_empty.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
defined?()
|
||||
^ expected an expression after `defined?`
|
||||
|
|
@ -8,3 +8,12 @@ defined? 1
|
|||
|
||||
defined?("foo"
|
||||
)
|
||||
|
||||
defined?
|
||||
1
|
||||
|
||||
defined?
|
||||
(1)
|
||||
|
||||
defined?
|
||||
()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue