seattlerb / debride

Analyze code for potentially uncalled / dead methods, now with auto-removal.
https://www.zenspider.com/projects/debride.html
720 stars 19 forks source link

Debride blows up with Racc::ParseError after upgrade to ruby 2.2.3 #22

Closed phiggins closed 9 years ago

phiggins commented 9 years ago

We just upgrade a rails app to use ruby 2.2.3 from 2.1.6, and I'm getting an exception parsing some ERB. Here's a minimal case I came up with:

pete@balloon:~/work/estately$ cat test.html.erb 
:
<%= link_to '1 day ago', :days => 1 %>
pete@balloon:~/work/estately$ debride test.html.erb 
/home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/racc/parser.rb:527:in `on_error': test.html.erb:1 :: parse error on value 1 (tINTEGER) (Racc::ParseError)
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1124:in `on_error'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/racc/parser.rb:258:in `_racc_do_parse_c'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/racc/parser.rb:258:in `do_parse'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1036:in `block in process'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:88:in `block in timeout'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `block in catch'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `catch'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `catch'
    from /home/pete/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:103:in `timeout'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1024:in `process'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1362:in `block in process'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1360:in `each'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/ruby_parser-3.7.1/lib/ruby_parser_extras.rb:1360:in `process'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-erb-1.0.1/lib/debride_erb.rb:22:in `process_erb'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-1.5.1/lib/debride.rb:94:in `block in run'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-1.5.1/lib/debride.rb:81:in `each'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-1.5.1/lib/debride.rb:81:in `run'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-1.5.1/lib/debride.rb:76:in `run'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/gems/debride-1.5.1/bin/debride:5:in `<top (required)>'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/bin/debride:23:in `load'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/bin/debride:23:in `<main>'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/bin/ruby_executable_hooks:15:in `eval'
    from /home/pete/.rvm/gems/ruby-2.2.3@estately/bin/ruby_executable_hooks:15:in `<main>'

Here's my debride versions:

pete@balloon:~/work/estately$ gem list debride

*** LOCAL GEMS ***

debride (1.5.1)
debride-erb (1.0.1)
debride-haml (1.0.0)
zenspider commented 9 years ago

Interesting! uhh... does ERB even need to play a part? Can you reduce this?

phiggins commented 9 years ago

Good point, I'm not sure. That was just where the failure had happened.

phiggins commented 9 years ago

If I move the code in the <%= %> tags into a ruby file and use debride on it, it parses fine.

zenspider commented 9 years ago
  def test_process_erb_bug
    # :
    # <%= link_to '1 day ago', :days => 1 %>

    # _buf = ''
    # _buf << ':\n'
    # @output_buffer.append=( link_to '1 day ago', :days => 1 )
    # _buf << '\n'
    # _buf.to_s

    sexp = Debride.new.process_erb "test/bug.erb"

    exp = s(:block,
            s(:lasgn, :_buf, s(:str, "")),
            s(:call, s(:lvar, :_buf), :<<, s(:str, ":\n")),
            s(:attrasgn, s(:ivar, :@output_buffer), :append=,
              s(:call, nil, :link_to,
                s(:str, "1 day ago"), s(:hash, s(:lit, :days), s(:lit, 1)))),
            s(:call, s(:lvar, :_buf), :<<, s(:str, "\n")),
            s(:call, s(:lvar, :_buf), :to_s))

    assert_equal exp, sexp
  end

this passes on ruby 2.0 and 2.2.2. Do you really think it is specific to ruby 2.2.3??

phiggins commented 9 years ago

It doesn't appear to be specific to 2.2.3. If I do a gem install debride debride-erb in a clean environment with any of the ruby versions I have installed locally I get the same failure.

Here are the ruby versions I tried:

ruby-1.9.3-p551
ruby-2.0.0-p598
ruby-2.1.5
ruby-2.1.6
ruby-2.2.0
ruby-2.2.1
ruby-2.2.3
phiggins commented 9 years ago

Here is my test script and output in case I'm doing something stupid: https://gist.github.com/phiggins/8edab52615f622bb4d56

zenspider commented 9 years ago

I'm fucking stumped by this stupid bug. I can reproduce it via top-level running, but not via tests. The code is all the same. The entry points look fine. But no boom. WTF.

zenspider commented 9 years ago

This was a bitch to fix. Done.

phiggins commented 9 years ago

Yay! :tada: