diff options
| author | Earlopain <14981592+Earlopain@users.noreply.github.com> | 2025-10-27 11:24:45 +0100 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2025-10-30 13:05:51 +0000 |
| commit | 99382f7461db80497b69df84ac52fab6710ba160 (patch) | |
| tree | 8818bb2379fe557e13f6fdc304febdf875f31602 | |
| parent | d5fbff50c7ff880ae71b8a8ae9aad976c69bea73 (diff) | |
[ruby/prism] Unescape unary method calls
Followup to https://github.com/ruby/prism/pull/2213
Before:
```sh
$ ruby -ve "puts 42.~@"
ruby 3.4.6 (2025-09-16 revision https://github.com/ruby/prism/commit/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 https://github.com/ruby/prism/commit/1d95d75c3f) +PRISM [x86_64-linux]
-43
```
https://github.com/ruby/prism/commit/a755bf228f
| -rw-r--r-- | prism/prism.c | 10 | ||||
| -rw-r--r-- | test/prism/fixtures/unary_method_calls.txt | 2 | ||||
| -rw-r--r-- | test/prism/ruby/parser_test.rb | 3 | ||||
| -rw-r--r-- | test/prism/ruby/ruby_parser_test.rb | 1 |
4 files changed, 14 insertions, 2 deletions
diff --git a/prism/prism.c b/prism/prism.c index 95e7d09050..a92de163f5 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -2721,6 +2721,8 @@ pm_call_node_binary_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t return node; } +static const uint8_t * parse_operator_symbol_name(const pm_token_t *); + /** * Allocate and initialize a new CallNode node from a call expression. */ @@ -2749,7 +2751,11 @@ pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *o pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION); } - node->name = pm_parser_constant_id_token(parser, message); + /** + * If the final character is `@` as is the case for `foo.~@`, + * we should ignore the @ in the same way we do for symbols. + */ + node->name = pm_parser_constant_id_location(parser, message->start, parse_operator_symbol_name(message)); return node; } @@ -19702,7 +19708,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b pm_parser_scope_pop(parser); /** - * If the final character is @. As is the case when defining + * If the final character is `@` as is the case when defining * methods to override the unary operators, we should ignore * the @ in the same way we do for symbols. */ diff --git a/test/prism/fixtures/unary_method_calls.txt b/test/prism/fixtures/unary_method_calls.txt new file mode 100644 index 0000000000..dda85e4bdb --- /dev/null +++ b/test/prism/fixtures/unary_method_calls.txt @@ -0,0 +1,2 @@ +42.~@ +42.!@ diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb index 016fda91f0..3104369d3e 100644 --- a/test/prism/ruby/parser_test.rb +++ b/test/prism/ruby/parser_test.rb @@ -109,6 +109,9 @@ module Prism # Regex with \c escape "unescaping.txt", "seattlerb/regexp_esc_C_slash.txt", + + # https://github.com/whitequark/parser/issues/1084 + "unary_method_calls.txt", ] # These files are failing to translate their lexer output into the lexer diff --git a/test/prism/ruby/ruby_parser_test.rb b/test/prism/ruby/ruby_parser_test.rb index 7640ddaf1c..42a888be82 100644 --- a/test/prism/ruby/ruby_parser_test.rb +++ b/test/prism/ruby/ruby_parser_test.rb @@ -57,6 +57,7 @@ module Prism "spanning_heredoc.txt", "symbols.txt", "tilde_heredocs.txt", + "unary_method_calls.txt", "unparser/corpus/literal/literal.txt", "while.txt", "whitequark/cond_eflipflop.txt", |
