whitequark / parser

A Ruby parser.
Other
1.57k stars 197 forks source link

Fix an error for flip-flop with beginless or endless ranges #946

Closed koic closed 11 months ago

koic commented 11 months ago

This PR resolves https://github.com/rubocop/rubocop/issues/12198.

$ ruby-parse -e 'if foo..; end'
Failed on: (fragment:0)
/Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.3/lib/parser/builders/default.rb:1676:
in `check_condition': undefined method `type' for nil (NoMethodError)

      case cond.type
               ^^^^^
        from /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.3/lib/parser/builders/default.rb:1707:
        in `check_condition'
        from /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.3/lib/parser/builders/default.rb:1275:
        in `condition'

I'm not sure if there's any significance to using the flip-flop syntax with nil, but by using beginless or endless ranges and explicitly specifying nil, the following current behaviors are made compatible:

iflipflop with explicitly nil

$ ruby-parse -e 'if foo..nil ; end'
(if
  (iflipflop
    (send nil :foo)
    (nil)) nil nil)
$ ruby-parse -e 'if nil..bar ; end'
(if
  (iflipflop
    (nil)
    (send nil :bar)) nil nil)

eflipflop with explicitly nil

$ ruby-parse -e 'if foo...nil ; end'
(if
  (eflipflop
    (send nil :foo)
    (nil)) nil nil)
$ ruby-parse -e 'if nil...bar ; end'
(if
  (eflipflop
    (nil)
    (send nil :bar)) nil nil)

The difference in the flip-flop with beginless or endless ranges is that s(:nil) is replaced by nil in the flip-flop ASTs.

This is reflected in the tests.

iliabylich commented 11 months ago

Thanks. Do you need a release?

koic commented 11 months ago

Thank you! If you could release it, one issue of RuboCop would be resolved :-)

iliabylich commented 11 months ago

Sure, 3.2.2.4 has been released.