summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-03-13 08:47:41 -0400
committergit <svn-admin@ruby-lang.org>2024-03-13 13:52:13 +0000
commitd1eaa97ec3cdbe38605379fc87a55987d6802dc7 (patch)
treeb7efdc26e943bf04664ce4c3818a29747651247d
parent3f8ef7ff7c09e67a48eff33804060803b9f11119 (diff)
[ruby/prism] Track parentheses in patterns
https://github.com/ruby/prism/commit/62db99f156
-rw-r--r--lib/prism/translation/ripper.rb20
-rw-r--r--prism/prism.c14
-rw-r--r--test/prism/snapshots/seattlerb/case_in.txt106
3 files changed, 88 insertions, 52 deletions
diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb
index 94156d4988..9f269f9eb8 100644
--- a/lib/prism/translation/ripper.rb
+++ b/lib/prism/translation/ripper.rb
@@ -583,13 +583,23 @@ module Prism
# foo => bar | baz
# ^^^^^^^^^
def visit_alternation_pattern_node(node)
- left = visit(node.left)
- right = visit(node.right)
+ left = visit_pattern_node(node.left)
+ right = visit_pattern_node(node.right)
bounds(node.location)
on_binary(left, :|, right)
end
+ # Visit a pattern within a pattern match. This is used to bypass the
+ # parenthesis node that can be used to wrap patterns.
+ private def visit_pattern_node(node)
+ if node.is_a?(ParenthesesNode)
+ visit(node.body)
+ else
+ visit(node)
+ end
+ end
+
# a and b
# ^^^^^^^
def visit_and_node(node)
@@ -1952,7 +1962,7 @@ module Prism
# This is a special case where we're not going to call on_in directly
# because we don't have access to the consequent. Instead, we'll return
# the component parts and let the parent node handle it.
- pattern = visit(node.pattern)
+ pattern = visit_pattern_node(node.pattern)
statements =
if node.statements.nil?
bounds(node.location)
@@ -2389,7 +2399,7 @@ module Prism
# ^^^^^^^^^^
def visit_match_predicate_node(node)
value = visit(node.value)
- pattern = on_in(visit(node.pattern), nil, nil)
+ pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
on_case(value, pattern)
end
@@ -2398,7 +2408,7 @@ module Prism
# ^^^^^^^^^^
def visit_match_required_node(node)
value = visit(node.value)
- pattern = on_in(visit(node.pattern), nil, nil)
+ pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
on_case(value, pattern)
end
diff --git a/prism/prism.c b/prism/prism.c
index 947d1a92bb..1d94ead82a 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -14883,14 +14883,20 @@ parse_pattern_primitives(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
break;
}
case PM_TOKEN_PARENTHESIS_LEFT: {
+ pm_token_t opening = parser->current;
parser_lex(parser);
- if (node != NULL) {
- pm_node_destroy(parser, node);
- }
- node = parse_pattern(parser, false, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
+ pm_node_t *body = parse_pattern(parser, false, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
accept1(parser, PM_TOKEN_NEWLINE);
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
+ pm_node_t *right = (pm_node_t *) pm_parentheses_node_create(parser, &opening, body, &parser->previous);
+
+ if (node == NULL) {
+ node = right;
+ } else {
+ node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator);
+ }
+
break;
}
default: {
diff --git a/test/prism/snapshots/seattlerb/case_in.txt b/test/prism/snapshots/seattlerb/case_in.txt
index e7e291c63f..950d66647e 100644
--- a/test/prism/snapshots/seattlerb/case_in.txt
+++ b/test/prism/snapshots/seattlerb/case_in.txt
@@ -186,16 +186,20 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a"
│ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (22,0)-(22,9))
+ │ │ └── @ InNode (location: (22,0)-(22,10))
│ │ ├── pattern:
- │ │ │ @ RangeNode (location: (22,4)-(22,9))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left: ∅
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (22,7)-(22,9))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 10
- │ │ │ └── operator_loc: (22,4)-(22,7) = "..."
+ │ │ │ @ ParenthesesNode (location: (22,3)-(22,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (22,4)-(22,9))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (22,7)-(22,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (22,4)-(22,7) = "..."
+ │ │ │ ├── opening_loc: (22,3)-(22,4) = "("
+ │ │ │ └── closing_loc: (22,9)-(22,10) = ")"
│ │ ├── statements: ∅
│ │ ├── in_loc: (22,0)-(22,2) = "in"
│ │ └── then_loc: ∅
@@ -211,16 +215,20 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a"
│ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (26,0)-(26,8))
+ │ │ └── @ InNode (location: (26,0)-(26,9))
│ │ ├── pattern:
- │ │ │ @ RangeNode (location: (26,4)-(26,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── left: ∅
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (26,6)-(26,8))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 10
- │ │ │ └── operator_loc: (26,4)-(26,6) = ".."
+ │ │ │ @ ParenthesesNode (location: (26,3)-(26,9))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (26,4)-(26,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (26,6)-(26,8))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (26,4)-(26,6) = ".."
+ │ │ │ ├── opening_loc: (26,3)-(26,4) = "("
+ │ │ │ └── closing_loc: (26,8)-(26,9) = ")"
│ │ ├── statements: ∅
│ │ ├── in_loc: (26,0)-(26,2) = "in"
│ │ └── then_loc: ∅
@@ -236,16 +244,20 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a"
│ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (30,0)-(30,8))
+ │ │ └── @ InNode (location: (30,0)-(30,9))
│ │ ├── pattern:
- │ │ │ @ RangeNode (location: (30,4)-(30,8))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left:
- │ │ │ │ @ IntegerNode (location: (30,4)-(30,5))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 1
- │ │ │ ├── right: ∅
- │ │ │ └── operator_loc: (30,5)-(30,8) = "..."
+ │ │ │ @ ParenthesesNode (location: (30,3)-(30,9))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (30,4)-(30,8))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (30,4)-(30,5))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right: ∅
+ │ │ │ │ └── operator_loc: (30,5)-(30,8) = "..."
+ │ │ │ ├── opening_loc: (30,3)-(30,4) = "("
+ │ │ │ └── closing_loc: (30,8)-(30,9) = ")"
│ │ ├── statements: ∅
│ │ ├── in_loc: (30,0)-(30,2) = "in"
│ │ └── then_loc: ∅
@@ -261,19 +273,23 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a"
│ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (34,0)-(34,9))
+ │ │ └── @ InNode (location: (34,0)-(34,10))
│ │ ├── pattern:
- │ │ │ @ RangeNode (location: (34,4)-(34,9))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left:
- │ │ │ │ @ IntegerNode (location: (34,4)-(34,5))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 1
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (34,8)-(34,9))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 3
- │ │ │ └── operator_loc: (34,5)-(34,8) = "..."
+ │ │ │ @ ParenthesesNode (location: (34,3)-(34,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (34,4)-(34,9))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (34,4)-(34,5))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (34,8)-(34,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 3
+ │ │ │ │ └── operator_loc: (34,5)-(34,8) = "..."
+ │ │ │ ├── opening_loc: (34,3)-(34,4) = "("
+ │ │ │ └── closing_loc: (34,9)-(34,10) = ")"
│ │ ├── statements: ∅
│ │ ├── in_loc: (34,0)-(34,2) = "in"
│ │ └── then_loc: ∅
@@ -289,11 +305,15 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a"
│ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (38,0)-(38,6))
+ │ │ └── @ InNode (location: (38,0)-(38,7))
│ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (38,4)-(38,6))
- │ │ │ ├── flags: decimal
- │ │ │ └── value: 42
+ │ │ │ @ ParenthesesNode (location: (38,3)-(38,7))
+ │ │ │ ├── body:
+ │ │ │ │ @ IntegerNode (location: (38,4)-(38,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ ├── opening_loc: (38,3)-(38,4) = "("
+ │ │ │ └── closing_loc: (38,6)-(38,7) = ")"
│ │ ├── statements: ∅
│ │ ├── in_loc: (38,0)-(38,2) = "in"
│ │ └── then_loc: ∅