module RipperRubyParser module SexpHandlers module Literals def process_string_literal exp _, content = exp.shift 2 process(content) end def process_string_content exp exp.shift string, rest = extract_string_parts exp if rest.empty? s(:str, string) else s(:dstr, string, *rest) end end def process_string_embexpr exp _, list = exp.shift 2 s(:evstr, process(list.first)) end def process_regexp_literal exp _, content, _ = exp.shift 3 string = extract_inner_string content[0] s(:lit, Regexp.new(string[1])) end def process_symbol_literal exp _, symbol = exp.shift 2 process(symbol) end def process_symbol exp _, node = exp.shift 2 with_position_from_node_symbol(node) {|sym| s(:lit, sym) } end def process_dyna_symbol exp _, list = exp.shift 2 string, rest = extract_string_parts list if rest.empty? s(:lit, string.to_sym) else s(:dsym, string, *rest) end end def process_at_tstring_content exp _, string, _ = exp.shift 3 s(:str, string) end private def extract_inner_string exp process(exp) || s(:str, "") end def extract_string_parts exp inner = exp.shift string = extract_inner_string(inner) rest = [] if string.sexp_type == :str string = string[1] else rest << string string = "" end string = unescape(string) until exp.empty? do result = process(exp.shift) if result.sexp_type == :str result[1] = unescape(result[1]) end rest << result end return string, rest end def unescape string string.gsub(/(\\[n\\"])/) do eval "\"#{$1}\"" end end end end end