-
Notifications
You must be signed in to change notification settings - Fork 175
Reject endless method as a block parameter default #3702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
f16fafa to
689acf2
Compare
src/prism.c
Outdated
| allows_trailing_comma, | ||
| false, | ||
| accepts_blocks_in_defaults, | ||
| is_lambda_literal, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is it basically. Pass this all the way down to parse_expression_prefix. Every other place I have left at the previous behaviour (accept endless method)
src/prism.c
Outdated
| pm_token_t end_keyword; | ||
|
|
||
| if (accept1(parser, PM_TOKEN_EQUAL)) { | ||
| if (accepts_endless_def && accept1(parser, PM_TOKEN_EQUAL)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other place of interest
| @@ -0,0 +1,47 @@ | |||
| p do |a = def f = 1| end | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say these error messages look kind of ugly. The second one (unexpected =) is telling, the rest are meh. The last two code snippets are already rejected, the error message didn't change for them.
I would not know how to improve these error messages, if that is necessary.
1037f92 to
ae51243
Compare
|
This one is a bit bigger, so will take a minute to review. I'm out this week but will get back to stuff in earnest next week. |
tenderlove
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me. Most of this patch is just updating function signatures.
|
Could you potentially do this with a new context instead? We already have |
|
Should be possible, yeah. I did start out with a new context but there are so few places that actually use them in such a way and that did turn me away from that. Will try to rework this |
|
I have this patch: Patch
diff --git a/config.yml b/config.yml
index 7d71d52d..2ce8babf 100644
--- a/config.yml
+++ b/config.yml
@@ -3720,6 +3720,7 @@ nodes:
- RequiredParameterNode # def m((a,b)); end
- on error: BackReferenceReadNode # a, (b, $&) = z
- on error: NumberedReferenceReadNode # a, (b, $1) = z
+ - on error: CallNode # p do |a = def f = 1, b| end
comment: |
Represents the targets expressions before a splat node.
diff --git a/include/prism/parser.h b/include/prism/parser.h
index 992729d6..d378ff0c 100644
--- a/include/prism/parser.h
+++ b/include/prism/parser.h
@@ -290,6 +290,9 @@ typedef enum {
/** expressions in block arguments using braces */
PM_CONTEXT_BLOCK_BRACES,
+ /** expressions in block parameters `foo do |...| end ` */
+ PM_CONTEXT_BLOCK_PARAMETERS,
+
/** expressions in block arguments using do..end */
PM_CONTEXT_BLOCK_KEYWORDS,
diff --git a/src/prism.c b/src/prism.c
index 02dd2f11..23460610 100644
--- a/src/prism.c
+++ b/src/prism.c
@@ -8603,6 +8603,7 @@ static const uint32_t context_terminators[] = {
[PM_CONTEXT_BEGIN_ELSE] = (1U << PM_TOKEN_KEYWORD_ENSURE) | (1U << PM_TOKEN_KEYWORD_END),
[PM_CONTEXT_BEGIN_RESCUE] = (1U << PM_TOKEN_KEYWORD_ENSURE) | (1U << PM_TOKEN_KEYWORD_RESCUE) | (1U << PM_TOKEN_KEYWORD_ELSE) | (1U << PM_TOKEN_KEYWORD_END),
[PM_CONTEXT_BLOCK_BRACES] = (1U << PM_TOKEN_BRACE_RIGHT),
+ [PM_CONTEXT_BLOCK_PARAMETERS] = 0,
[PM_CONTEXT_BLOCK_KEYWORDS] = (1U << PM_TOKEN_KEYWORD_END) | (1U << PM_TOKEN_KEYWORD_RESCUE) | (1U << PM_TOKEN_KEYWORD_ENSURE),
[PM_CONTEXT_BLOCK_ENSURE] = (1U << PM_TOKEN_KEYWORD_END),
[PM_CONTEXT_BLOCK_ELSE] = (1U << PM_TOKEN_KEYWORD_ENSURE) | (1U << PM_TOKEN_KEYWORD_END),
@@ -8754,6 +8755,7 @@ context_human(pm_context_t context) {
assert(false && "unreachable");
return "";
case PM_CONTEXT_BEGIN: return "begin statement";
+ case PM_CONTEXT_BLOCK_PARAMETERS: return "'|'..'|' block parameter";
case PM_CONTEXT_BLOCK_BRACES: return "'{'..'}' block";
case PM_CONTEXT_BLOCK_KEYWORDS: return "'do'..'end' block";
case PM_CONTEXT_CASE_WHEN: return "'when' clause";
@@ -15357,6 +15359,9 @@ parse_block_parameters(
) {
pm_parameters_node_t *parameters = NULL;
if (!match1(parser, PM_TOKEN_SEMICOLON)) {
+ if (!is_lambda_literal) {
+ context_push(parser, PM_CONTEXT_BLOCK_PARAMETERS);
+ }
parameters = parse_parameters(
parser,
is_lambda_literal ? PM_BINDING_POWER_DEFINED : PM_BINDING_POWER_INDEX,
@@ -15367,6 +15372,9 @@ parse_block_parameters(
true,
(uint16_t) (depth + 1)
);
+ if (!is_lambda_literal) {
+ context_pop(parser);
+ }
}
pm_block_parameters_node_t *block_parameters = pm_block_parameters_node_create(parser, parameters, opening);
@@ -15717,6 +15725,7 @@ parse_return(pm_parser_t *parser, pm_node_t *node) {
// These contexts are invalid for a return.
pm_parser_err_node(parser, node, PM_ERR_RETURN_INVALID);
return;
+ case PM_CONTEXT_BLOCK_PARAMETERS:
case PM_CONTEXT_BLOCK_BRACES:
case PM_CONTEXT_BLOCK_ELSE:
case PM_CONTEXT_BLOCK_ENSURE:
@@ -15754,6 +15763,7 @@ static void
parse_block_exit(pm_parser_t *parser, pm_node_t *node) {
for (pm_context_node_t *context_node = parser->current_context; context_node != NULL; context_node = context_node->prev) {
switch (context_node->context) {
+ case PM_CONTEXT_BLOCK_PARAMETERS:
case PM_CONTEXT_BLOCK_BRACES:
case PM_CONTEXT_BLOCK_KEYWORDS:
case PM_CONTEXT_BLOCK_ELSE:
@@ -17973,6 +17983,7 @@ parse_retry(pm_parser_t *parser, const pm_node_t *node) {
assert(false && "unreachable");
break;
case PM_CONTEXT_BEGIN:
+ case PM_CONTEXT_BLOCK_PARAMETERS:
case PM_CONTEXT_BLOCK_BRACES:
case PM_CONTEXT_BLOCK_KEYWORDS:
case PM_CONTEXT_CASE_IN:
@@ -18051,6 +18062,7 @@ parse_yield(pm_parser_t *parser, const pm_node_t *node) {
case PM_CONTEXT_BEGIN_ELSE:
case PM_CONTEXT_BEGIN_ENSURE:
case PM_CONTEXT_BEGIN_RESCUE:
+ case PM_CONTEXT_BLOCK_PARAMETERS:
case PM_CONTEXT_BLOCK_BRACES:
case PM_CONTEXT_BLOCK_KEYWORDS:
case PM_CONTEXT_BLOCK_ELSE:
@@ -19611,7 +19623,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
pm_token_t equal;
pm_token_t end_keyword;
- if (accept1(parser, PM_TOKEN_EQUAL)) {
+ if (!context_p(parser, PM_CONTEXT_BLOCK_PARAMETERS) && accept1(parser, PM_TOKEN_EQUAL)) {
if (token_is_setter_name(&name)) {
pm_parser_err_token(parser, &name, PM_ERR_DEF_ENDLESS_SETTER);
}It's more concise but also not correct. For example, it rejects |
|
@kddnewton I've sent you an email two days ago to your git commit email. Did you receive it/any other way to get in contact with you? |
|
Sorry yes I will respond |
Fixes [Bug #21661]
ae51243 to
475fa46
Compare
|
I rewrote it slightly to use a new context, I think I'm going to roll with this approach. Thanks for the patch, it helped! |
Fixes [Bug #21661]
It's not particularly nice to me to now have 3 bool parameters for expressions. But I guess this follows b624e09