module RipperRubyParser::SexpHandlers::Blocks

Sexp handlers for blocks and related constructs

Public Instance Methods

process_begin(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 58
def process_begin(exp)
  _, body, pos = exp.shift 3

  body = convert_void_stmt_to_nil_symbol process(body)
  with_position pos, s(:begin, body)
end
process_block_var(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 45
def process_block_var(exp)
  _, args, shadowargs = exp.shift 3

  names = process(args)

  if shadowargs
    shadowargs = map_process_list(shadowargs).map { |item| item[1] }
    names << s(:shadow, *shadowargs)
  end

  convert_arguments names
end
process_bodystmt(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 77
def process_bodystmt(exp)
  _, main, rescue_block, else_block, ensure_block = exp.shift 5

  body_list = []

  main_block = process(main)
  line = main_block.line
  body_list << main_block if main_block.sexp_type != :void_stmt

  body_list.push(*process(rescue_block)) if rescue_block
  body_list << process(else_block) if else_block
  body_list = [s(:rescue, *body_list)] if rescue_block

  if ensure_block
    body_list << process(ensure_block)
    body_list = [s(:ensure, *body_list)]
  end

  wrap_in_block(body_list, line)
end
process_break(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 119
def process_break(exp)
  _, args = exp.shift 2
  args = handle_return_argument_list(args)
  if args.empty?
    s(:break)
  else
    s(:break, args)
  end
end
process_ensure(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 104
def process_ensure(exp)
  _, block = exp.shift 2
  convert_empty_to_nil_symbol safe_unwrap_void_stmt process(block)
end
process_kwrest_param(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 40
def process_kwrest_param(exp)
  _, sym, = exp.shift 3
  process(sym) || s(:lvar, :"")
end
process_lambda(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 129
def process_lambda(exp)
  _, args, statements = exp.shift 3

  old_type = args.sexp_type
  args = convert_arguments(process(args))
  statements = process(statements)
  line = args.line || statements.line
  args = nil if args == s(:args) && old_type == :params
  call = s(:lambda)
  call.line = line

  make_iter call, args, safe_unwrap_void_stmt(statements)
end
process_method_add_block(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 7
def process_method_add_block(exp)
  _, call, block = exp.shift 3
  _, args, stmt = block
  call = process(call)
  args = process(args)
  kwrest = kwrest_param(args) if args
  stmt = with_kwrest(kwrest) { process(stmt) }
  make_iter call, args, safe_unwrap_void_stmt(stmt)
end
process_next(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 109
def process_next(exp)
  _, args = exp.shift 2
  args = handle_return_argument_list(args)
  if args.empty?
    s(:next)
  else
    s(:next, args)
  end
end
process_params(exp) click to toggle source

NOTE: Argument forwarding is handled differently in Ruby 3.0 and 3.1 3.0: s(:params, nil, nil, s(:args_forward), nil, nil, nil, nil) 3.1: s(:params, nil, nil, nil, nil, nil, s(:args_forward), :&)

# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 20
def process_params(exp)
  _, normal, defaults, splat, rest, kwargs, doublesplat, block = exp.shift 8

  args =
    handle_normal_arguments(normal) +
    handle_default_arguments(defaults) +
    handle_splat(splat) +
    handle_normal_arguments(rest) +
    handle_kwargs(kwargs) +
    handle_double_splat(doublesplat) +
    handle_block_argument(block)

  s(:args, *args)
end
process_rescue(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 65
def process_rescue(exp)
  _, eclass, evar, block, after = exp.shift 5
  rescue_block = map_process_list_compact block.sexp_body
  rescue_block << nil if rescue_block.empty?

  capture = handle_rescue_class_list eclass

  capture << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar

  s(s(:resbody, capture, *rescue_block), *process(after))
end
process_rescue_mod(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 98
def process_rescue_mod(exp)
  _, scary, safe = exp.shift 3

  s(:rescue, process(scary), s(:resbody, s(:array), process(safe)))
end
process_rest_param(exp) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 35
def process_rest_param(exp)
  _, ident = exp.shift 2
  s(:splat, process(ident))
end

Private Instance Methods

handle_block_argument(block) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 197
def handle_block_argument(block)
  return [] unless block
  return [] if block == :& # Part of argument forwarding in Ruby 3.1; ignore

  [process(block)]
end
handle_default_arguments(defaults) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 151
def handle_default_arguments(defaults)
  return [] unless defaults

  defaults.map do |sym, val|
    s(:lasgn,
      extract_node_symbol(process(sym)),
      process(val))
  end
end
handle_double_splat(doublesplat) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 185
def handle_double_splat(doublesplat)
  return [] unless doublesplat

  contents = process(doublesplat)
  case contents.sexp_type
  when :forward_args # Argument forwarding in Ruby 3.1
    [contents]
  else
    [s(:dsplat, contents)]
  end
end
handle_kwargs(kwargs) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 172
def handle_kwargs(kwargs)
  return [] unless kwargs

  kwargs.map do |sym, val|
    symbol = extract_node_symbol process(sym)
    if val
      s(:kwarg, symbol, process(val))
    else
      s(:kwarg, symbol)
    end
  end
end
handle_normal_arguments(normal) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 145
def handle_normal_arguments(normal)
  return [] unless normal

  map_process_list normal
end
handle_rescue_class_list(eclass) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 204
def handle_rescue_class_list(eclass)
  if eclass.nil?
    s(:array)
  elsif eclass.first.is_a? Symbol
    eclass = process(eclass)
    body = eclass.sexp_body
    if eclass.sexp_type == :mrhs
      body.first
    else
      s(:array, *body)
    end
  else
    s(:array, process(eclass.first))
  end
end
handle_splat(splat) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 161
def handle_splat(splat)
  if splat == 0
    # Only relevant for Ruby < 2.6
    [s(:excessed_comma)]
  elsif splat
    [process(splat)]
  else
    []
  end
end
make_iter(call, args, stmt) click to toggle source
# File lib/ripper_ruby_parser/sexp_handlers/blocks.rb, line 220
def make_iter(call, args, stmt)
  args[-1] = nil if args && args.last == s(:excessed_comma)
  args ||= 0
  if stmt.empty?
    s(:iter, call, args)
  else
    s(:iter, call, args, stmt)
  end
end