seattlerb / ruby_parser

ruby_parser is a ruby parser written in pure ruby. It outputs s-expressions which can be manipulated and converted back to ruby via the ruby2ruby gem.
http://www.zenspider.com/projects/ruby_parser.html
476 stars 100 forks source link

parse error on value ".." (tDOT2) when it comes before a number in an infinite range #309

Closed mashedkeyboard closed 3 years ago

mashedkeyboard commented 4 years ago

Hi folks,

In Rails, this is valid syntax:

Model.where(updated_at: ..5.years.ago)

The infinite range is used to mean anything prior to 5 years ago, inclusive of today. However, this throws an error in ruby_parse:

#<Racc::ParseError: test.rb:3 :: parse error on value ".." (tDOT2)>

Interestingly, this seems to only be a problem when it's an infinite backwards range. Take the below examples:

# test.rb
puts %i[a b c d e][3..]
$ ruby test.rb 
d
e

$ ruby_parse test.rb
# file = test.rb loc = 1
s(:call,
 nil,
 :puts,
 s(:call,
  s(:array, s(:lit, :a), s(:lit, :b), s(:lit, :c), s(:lit, :d), s(:lit, :e)),
  :[],
  s(:dot2, s(:lit, 3), nil)))
done

 0.00s:   679.63 l/s:   15.93 Kb/s:    0 Kb:    1 loc:TOTAL

but

# test.rb
puts %i[a b c d e][..3]
$ ruby test.rb 
a
b
c
d

$ ruby_parse test.rb
# file = test.rb loc = 1
/home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/racc/parser.rb:544:in `on_error' #<Racc::ParseError: test.rb:1 :: parse error on value ".." (tDOT2)> for test.rb
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/racc/parser.rb:544:in `on_error'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser_extras.rb:1304:in `on_error'
  (eval):3:in `_racc_do_parse_c'
  (eval):3:in `do_parse'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser_extras.rb:1329:in `block in process'
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/timeout.rb:95:in `block in timeout'
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/timeout.rb:33:in `block in catch'
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/timeout.rb:33:in `catch'
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/timeout.rb:33:in `catch'
  /home/curtispf/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/timeout.rb:110:in `timeout'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser_extras.rb:1317:in `process'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser.rb:36:in `block in process'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser.rb:33:in `each'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/lib/ruby_parser.rb:33:in `process'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/bin/ruby_parse:50:in `block in <top (required)>'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/bin/ruby_parse:31:in `each'
  /home/curtispf/.rvm/gems/ruby-2.7.1/gems/ruby_parser-3.15.0/bin/ruby_parse:31:in `<top (required)>'
  /home/curtispf/.rvm/gems/ruby-2.7.1/bin/ruby_parse:23:in `load'
  /home/curtispf/.rvm/gems/ruby-2.7.1/bin/ruby_parse:23:in `<main>'
  /home/curtispf/.rvm/gems/ruby-2.7.1/bin/ruby_executable_hooks:24:in `eval'
  /home/curtispf/.rvm/gems/ruby-2.7.1/bin/ruby_executable_hooks:24:in `<main>'
done

 0.00s:   305.12 l/s:    7.15 Kb/s:    0 Kb:    1 loc:TOTAL

It'd be great to get this fixed! :) I'm using ruby_parser (3.15.0) with ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux].

Thanks!

hasanen commented 4 years ago

Same with three dots (tDOT3)

Model.where(updated_at: ...5.years.ago)
zenspider commented 3 years ago

Yup. Want to take a whack at it?

heyvito commented 3 years ago

Just to leave it documented, I also had issues with endless methods. I can try to come up with a PR for those cases Ryan. Just need a couple days. <3

ReganRyanNZ commented 3 years ago

Note that there's a new "forward everything" argument that is triple dots, that also breaks brakeman. For info on the syntax: https://blog.saeloun.com/2019/12/04/ruby-2-7-adds-new-operator-for-arguments-forwarding.html

presidentbeef commented 3 years ago

"Beginless" ranges are working on master, I believe.

And argument forwarding (triple dots) is in progress: #316 😉

LilyReile commented 3 years ago

@presidentbeef I can confirm that beginless ranges (at least the triple dot version) are not supported on main/5.1.1

:/

presidentbeef commented 3 years ago

@DylanReile should be if you use the brakeman 5.1.1 gem. Otherwise... yes, it's not released yet in ruby_parser.

LilyReile commented 3 years ago

@presidentbeef Hmm, I was using the brakeman 5.1.1 gem via bundle exec brakeman

presidentbeef commented 3 years ago

Oops, I misread this issue. Is your code similar to https://github.com/presidentbeef/brakeman/issues/1483#issuecomment-846500246?

zenspider commented 3 years ago
9225 % for S in ..1 2.. ...3 4... ; do rake debug R="$S"; done
s(:dot2, nil, s(:lit, 1))
s(:dot2, s(:lit, 2), nil)
s(:dot3, nil, s(:lit, 3))
s(:dot3, s(:lit, 4), nil)
zenspider commented 3 years ago

release coming soonish