@@ -6603,6 +6603,7 @@ context_terminator(pm_context_t context, pm_token_t *token) {
6603
6603
case PM_CONTEXT_ELSE:
6604
6604
case PM_CONTEXT_FOR:
6605
6605
case PM_CONTEXT_ENSURE:
6606
+ case PM_CONTEXT_ENSURE_DEF:
6606
6607
return token->type == PM_TOKEN_KEYWORD_END;
6607
6608
case PM_CONTEXT_FOR_INDEX:
6608
6609
return token->type == PM_TOKEN_KEYWORD_IN;
@@ -6623,8 +6624,10 @@ context_terminator(pm_context_t context, pm_token_t *token) {
6623
6624
return token->type == PM_TOKEN_PARENTHESIS_RIGHT;
6624
6625
case PM_CONTEXT_BEGIN:
6625
6626
case PM_CONTEXT_RESCUE:
6627
+ case PM_CONTEXT_RESCUE_DEF:
6626
6628
return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END;
6627
6629
case PM_CONTEXT_RESCUE_ELSE:
6630
+ case PM_CONTEXT_RESCUE_ELSE_DEF:
6628
6631
return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_END;
6629
6632
case PM_CONTEXT_LAMBDA_BRACES:
6630
6633
return token->type == PM_TOKEN_BRACE_RIGHT;
@@ -6690,6 +6693,10 @@ context_def_p(pm_parser_t *parser) {
6690
6693
while (context_node != NULL) {
6691
6694
switch (context_node->context) {
6692
6695
case PM_CONTEXT_DEF:
6696
+ case PM_CONTEXT_DEF_PARAMS:
6697
+ case PM_CONTEXT_ENSURE_DEF:
6698
+ case PM_CONTEXT_RESCUE_DEF:
6699
+ case PM_CONTEXT_RESCUE_ELSE_DEF:
6693
6700
return true;
6694
6701
case PM_CONTEXT_CLASS:
6695
6702
case PM_CONTEXT_MODULE:
@@ -11837,7 +11844,7 @@ parse_parameters(
11837
11844
* nodes pointing to each other from the top.
11838
11845
*/
11839
11846
static inline void
11840
- parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
11847
+ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, bool def_p ) {
11841
11848
pm_rescue_node_t *current = NULL;
11842
11849
11843
11850
while (accept1(parser, PM_TOKEN_KEYWORD_RESCUE)) {
@@ -11900,7 +11907,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
11900
11907
11901
11908
if (!match3(parser, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
11902
11909
pm_accepts_block_stack_push(parser, true);
11903
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_RESCUE);
11910
+ pm_statements_node_t *statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_DEF : PM_CONTEXT_RESCUE);
11904
11911
if (statements) {
11905
11912
pm_rescue_node_statements_set(rescue, statements);
11906
11913
}
@@ -11936,7 +11943,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
11936
11943
pm_statements_node_t *else_statements = NULL;
11937
11944
if (!match2(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_ENSURE)) {
11938
11945
pm_accepts_block_stack_push(parser, true);
11939
- else_statements = parse_statements(parser, PM_CONTEXT_RESCUE_ELSE);
11946
+ else_statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_ELSE_DEF : PM_CONTEXT_RESCUE_ELSE);
11940
11947
pm_accepts_block_stack_pop(parser);
11941
11948
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
11942
11949
}
@@ -11952,7 +11959,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
11952
11959
pm_statements_node_t *ensure_statements = NULL;
11953
11960
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
11954
11961
pm_accepts_block_stack_push(parser, true);
11955
- ensure_statements = parse_statements(parser, PM_CONTEXT_ENSURE);
11962
+ ensure_statements = parse_statements(parser, def_p ? PM_CONTEXT_ENSURE_DEF : PM_CONTEXT_ENSURE);
11956
11963
pm_accepts_block_stack_pop(parser);
11957
11964
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
11958
11965
}
@@ -11970,10 +11977,10 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
11970
11977
}
11971
11978
11972
11979
static inline pm_begin_node_t *
11973
- parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements) {
11980
+ parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements, bool def_p ) {
11974
11981
pm_token_t no_begin_token = not_provided(parser);
11975
11982
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &no_begin_token, statements);
11976
- parse_rescues(parser, begin_node);
11983
+ parse_rescues(parser, begin_node, def_p );
11977
11984
11978
11985
// All nodes within a begin node are optional, so we look
11979
11986
// for the earliest possible node that we can use to set
@@ -12078,7 +12085,7 @@ parse_block(pm_parser_t *parser) {
12078
12085
12079
12086
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
12080
12087
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
12081
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
12088
+ statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false );
12082
12089
}
12083
12090
}
12084
12091
@@ -14547,7 +14554,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14547
14554
}
14548
14555
14549
14556
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
14550
- parse_rescues(parser, begin_node);
14557
+ parse_rescues(parser, begin_node, false );
14551
14558
14552
14559
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
14553
14560
begin_node->base.location.end = parser->previous.end;
@@ -14665,7 +14672,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14665
14672
14666
14673
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
14667
14674
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
14668
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
14675
+ statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false );
14669
14676
}
14670
14677
14671
14678
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
@@ -14717,7 +14724,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14717
14724
14718
14725
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
14719
14726
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
14720
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
14727
+ statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false );
14721
14728
}
14722
14729
14723
14730
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
@@ -14744,6 +14751,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14744
14751
pm_token_t operator = not_provided(parser);
14745
14752
pm_token_t name = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = def_keyword.end, .end = def_keyword.end };
14746
14753
14754
+ // This context is necessary for lexing `...` in a bare params correctly.
14755
+ // It must be pushed before lexing the first param, so it is here.
14747
14756
context_push(parser, PM_CONTEXT_DEF_PARAMS);
14748
14757
parser_lex(parser);
14749
14758
pm_constant_id_t old_param_name = parser->current_param_name;
@@ -14844,7 +14853,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14844
14853
break;
14845
14854
}
14846
14855
case PM_TOKEN_PARENTHESIS_LEFT: {
14856
+ // The current context is `PM_CONTEXT_DEF_PARAMS`, however the inner expression
14857
+ // of this parenthesis should not be processed under this context.
14858
+ // Thus, the context is popped here.
14859
+ context_pop(parser);
14847
14860
parser_lex(parser);
14861
+
14848
14862
pm_token_t lparen = parser->previous;
14849
14863
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_DEF_RECEIVER);
14850
14864
@@ -14859,6 +14873,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14859
14873
14860
14874
pm_parser_scope_push(parser, true);
14861
14875
parser->current_param_name = 0;
14876
+
14877
+ // To push `PM_CONTEXT_DEF_PARAMS` again is for the same reason as described the above.
14878
+ context_push(parser, PM_CONTEXT_DEF_PARAMS);
14862
14879
name = parse_method_definition_name(parser);
14863
14880
break;
14864
14881
}
@@ -14967,7 +14984,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
14967
14984
14968
14985
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
14969
14986
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
14970
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
14987
+ statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, true );
14971
14988
}
14972
14989
14973
14990
pm_accepts_block_stack_pop(parser);
@@ -15222,7 +15239,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
15222
15239
15223
15240
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
15224
15241
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
15225
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
15242
+ statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false );
15226
15243
}
15227
15244
15228
15245
pm_constant_id_list_t locals = parser->current_scope->locals;
@@ -15893,7 +15910,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
15893
15910
15894
15911
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
15895
15912
assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
15896
- body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body);
15913
+ body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body, false );
15897
15914
}
15898
15915
15899
15916
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
0 commit comments