module RipperRubyParser::SexpHandlers::StringLiterals

Sexp handlers for string and stringlike literals

Constants

INTERPOLATING_HEREDOC
INTERPOLATING_STRINGS
INTERPOLATING_WORD_LIST
NON_INTERPOLATING_HEREDOC
NON_INTERPOLATING_STRINGS
NON_INTERPOLATING_WORD_LIST
REGEXP_LITERALS

Public Instance Methods

process_at_tstring_content(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 124
def process_at_tstring_content(exp)
  _, content, pos, delim = exp.shift 4
  string = fix_encoding handle_string_unescaping(content, delim)
  with_position(pos, s(:str, string))
end
process_dyna_symbol(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 107
def process_dyna_symbol(exp)
  _, node = exp.shift 2
  handle_dyna_symbol_content(node)
end
process_qsymbols(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 112
def process_qsymbols(exp)
  _, *items = shift_all(exp)
  items = items.map { |item| handle_symbol_content(item) }
  s(:qsymbols, *items)
end
process_regexp(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 91
def process_regexp(exp)
  _, *rest = shift_all exp
  line, string, rest = extract_string_parts(rest)
  with_line_number(line, s(:dregx, string, *rest))
end
process_regexp_literal(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 76
def process_regexp_literal(exp)
  _, content, (_, flags,) = exp.shift 3

  content = process(content)
  numflags = character_flags_to_numerical flags

  if content.length == 2
    return with_line_number(content.line, s(:lit, Regexp.new(content.last, numflags)))
  end

  content.sexp_type = :dregx_once if /o/.match?(flags)
  content << numflags unless numflags == 0
  content
end
process_string_concat(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 46
def process_string_concat(exp)
  _, left, right = exp.shift 3

  left = process(left)
  right = process(right)

  if left.sexp_type == :str
    merge_left_into_right(left, right)
  else
    merge_right_into_left(left, right)
  end
end
process_string_content(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 12
def process_string_content(exp)
  _, *rest = shift_all exp
  line, string, rest = extract_string_parts(rest)

  if rest.empty?
    with_line_number(line, s(:str, string))
  else
    s(:dstr, string, *rest)
  end
end
Also aliased as: process_word
process_string_dvar(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 40
def process_string_dvar(exp)
  _, list = exp.shift 2
  val = process(list)
  s(:dstr, "", s(:evstr, val))
end
process_string_embexpr(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 25
def process_string_embexpr(exp)
  _, list = exp.shift 2

  val = process(list.sexp_body.first)

  case val.sexp_type
  when :str, :dstr
    val
  when :void_stmt
    s(:dstr, "", s(:evstr))
  else
    s(:dstr, "", s(:evstr, val))
  end
end
process_string_literal(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 7
def process_string_literal(exp)
  _, content = exp.shift 2
  process(content)
end
process_symbol(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 102
def process_symbol(exp)
  _, node = exp.shift 2
  handle_symbol_content(node)
end
process_symbol_literal(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 97
def process_symbol_literal(exp)
  _, symbol = exp.shift 2
  handle_symbol_content(symbol)
end
process_symbols(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 118
def process_symbols(exp)
  _, *items = shift_all(exp)
  items = items.map { |item| handle_dyna_symbol_content(item) }
  s(:symbols, *items)
end
process_word(exp)
process_xstring(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 64
def process_xstring(exp)
  _, *rest = shift_all exp
  line, string, rest = extract_string_parts(rest)
  result = if rest.empty?
             s(:xstr, string)
           else
             s(:dxstr, string, *rest)
           end
  result.line = line
  result
end
process_xstring_literal(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 59
def process_xstring_literal(exp)
  _, content = exp.shift 2
  process(content)
end

Private Instance Methods

character_flags_to_numerical(flags) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 180
def character_flags_to_numerical(flags)
  numflags = 0

  numflags = Regexp::MULTILINE if /m/.match?(flags)
  numflags |= Regexp::EXTENDED if /x/.match?(flags)
  numflags |= Regexp::IGNORECASE if /i/.match?(flags)

  numflags |= Regexp::NOENCODING if /n/.match?(flags)
  numflags |= Regexp::FIXEDENCODING if /[ues]/.match?(flags)

  numflags
end
extract_string_parts(list) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 132
def extract_string_parts(list)
  return nil, "", [] if list.empty?

  list = merge_raw_string_literals list
  list = map_process_list list
  parts = unpack_dstr list
  merge_initial_string_literals(parts)
end
handle_dyna_symbol_content(node) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 193
def handle_dyna_symbol_content(node)
  type, *body = *process(node)
  case type
  when :str, :xstr
    s(:lit, body.first.to_sym)
  when :dstr, :dxstr
    s(:dsym, *body)
  end
end
handle_string_unescaping(content, delim) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 238
def handle_string_unescaping(content, delim)
  case delim
  when INTERPOLATING_HEREDOC, *INTERPOLATING_STRINGS
    unescape(content)
  when INTERPOLATING_WORD_LIST
    unescape_wordlist_word(content)
  when *NON_INTERPOLATING_STRINGS
    simple_unescape(content, delim)
  when *REGEXP_LITERALS
    unescape_regexp(content)
  when NON_INTERPOLATING_WORD_LIST
    simple_unescape_wordlist_word(content, delim)
  else
    content
  end
end
handle_symbol_content(node) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 203
def handle_symbol_content(node)
  if node.sexp_type == :@kw
    symbol, position = extract_node_symbol_with_position(node)
    with_position(position, s(:lit, symbol))
  else
    processed = process(node)
    symbol = processed.last.to_sym
    line = processed.line
    with_line_number(line, s(:lit, symbol))
  end
end
merge_initial_string_literals(parts) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 169
def merge_initial_string_literals(parts)
  string = ""
  while parts.first&.sexp_type == :str
    str = parts.shift
    line ||= str.line
    string += str.last
  end

  return line, string, parts
end
merge_left_into_right(left, right) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 215
def merge_left_into_right(left, right)
  right[1] = left.last + right[1]
  right
end
merge_raw_string_literals(list) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 141
def merge_raw_string_literals(list)
  chunks = list.chunk { |it| it.sexp_type == :@tstring_content }
  chunks.flat_map do |is_simple, items|
    if is_simple && items.count > 1
      head = items.first
      contents = items.map { |it| it[1] }.join
      [s(:@tstring_content, contents, head[2], head[3])]
    else
      items
    end
  end
end
merge_right_into_left(left, right) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 220
def merge_right_into_left(left, right)
  if right.sexp_type == :str
    left.push right
  else
    _, first, *rest = right
    left.push s(:str, first) unless first.empty?
    left.push(*rest)
  end
end
unpack_dstr(list) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/string_literals.rb, line 154
def unpack_dstr(list)
  list.flat_map do |item|
    type, val, *rest = item
    if type == :dstr
      if val.empty?
        rest
      else
        [s(:str, val), *rest]
      end
    else
      [item]
    end
  end
end