tree-sitter-ruby
tree-sitter-ruby copied to clipboard
Incorrect precedence for indexing with comparison
While investigating #146 , I discovered that the tree for a comparison of an indexed object appears incorrect.
Consider the following program:
x [0] == 1
tree-sitter-ruby will emit the following CST:
(program [0, 0] - [1, 0]
(call [0, 0] - [0, 10]
method: (identifier [0, 0] - [0, 1])
arguments: (argument_list [0, 2] - [0, 10]
(binary [0, 2] - [0, 10]
left: (array [0, 2] - [0, 5]
(integer [0, 3] - [0, 4]))
right: (integer [0, 9] - [0, 10])))))
That is, this is interpreted as equivalent to:
x([0] == 1)
whereas Ruby evaluates this as:
(x[0]) == 1
This can be confirmed by running
x = [1, 2, 3]
z = x [0] == 1
puts z
which prints true
.
I believe the correct CST should be:
(program [0, 0] - [1, 0]
(binary [0, 0] - [0, 10]
left: (element_reference [0, 0] - [0, 5]
object: (identifier [0, 0] - [0, 1])
(integer [0, 3] - [0, 4]))
right: (integer [0, 9] - [0, 10])))
I did a little more investigation with irb, and I think my conclusion is that the tree-sitter CST would need to be context-sensitive in order to represent programs consistently with mruby:
irb(main):001:0> x = [0, 1, 2]
=> [0, 1, 2]
irb(main):002:0> x [0]
=> 0
irb(main):003:0> def y(z)
irb(main):004:1> z
irb(main):005:1> end
=> :y
irb(main):006:0> y [0]
=> [0]
irb(main):007:0> x [0] == 0
=> true
irb(main):008:0> y [0] == 0
=> false
irb(main):009:0> y [0] == [0]
=> true
One suggestion here would be to completely collapse element referencing with method invocation.