Skip to content

Commit 80dbd85

Browse files
committed
Fix parser translator when splatting in pattern matching pin
Because it ends up treating it as a local variable, and `a.x` is not a valid local variable name. I'm not big on pattern matching, but conceptually it makes sense to me to treat anything inside ^() to not be pattern matching syntax?
1 parent 6ae402e commit 80dbd85

File tree

3 files changed

+169
-47
lines changed

3 files changed

+169
-47
lines changed

lib/prism/translation/parser/compiler.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,8 @@ def visit_parentheses_node(node)
14811481
# foo => ^(bar)
14821482
# ^^^^^^
14831483
def visit_pinned_expression_node(node)
1484-
expression = builder.begin(token(node.lparen_loc), visit(node.expression), token(node.rparen_loc))
1484+
parts = node.expression.accept(copy_compiler(in_pattern: false)) # Don't treat * and similar as match_rest
1485+
expression = builder.begin(token(node.lparen_loc), parts, token(node.rparen_loc))
14851486
builder.pin(token(node.operator_loc), expression)
14861487
end
14871488

snapshots/patterns.txt

Lines changed: 163 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
@ ProgramNode (location: (1,0)-(220,14))
1+
@ ProgramNode (location: (1,0)-(224,14))
22
├── flags: ∅
33
├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x, :_a]
44
└── statements:
5-
@ StatementsNode (location: (1,0)-(220,14))
5+
@ StatementsNode (location: (1,0)-(224,14))
66
├── flags: ∅
7-
└── body: (length: 187)
7+
└── body: (length: 190)
88
├── @ MatchRequiredNode (location: (1,0)-(1,10))
99
│ ├── flags: newline
1010
│ ├── value:
@@ -5727,49 +5727,166 @@
57275727
│ │ ├── closing_loc: ∅
57285728
│ │ └── block: ∅
57295729
│ └── operator_loc: (219,10)-(219,13) = "and"
5730-
└── @ OrNode (location: (220,0)-(220,14))
5730+
├── @ OrNode (location: (220,0)-(220,14))
5731+
│ ├── flags: newline
5732+
│ ├── left:
5733+
│ │ @ ParenthesesNode (location: (220,0)-(220,9))
5734+
│ │ ├── flags: ∅
5735+
│ │ ├── body:
5736+
│ │ │ @ StatementsNode (location: (220,1)-(220,8))
5737+
│ │ │ ├── flags: ∅
5738+
│ │ │ └── body: (length: 1)
5739+
│ │ │ └── @ MatchPredicateNode (location: (220,1)-(220,8))
5740+
│ │ │ ├── flags: newline
5741+
│ │ │ ├── value:
5742+
│ │ │ │ @ LocalVariableReadNode (location: (220,1)-(220,2))
5743+
│ │ │ │ ├── flags: ∅
5744+
│ │ │ │ ├── name: :a
5745+
│ │ │ │ └── depth: 0
5746+
│ │ │ ├── pattern:
5747+
│ │ │ │ @ ArrayPatternNode (location: (220,6)-(220,8))
5748+
│ │ │ │ ├── flags: ∅
5749+
│ │ │ │ ├── constant: ∅
5750+
│ │ │ │ ├── requireds: (length: 1)
5751+
│ │ │ │ │ └── @ LocalVariableTargetNode (location: (220,6)-(220,7))
5752+
│ │ │ │ │ ├── flags: ∅
5753+
│ │ │ │ │ ├── name: :b
5754+
│ │ │ │ │ └── depth: 0
5755+
│ │ │ │ ├── rest:
5756+
│ │ │ │ │ @ ImplicitRestNode (location: (220,7)-(220,8))
5757+
│ │ │ │ │ └── flags: ∅
5758+
│ │ │ │ ├── posts: (length: 0)
5759+
│ │ │ │ ├── opening_loc: ∅
5760+
│ │ │ │ └── closing_loc: ∅
5761+
│ │ │ └── operator_loc: (220,3)-(220,5) = "in"
5762+
│ │ ├── opening_loc: (220,0)-(220,1) = "("
5763+
│ │ └── closing_loc: (220,8)-(220,9) = ")"
5764+
│ ├── right:
5765+
│ │ @ CallNode (location: (220,13)-(220,14))
5766+
│ │ ├── flags: variable_call, ignore_visibility
5767+
│ │ ├── receiver: ∅
5768+
│ │ ├── call_operator_loc: ∅
5769+
│ │ ├── name: :c
5770+
│ │ ├── message_loc: (220,13)-(220,14) = "c"
5771+
│ │ ├── opening_loc: ∅
5772+
│ │ ├── arguments: ∅
5773+
│ │ ├── closing_loc: ∅
5774+
│ │ └── block: ∅
5775+
│ └── operator_loc: (220,10)-(220,12) = "or"
5776+
├── @ MatchRequiredNode (location: (222,0)-(222,14))
5777+
│ ├── flags: newline
5778+
│ ├── value:
5779+
│ │ @ LocalVariableReadNode (location: (222,0)-(222,1))
5780+
│ │ ├── flags: ∅
5781+
│ │ ├── name: :x
5782+
│ │ └── depth: 0
5783+
│ ├── pattern:
5784+
│ │ @ PinnedExpressionNode (location: (222,5)-(222,14))
5785+
│ │ ├── flags: ∅
5786+
│ │ ├── expression:
5787+
│ │ │ @ ArrayNode (location: (222,7)-(222,13))
5788+
│ │ │ ├── flags: contains_splat
5789+
│ │ │ ├── elements: (length: 1)
5790+
│ │ │ │ └── @ SplatNode (location: (222,8)-(222,12))
5791+
│ │ │ │ ├── flags: ∅
5792+
│ │ │ │ ├── operator_loc: (222,8)-(222,9) = "*"
5793+
│ │ │ │ └── expression:
5794+
│ │ │ │ @ CallNode (location: (222,9)-(222,12))
5795+
│ │ │ │ ├── flags: ∅
5796+
│ │ │ │ ├── receiver:
5797+
│ │ │ │ │ @ LocalVariableReadNode (location: (222,9)-(222,10))
5798+
│ │ │ │ │ ├── flags: ∅
5799+
│ │ │ │ │ ├── name: :a
5800+
│ │ │ │ │ └── depth: 0
5801+
│ │ │ │ ├── call_operator_loc: (222,10)-(222,11) = "."
5802+
│ │ │ │ ├── name: :x
5803+
│ │ │ │ ├── message_loc: (222,11)-(222,12) = "x"
5804+
│ │ │ │ ├── opening_loc: ∅
5805+
│ │ │ │ ├── arguments: ∅
5806+
│ │ │ │ ├── closing_loc: ∅
5807+
│ │ │ │ └── block: ∅
5808+
│ │ │ ├── opening_loc: (222,7)-(222,8) = "["
5809+
│ │ │ └── closing_loc: (222,12)-(222,13) = "]"
5810+
│ │ ├── operator_loc: (222,5)-(222,6) = "^"
5811+
│ │ ├── lparen_loc: (222,6)-(222,7) = "("
5812+
│ │ └── rparen_loc: (222,13)-(222,14) = ")"
5813+
│ └── operator_loc: (222,2)-(222,4) = "=>"
5814+
├── @ MatchRequiredNode (location: (223,0)-(223,15))
5815+
│ ├── flags: newline
5816+
│ ├── value:
5817+
│ │ @ LocalVariableReadNode (location: (223,0)-(223,1))
5818+
│ │ ├── flags: ∅
5819+
│ │ ├── name: :x
5820+
│ │ └── depth: 0
5821+
│ ├── pattern:
5822+
│ │ @ PinnedExpressionNode (location: (223,5)-(223,15))
5823+
│ │ ├── flags: ∅
5824+
│ │ ├── expression:
5825+
│ │ │ @ ArrayNode (location: (223,7)-(223,14))
5826+
│ │ │ ├── flags: ∅
5827+
│ │ │ ├── elements: (length: 1)
5828+
│ │ │ │ └── @ KeywordHashNode (location: (223,8)-(223,13))
5829+
│ │ │ │ ├── flags: ∅
5830+
│ │ │ │ └── elements: (length: 1)
5831+
│ │ │ │ └── @ AssocSplatNode (location: (223,8)-(223,13))
5832+
│ │ │ │ ├── flags: ∅
5833+
│ │ │ │ ├── value:
5834+
│ │ │ │ │ @ CallNode (location: (223,10)-(223,13))
5835+
│ │ │ │ │ ├── flags: ∅
5836+
│ │ │ │ │ ├── receiver:
5837+
│ │ │ │ │ │ @ LocalVariableReadNode (location: (223,10)-(223,11))
5838+
│ │ │ │ │ │ ├── flags: ∅
5839+
│ │ │ │ │ │ ├── name: :a
5840+
│ │ │ │ │ │ └── depth: 0
5841+
│ │ │ │ │ ├── call_operator_loc: (223,11)-(223,12) = "."
5842+
│ │ │ │ │ ├── name: :x
5843+
│ │ │ │ │ ├── message_loc: (223,12)-(223,13) = "x"
5844+
│ │ │ │ │ ├── opening_loc: ∅
5845+
│ │ │ │ │ ├── arguments: ∅
5846+
│ │ │ │ │ ├── closing_loc: ∅
5847+
│ │ │ │ │ └── block: ∅
5848+
│ │ │ │ └── operator_loc: (223,8)-(223,10) = "**"
5849+
│ │ │ ├── opening_loc: (223,7)-(223,8) = "["
5850+
│ │ │ └── closing_loc: (223,13)-(223,14) = "]"
5851+
│ │ ├── operator_loc: (223,5)-(223,6) = "^"
5852+
│ │ ├── lparen_loc: (223,6)-(223,7) = "("
5853+
│ │ └── rparen_loc: (223,14)-(223,15) = ")"
5854+
│ └── operator_loc: (223,2)-(223,4) = "=>"
5855+
└── @ MatchRequiredNode (location: (224,0)-(224,14))
57315856
├── flags: newline
5732-
├── left:
5733-
│ @ ParenthesesNode (location: (220,0)-(220,9))
5857+
├── value:
5858+
│ @ LocalVariableReadNode (location: (224,0)-(224,1))
5859+
│ ├── flags: ∅
5860+
│ ├── name: :x
5861+
│ └── depth: 0
5862+
├── pattern:
5863+
│ @ PinnedExpressionNode (location: (224,5)-(224,14))
57345864
│ ├── flags: ∅
5735-
│ ├── body:
5736-
│ │ @ StatementsNode (location: (220,1)-(220,8))
5865+
│ ├── expression:
5866+
│ │ @ HashNode (location: (224,7)-(224,13))
57375867
│ │ ├── flags: ∅
5738-
│ │ └── body: (length: 1)
5739-
│ │ └── @ MatchPredicateNode (location: (220,1)-(220,8))
5740-
│ │ ├── flags: newline
5741-
│ │ ├── value:
5742-
│ │ │ @ LocalVariableReadNode (location: (220,1)-(220,2))
5743-
│ │ │ ├── flags: ∅
5744-
│ │ │ ├── name: :a
5745-
│ │ │ └── depth: 0
5746-
│ │ ├── pattern:
5747-
│ │ │ @ ArrayPatternNode (location: (220,6)-(220,8))
5748-
│ │ │ ├── flags: ∅
5749-
│ │ │ ├── constant: ∅
5750-
│ │ │ ├── requireds: (length: 1)
5751-
│ │ │ │ └── @ LocalVariableTargetNode (location: (220,6)-(220,7))
5752-
│ │ │ │ ├── flags: ∅
5753-
│ │ │ │ ├── name: :b
5754-
│ │ │ │ └── depth: 0
5755-
│ │ │ ├── rest:
5756-
│ │ │ │ @ ImplicitRestNode (location: (220,7)-(220,8))
5757-
│ │ │ │ └── flags: ∅
5758-
│ │ │ ├── posts: (length: 0)
5759-
│ │ │ ├── opening_loc: ∅
5760-
│ │ │ └── closing_loc: ∅
5761-
│ │ └── operator_loc: (220,3)-(220,5) = "in"
5762-
│ ├── opening_loc: (220,0)-(220,1) = "("
5763-
│ └── closing_loc: (220,8)-(220,9) = ")"
5764-
├── right:
5765-
│ @ CallNode (location: (220,13)-(220,14))
5766-
│ ├── flags: variable_call, ignore_visibility
5767-
│ ├── receiver: ∅
5768-
│ ├── call_operator_loc: ∅
5769-
│ ├── name: :c
5770-
│ ├── message_loc: (220,13)-(220,14) = "c"
5771-
│ ├── opening_loc: ∅
5772-
│ ├── arguments: ∅
5773-
│ ├── closing_loc: ∅
5774-
│ └── block: ∅
5775-
└── operator_loc: (220,10)-(220,12) = "or"
5868+
│ │ ├── opening_loc: (224,7)-(224,8) = "{"
5869+
│ │ ├── elements: (length: 1)
5870+
│ │ │ └── @ AssocNode (location: (224,9)-(224,11))
5871+
│ │ │ ├── flags: ∅
5872+
│ │ │ ├── key:
5873+
│ │ │ │ @ SymbolNode (location: (224,9)-(224,11))
5874+
│ │ │ │ ├── flags: static_literal, forced_us_ascii_encoding
5875+
│ │ │ │ ├── opening_loc: ∅
5876+
│ │ │ │ ├── value_loc: (224,9)-(224,10) = "a"
5877+
│ │ │ │ ├── closing_loc: (224,10)-(224,11) = ":"
5878+
│ │ │ │ └── unescaped: "a"
5879+
│ │ │ ├── value:
5880+
│ │ │ │ @ ImplicitNode (location: (224,9)-(224,11))
5881+
│ │ │ │ ├── flags: ∅
5882+
│ │ │ │ └── value:
5883+
│ │ │ │ @ LocalVariableReadNode (location: (224,9)-(224,11))
5884+
│ │ │ │ ├── flags: ∅
5885+
│ │ │ │ ├── name: :a
5886+
│ │ │ │ └── depth: 0
5887+
│ │ │ └── operator_loc: ∅
5888+
│ │ └── closing_loc: (224,12)-(224,13) = "}"
5889+
│ ├── operator_loc: (224,5)-(224,6) = "^"
5890+
│ ├── lparen_loc: (224,6)-(224,7) = "("
5891+
│ └── rparen_loc: (224,13)-(224,14) = ")"
5892+
└── operator_loc: (224,2)-(224,4) = "=>"

test/prism/fixtures/patterns.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,7 @@ a in b, and c
218218
a in b, or c
219219
(a in b,) and c
220220
(a in b,) or c
221+
222+
x => ^([*a.x])
223+
x => ^([**a.x])
224+
x => ^({ a: })

0 commit comments

Comments
 (0)