Skip to content

Commit a192db5

Browse files
authored
Merge pull request #3694 from Earlopain/escape-unary-method-calls
Unescape unary method calls
2 parents a364e48 + a755bf2 commit a192db5

File tree

5 files changed

+47
-2
lines changed

5 files changed

+47
-2
lines changed

snapshots/unary_method_calls.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@ ProgramNode (location: (1,0)-(2,5))
2+
├── flags: ∅
3+
├── locals: []
4+
└── statements:
5+
@ StatementsNode (location: (1,0)-(2,5))
6+
├── flags: ∅
7+
└── body: (length: 2)
8+
├── @ CallNode (location: (1,0)-(1,5))
9+
│ ├── flags: newline
10+
│ ├── receiver:
11+
│ │ @ IntegerNode (location: (1,0)-(1,2))
12+
│ │ ├── flags: static_literal, decimal
13+
│ │ └── value: 42
14+
│ ├── call_operator_loc: (1,2)-(1,3) = "."
15+
│ ├── name: :~
16+
│ ├── message_loc: (1,3)-(1,5) = "~@"
17+
│ ├── opening_loc: ∅
18+
│ ├── arguments: ∅
19+
│ ├── closing_loc: ∅
20+
│ └── block: ∅
21+
└── @ CallNode (location: (2,0)-(2,5))
22+
├── flags: newline
23+
├── receiver:
24+
│ @ IntegerNode (location: (2,0)-(2,2))
25+
│ ├── flags: static_literal, decimal
26+
│ └── value: 42
27+
├── call_operator_loc: (2,2)-(2,3) = "."
28+
├── name: :!
29+
├── message_loc: (2,3)-(2,5) = "!@"
30+
├── opening_loc: ∅
31+
├── arguments: ∅
32+
├── closing_loc: ∅
33+
└── block: ∅

src/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)