class Opal::Nodes::DefNode

FIXME: needs rewrite

def compile

def compile
  extract_block_arg
  split_args
  inline_params = nil
  scope_name = nil
  # block name (&block)
  if block_arg
    block_name = variable(block_arg).to_sym
  end
  in_scope do
    scope.mid = mid
    scope.defs = true if recvr
    if block_name
      scope.uses_block!
      scope.add_arg block_name
    end
    scope.block_name = block_name || '$yield'
    inline_params = process(inline_args_sexp)
    stmt_code = stmt(compiler.returns(stmts))
    add_temp 'self = this'
    compile_inline_args
    compile_post_args
    scope.identify!
    scope_name = scope.identity
    compile_block_arg
    if compiler.arity_check?
      compile_arity_check
    end
    if scope.uses_zuper
      add_local '$zuper'
      add_local '$zuper_index'
      add_local '$zuper_length'
      line "$zuper = [];"
      line
      line "for($zuper_index = 0; $zuper_index < arguments.length; $zuper_index++) {"
      line "  $zuper[$zuper_index] = arguments[$zuper_index];"
      line "}"
    end
    unshift "\n#{current_indent}", scope.to_vars
    line stmt_code
    if scope.catch_return
      unshift "try {\n"
      line "} catch ($returner) { if ($returner === Opal.returner) { return $returner.$v }"
      push " throw $returner; }"
    end
  end
  #     This is a special utf8 char ---v
  function_name = valid_name?(mid) ? " ː#{mid}" : ''
  unshift ") {"
  unshift(inline_params)
  unshift "function#{function_name}("
  unshift "#{scope_name} = " if scope_name
  line "}"
  push ", #{scope_name}.$$arity = #{arity}"
  if compiler.arity_check?
    push ", #{scope_name}.$$parameters = #{parameters_code}"
  end
  if    recvr                         then unshift 'Opal.defs(', recv(recvr), ", '$#{mid}', "
  elsif scope.iter?                   then unshift "Opal.def(self, '$#{mid}', "
  elsif scope.module? || scope.class? then unshift "Opal.defn(self, '$#{mid}', "
  elsif scope.sclass? && scope.defs   then unshift "Opal.defs(self, '$#{mid}', "
  elsif scope.sclass?                 then unshift "Opal.defn(self, '$#{mid}', "
  elsif compiler.eval?                then unshift "Opal.def(self, '$#{mid}', "
  elsif scope.top?                    then unshift "Opal.defn(Opal.Object, '$#{mid}', "
  elsif scope.def?                    then unshift "Opal.def(self, '$#{mid}', "
  else raise "Unsupported use of `def`; please file a bug at https://github.com/opal/opal/issues/new reporting this message."
  end
  push ')'
  wrap '(', ", nil) && '#{mid}'" if expr?
end

def compile_arity_check

Returns code used in debug mode to check arity of method call
def compile_arity_check
  if arity_checks.size > 0
    meth = scope.mid.to_s.inspect
    line "var $arity = arguments.length;"
    push " if (#{arity_checks.join(' || ')}) { Opal.ac($arity, #{arity}, this, #{meth}); }"
  end
end

def extract_block_arg

def extract_block_arg
  if args.last.is_a?(Sexp) && args.last.type == :blockarg
    @block_arg = args.pop[1]
  end
end