summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-10-02 10:29:07 -0400
committergit <svn-admin@ruby-lang.org>2024-10-02 14:47:53 +0000
commit2e2520ef10d4cbb86123adcb75e5aab664813bec (patch)
treedf520f516187279b34af779e1a37fd0d4fdd9318
parente41e4bacb1664e4f74e7c00f83e0bc81eee897c6 (diff)
[ruby/prism] Fix up beginless ranges in method definitions
https://github.com/ruby/prism/commit/ab9d80987a
-rw-r--r--prism/prism.c29
-rw-r--r--test/prism/fixtures/range_beginless.txt5
-rw-r--r--test/prism/snapshots/range_beginless.txt114
3 files changed, 138 insertions, 10 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 3549b59286..7b4b7828fd 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -11452,10 +11452,7 @@ parser_lex(pm_parser_t *parser) {
if (match(parser, '.')) {
if (match(parser, '.')) {
// If we're _not_ inside a range within default parameters
- if (
- !context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) &&
- context_p(parser, PM_CONTEXT_DEF_PARAMS)
- ) {
+ if (!context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) && context_p(parser, PM_CONTEXT_DEF_PARAMS)) {
if (lex_state_p(parser, PM_LEX_STATE_END)) {
lex_state_set(parser, PM_LEX_STATE_BEG);
} else {
@@ -14571,9 +14568,10 @@ parse_parameters(
bool repeated = pm_parser_parameter_name_check(parser, &name);
pm_parser_local_add_token(parser, &name, 1);
- if (accept1(parser, PM_TOKEN_EQUAL)) {
- pm_token_t operator = parser->previous;
+ if (match1(parser, PM_TOKEN_EQUAL)) {
+ pm_token_t operator = parser->current;
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
+ parser_lex(parser);
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &name);
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
@@ -14624,6 +14622,8 @@ parse_parameters(
case PM_TOKEN_LABEL: {
if (!uses_parentheses) parser->in_keyword_arg = true;
update_parameter_state(parser, &parser->current, &order);
+
+ context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
parser_lex(parser);
pm_token_t name = parser->previous;
@@ -14643,15 +14643,20 @@ parse_parameters(
case PM_TOKEN_COMMA:
case PM_TOKEN_PARENTHESIS_RIGHT:
case PM_TOKEN_PIPE: {
+ context_pop(parser);
+
pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name);
if (repeated) {
pm_node_flag_set_repeated_parameter(param);
}
+
pm_parameters_node_keywords_append(params, param);
break;
}
case PM_TOKEN_SEMICOLON:
case PM_TOKEN_NEWLINE: {
+ context_pop(parser);
+
if (uses_parentheses) {
looping = false;
break;
@@ -14661,6 +14666,7 @@ parse_parameters(
if (repeated) {
pm_node_flag_set_repeated_parameter(param);
}
+
pm_parameters_node_keywords_append(params, param);
break;
}
@@ -14668,8 +14674,6 @@ parse_parameters(
pm_node_t *param;
if (token_begins_expression_p(parser->current.type)) {
- context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
-
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &local);
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
@@ -14681,7 +14685,6 @@ parse_parameters(
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_PARAMETER_CIRCULAR);
}
- context_pop(parser);
param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
}
else {
@@ -14691,6 +14694,8 @@ parse_parameters(
if (repeated) {
pm_node_flag_set_repeated_parameter(param);
}
+
+ context_pop(parser);
pm_parameters_node_keywords_append(params, param);
// If parsing the value of the parameter resulted in error recovery,
@@ -19246,6 +19251,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
lex_state_set(parser, PM_LEX_STATE_BEG);
parser->command_start = true;
+ context_pop(parser);
if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_DEF_PARAMS_TERM_PAREN, pm_token_type_human(parser->current.type));
parser->previous.start = parser->previous.end;
@@ -19265,17 +19271,20 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
lparen = not_provided(parser);
rparen = not_provided(parser);
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true, true, (uint16_t) (depth + 1));
+
+ context_pop(parser);
break;
}
default: {
lparen = not_provided(parser);
rparen = not_provided(parser);
params = NULL;
+
+ context_pop(parser);
break;
}
}
- context_pop(parser);
pm_node_t *statements = NULL;
pm_token_t equal;
pm_token_t end_keyword;
diff --git a/test/prism/fixtures/range_beginless.txt b/test/prism/fixtures/range_beginless.txt
new file mode 100644
index 0000000000..a55b9b57e7
--- /dev/null
+++ b/test/prism/fixtures/range_beginless.txt
@@ -0,0 +1,5 @@
+def f(x = ...?a); end
+
+def f(x: ...?a); end
+
+def f() ...:a; end
diff --git a/test/prism/snapshots/range_beginless.txt b/test/prism/snapshots/range_beginless.txt
new file mode 100644
index 0000000000..800f087dc1
--- /dev/null
+++ b/test/prism/snapshots/range_beginless.txt
@@ -0,0 +1,114 @@
+@ ProgramNode (location: (1,0)-(5,18))
+├── flags: ∅
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,18))
+ ├── flags: ∅
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(1,21))
+ │ ├── flags: newline
+ │ ├── name: :f
+ │ ├── name_loc: (1,4)-(1,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "x"
+ │ │ │ ├── operator_loc: (1,8)-(1,9) = "="
+ │ │ │ └── value:
+ │ │ │ @ RangeNode (location: (1,10)-(1,15))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ StringNode (location: (1,13)-(1,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (1,13)-(1,14) = "?"
+ │ │ │ │ ├── content_loc: (1,14)-(1,15) = "a"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ └── operator_loc: (1,10)-(1,13) = "..."
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ ├── rparen_loc: (1,15)-(1,16) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,18)-(1,21) = "end"
+ ├── @ DefNode (location: (3,0)-(3,20))
+ │ ├── flags: newline
+ │ ├── name: :f
+ │ ├── name_loc: (3,4)-(3,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,6)-(3,14))
+ │ │ ├── flags: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (3,6)-(3,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (3,6)-(3,8) = "x:"
+ │ │ │ └── value:
+ │ │ │ @ RangeNode (location: (3,9)-(3,14))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ StringNode (location: (3,12)-(3,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (3,12)-(3,13) = "?"
+ │ │ │ │ ├── content_loc: (3,13)-(3,14) = "a"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ └── operator_loc: (3,9)-(3,12) = "..."
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,5)-(3,6) = "("
+ │ ├── rparen_loc: (3,14)-(3,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,17)-(3,20) = "end"
+ └── @ DefNode (location: (5,0)-(5,18))
+ ├── flags: newline
+ ├── name: :f
+ ├── name_loc: (5,4)-(5,5) = "f"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (5,8)-(5,13))
+ │ ├── flags: ∅
+ │ └── body: (length: 1)
+ │ └── @ RangeNode (location: (5,8)-(5,13))
+ │ ├── flags: newline, exclude_end
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ SymbolNode (location: (5,11)-(5,13))
+ │ │ ├── flags: static_literal, forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,11)-(5,12) = ":"
+ │ │ ├── value_loc: (5,12)-(5,13) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ └── operator_loc: (5,8)-(5,11) = "..."
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (5,5)-(5,6) = "("
+ ├── rparen_loc: (5,6)-(5,7) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,15)-(5,18) = "end"