Skip to content

Commit

Permalink
Merge pull request #1724 from ruby/split-masgn
Browse files Browse the repository at this point in the history
Revisit multi target nodes
  • Loading branch information
kddnewton authored Oct 26, 2023
2 parents fbe2f82 + e6deed0 commit 80c48e5
Show file tree
Hide file tree
Showing 76 changed files with 1,059 additions and 801 deletions.
26 changes: 10 additions & 16 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,11 @@ nodes:
^^^^^^^^^^^^^^
- name: MultiTargetNode
fields:
- name: targets
- name: lefts
type: node[]
- name: rest
type: node?
- name: rights
type: node[]
- name: lparen_loc
type: location?
Expand All @@ -1935,7 +1939,11 @@ nodes:
^^^^^^
- name: MultiWriteNode
fields:
- name: targets
- name: lefts
type: node[]
- name: rest
type: node?
- name: rights
type: node[]
- name: lparen_loc
type: location?
Expand Down Expand Up @@ -2176,20 +2184,6 @@ nodes:
/foo/i
^^^^^^
- name: RequiredDestructuredParameterNode
fields:
- name: parameters
type: node[]
- name: opening_loc
type: location
- name: closing_loc
type: location
comment: |
Represents a destructured required parameter node.
def foo((bar, baz))
^^^^^^^^^^
end
- name: RequiredParameterNode
fields:
- name: name
Expand Down
1 change: 1 addition & 0 deletions include/prism/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ typedef enum {
PM_CONTEXT_EMBEXPR, // an interpolated expression
PM_CONTEXT_ENSURE, // an ensure statement
PM_CONTEXT_FOR, // a for loop
PM_CONTEXT_FOR_INDEX, // a for loop's index
PM_CONTEXT_IF, // an if statement
PM_CONTEXT_LAMBDA_BRACES, // a lambda expression with braces
PM_CONTEXT_LAMBDA_DO_END, // a lambda expression with do..end
Expand Down
8 changes: 5 additions & 3 deletions lib/prism/debug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ def self.prism_locals(source)

# Recurse down the parameter tree to find any destructured
# parameters and add them after the other parameters.
param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse
param_stack = params.requireds.concat(params.posts).grep(MultiTargetNode).reverse
while (param = param_stack.pop)
case param
when RequiredDestructuredParameterNode
param_stack.concat(param.parameters.reverse)
when MultiTargetNode
param_stack.concat(param.rights.reverse)
param_stack << param.rest
param_stack.concat(param.lefts.reverse)
when RequiredParameterNode
sorted << param.name
when SplatNode
Expand Down
156 changes: 74 additions & 82 deletions src/prism.c

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions test/prism/constant_path_node_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ def test_full_name_for_constant_path_target
RUBY

node = Prism.parse(source).value.statements.body.first
target = node.targets.first
assert_equal("Foo::Bar::Baz::Qux", target.full_name)
assert_equal("Foo::Bar::Baz::Qux", node.lefts.first.full_name)
end
end
end
2 changes: 1 addition & 1 deletion test/prism/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ def test_unterminated_global_variable
def test_invalid_global_variable_write
assert_errors expression("$',"), "$',", [
["Immutable variable as a write target", 0..2],
["Unexpected write target", 0..3]
["Unexpected write target", 0..2]
]
end

Expand Down
1 change: 1 addition & 0 deletions test/prism/fixtures/variables.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ Foo = 1, 2

(a; b; c)

a, (b, c), d = []
25 changes: 11 additions & 14 deletions test/prism/location_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def test_ClassVariableReadNode

def test_ClassVariableTargetNode
assert_location(ClassVariableTargetNode, "@@foo, @@bar = baz", 0...5) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -252,7 +252,7 @@ def test_ConstantPathOrWriteNode

def test_ConstantPathTargetNode
assert_location(ConstantPathTargetNode, "::Foo, ::Bar = baz", 0...5) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -281,7 +281,7 @@ def test_ConstantReadNode

def test_ConstantTargetNode
assert_location(ConstantTargetNode, "Foo, Bar = baz", 0...3) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -379,7 +379,7 @@ def test_GlobalVariableReadNode

def test_GlobalVariableTargetNode
assert_location(GlobalVariableTargetNode, "$foo, $bar = baz", 0...4) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -457,7 +457,7 @@ def test_InstanceVariableReadNode

def test_InstanceVariableTargetNode
assert_location(InstanceVariableTargetNode, "@foo, @bar = baz", 0...4) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -548,7 +548,7 @@ def test_LocalVariableReadNode

def test_LocalVariableTargetNode
assert_location(LocalVariableTargetNode, "foo, bar = baz", 0...3) do |node|
node.targets.first
node.lefts.first
end
end

Expand Down Expand Up @@ -578,7 +578,10 @@ def test_ModuleNode

def test_MultiTargetNode
assert_location(MultiTargetNode, "for foo, bar in baz do end", 4...12, &:index)
assert_location(MultiTargetNode, "foo, (bar, baz) = qux", 5...15) { |node| node.targets.last }
assert_location(MultiTargetNode, "foo, (bar, baz) = qux", 5...15) { |node| node.lefts.last }
assert_location(MultiTargetNode, "def foo((bar)); end", 8...13) do |node|
node.parameters.requireds.first
end
end

def test_MultiWriteNode
Expand Down Expand Up @@ -676,12 +679,6 @@ def test_RequiredParameterNode
end
end

def test_RequiredDestructuredParameterNode
assert_location(RequiredDestructuredParameterNode, "def foo((bar)); end", 8...13) do |node|
node.parameters.requireds.first
end
end

def test_RescueNode
code = <<~RUBY
begin
Expand Down Expand Up @@ -736,7 +733,7 @@ def test_SourceLineNode
end

def test_SplatNode
assert_location(SplatNode, "*foo = bar", 0...4) { |node| node.targets.first }
assert_location(SplatNode, "*foo = bar", 0...4, &:rest)
end

def test_StatementsNode
Expand Down
4 changes: 3 additions & 1 deletion test/prism/snapshots/arrays.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions test/prism/snapshots/for.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion test/prism/snapshots/method_calls.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 18 additions & 12 deletions test/prism/snapshots/methods.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions test/prism/snapshots/procs.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 80c48e5

Please sign in to comment.