require 'ripper' require 'ripper_ruby_parser/syntax_error' require 'ripper_ruby_parser/unescape' module RipperRubyParser # Variant of Ripper's SexpBuilder parser class that inserts comments as # Sexps into the built parse tree. # # @api private class CommentingRipperParser < Ripper::SexpBuilder def initialize(*args) super @comment = nil @comment_stack = [] @delimiter_stack = [] @in_symbol = false end def parse result = suppress_warnings { super } raise 'Ripper parse failed.' unless result Sexp.from_array(result) end def on_backtick(delimiter) @delimiter_stack.push delimiter super end def on_comment(tok) @comment ||= '' @comment += tok super end def on_kw(tok) case tok when 'class', 'def', 'module' unless @in_symbol @comment_stack.push [tok.to_sym, @comment] @comment = nil end end super end def on_module(*args) commentize(:module, super) end def on_class(*args) commentize(:class, super) end def on_sclass(*args) commentize(:class, super) end def on_def(*args) commentize(:def, super) end def on_defs(*args) commentize(:def, super) end def on_args_new [:args] end def on_args_add(list, elem) list << elem end def on_heredoc_beg(delimiter) @delimiter_stack.push delimiter super end def on_heredoc_end(delimiter) @delimiter_stack.pop super end def on_mlhs_new [:mlhs] end def on_mlhs_add(list, elem) if list.first == :mlhs list << elem else [:mlhs_add_post, list, elem] end end def on_mrhs_new [:mrhs] end def on_mrhs_add(list, elem) list << elem end def on_qsymbols_beg(delimiter) @delimiter_stack.push delimiter super end def on_qsymbols_new [:qsymbols] end def on_qsymbols_add(list, elem) list << elem end def on_qwords_beg(delimiter) @delimiter_stack.push delimiter super end def on_qwords_new [:qwords] end def on_qwords_add(list, elem) list << elem end def on_regexp_beg(delimiter) @delimiter_stack.push delimiter super end def on_regexp_end(delimiter) @delimiter_stack.pop super end def on_regexp_new [:regexp] end def on_regexp_add(list, elem) list << elem end def on_stmts_new [:stmts] end def on_stmts_add(list, elem) list << elem end def on_string_add(list, elem) list << elem end def on_symbols_beg(delimiter) @delimiter_stack.push delimiter super end def on_symbols_new [:symbols] end def on_symbols_add(list, elem) list << elem end def on_tstring_beg(delimiter) @delimiter_stack.push delimiter super end def on_tstring_content(content) content = case @delimiter_stack.last when /^<