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 interpolation in heredocs like strings #304

Closed presidentbeef closed 4 years ago

presidentbeef commented 4 years ago

RubyParser misidentifies #${ as global variable interpolation in heredocs:

2.7.0 :002'> RubyParser.new.parse '<<-HEREDOC
2.7.0 :003'> #${this is not actually interpolation!}
2.7.0 :004 > HEREDOC'
Traceback (most recent call last):
       16: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser.rb:33:in `process'
       15: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser.rb:33:in `each'
       14: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser.rb:36:in `block in process'
       13: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser_extras.rb:1285:in `process'
       12: from /home/justin/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/timeout.rb:110:in `timeout'
       11: from /home/justin/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `catch'
       10: from /home/justin/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `catch'
        9: from /home/justin/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `block in catch'
        8: from /home/justin/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/timeout.rb:95:in `block in timeout'
        7: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser_extras.rb:1297:in `block in process'
        6: from (eval):3:in `do_parse'
        5: from (eval):3:in `_racc_do_parse_c'
        4: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_parser_extras.rb:1262:in `next_token'
        3: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_lexer.rex.rb:334:in `next_token'
        2: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_lexer.rb:598:in `process_gvar_oddity'
        1: from /home/justin/.rvm/gems/ruby-2.7.0@brakeman/gems/ruby_parser-3.14.2/lib/ruby_lexer.rb:990:in `rb_compile_error'
RubyParser::SyntaxError ("${" is not allowed as a global variable name. near line 1: "this is not actually interpolation!}")

Ruby doesn't mind:

2.7.0 :005"> <<-HEREDOC
2.7.0 :006"> #${this is not actually interpolation!}
2.7.0 :007 > HEREDOC
 => "\#${this is not actually interpolation!}\n"

But also RubyParser only has a problem with this in heredocs:

2.7.0 :008 > RubyParser.new.parse '"#${this is not actually interpolation!}"'
 => s(:str, "\#${this is not actually interpolation!}")

So I straight copy-pasted the code from parse_string that I believe handles the same thing. I recognize this is a terrible way to "write" code.

From my testing, this did not introduce any regressions.

zenspider commented 4 years ago

Done. Thank you!

presidentbeef commented 4 years ago

Thanks!