tree-sitter-ruby icon indicating copy to clipboard operation
tree-sitter-ruby copied to clipboard

Incorrect precedence for indexing with comparison

Open nbrahms opened this issue 4 years ago • 1 comments

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])))

nbrahms avatar Jan 20 '21 20:01 nbrahms

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.

nbrahms avatar Jan 20 '21 23:01 nbrahms