Skip to content

Commit 99382f7

Browse files
Earlopainmatzbot
authored andcommitted
[ruby/prism] Unescape unary method calls
Followup to ruby/prism#2213 Before: ```sh $ ruby -ve "puts 42.~@" ruby 3.4.6 (2025-09-16 revision ruby/prism@dbd83256b1) +PRISM [x86_64-linux] -e:1:in '<main>': undefined method '~@' for an instance of Integer (NoMethodError) Did you mean? ~ ``` After (matches parse.y): ```sh $ ./miniruby -ve "puts 42.~@" ruby 3.5.0dev (2025-10-16T03:40:45Z master ruby/prism@1d95d75c3f) +PRISM [x86_64-linux] -43 ``` ruby/prism@a755bf228f
1 parent d5fbff5 commit 99382f7

File tree

4 files changed

+14
-2
lines changed

4 files changed

+14
-2
lines changed

prism/prism.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,6 +2721,8 @@ pm_call_node_binary_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t
27212721
return node;
27222722
}
27232723

2724+
static const uint8_t * parse_operator_symbol_name(const pm_token_t *);
2725+
27242726
/**
27252727
* Allocate and initialize a new CallNode node from a call expression.
27262728
*/
@@ -2749,7 +2751,11 @@ pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *o
27492751
pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION);
27502752
}
27512753

2752-
node->name = pm_parser_constant_id_token(parser, message);
2754+
/**
2755+
* If the final character is `@` as is the case for `foo.~@`,
2756+
* we should ignore the @ in the same way we do for symbols.
2757+
*/
2758+
node->name = pm_parser_constant_id_location(parser, message->start, parse_operator_symbol_name(message));
27532759
return node;
27542760
}
27552761

@@ -19702,7 +19708,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1970219708
pm_parser_scope_pop(parser);
1970319709

1970419710
/**
19705-
* If the final character is @. As is the case when defining
19711+
* If the final character is `@` as is the case when defining
1970619712
* methods to override the unary operators, we should ignore
1970719713
* the @ in the same way we do for symbols.
1970819714
*/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
42.~@
2+
42.!@

test/prism/ruby/parser_test.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ class ParserTest < TestCase
109109
# Regex with \c escape
110110
"unescaping.txt",
111111
"seattlerb/regexp_esc_C_slash.txt",
112+
113+
# https://github.com/whitequark/parser/issues/1084
114+
"unary_method_calls.txt",
112115
]
113116

114117
# These files are failing to translate their lexer output into the lexer

test/prism/ruby/ruby_parser_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class RubyParserTest < TestCase
5757
"spanning_heredoc.txt",
5858
"symbols.txt",
5959
"tilde_heredocs.txt",
60+
"unary_method_calls.txt",
6061
"unparser/corpus/literal/literal.txt",
6162
"while.txt",
6263
"whitequark/cond_eflipflop.txt",

0 commit comments

Comments
 (0)