class CodeTools::AST::Parameters

Attributes

block_arg[R]
block_index[R]
defaults[RW]
keywords[RW]
kwrest[RW]
kwrest_index[R]
names[RW]
optional[RW]
post[RW]
required[RW]
splat[RW]

Public Class Methods

new(line, required=nil, optional=nil, splat=nil, post=nil, kwargs=nil, kwrest=nil, block=nil) click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 357
def initialize(line, required=nil, optional=nil, splat=nil,
               post=nil, kwargs=nil, kwrest=nil, block=nil)
  @line = line
  @defaults = nil
  @keywords = nil
  @block_arg = nil
  @splat_index = nil
  @block_index = nil
  @kwrest_index = nil
  @locals = []
  @local_index = 0

  names = []

  process_fixed_arguments Array(required), @required = [], names

  if optional
    @defaults = DefaultArguments.new line, optional
    @optional = @defaults.names
    names.concat @optional
    @locals.concat @defaults.arguments
  else
    @optional = []
  end

  case splat
  when Symbol
    names << splat
    @locals << splat
  when true
    splat = :*
    @locals << splat
  when false
    splat = nil
    @splat_index = -3
  end

  @splat = splat

  process_fixed_arguments post, @post = [], names

  if kwargs || kwrest
    placeholder_var = local_placeholder
    @locals << placeholder_var
  end

  kwrest = placeholder_var if kwrest == true

  if kwargs
    @keywords = KeywordParameters.new line, kwargs, kwrest
    names.concat @keywords.names
  elsif kwrest
    @keywords = KeywordParameters.new line, nil, kwrest
  end

  @keywords.value = LocalVariableAccess.new line, placeholder_var if @keywords

  if kwrest
    @kwrest_index = total_args + @keywords.arguments.length + 1
    @kwrest_index += 1 if block
  end

  @names = names

  self.block_arg = block
end

Public Instance Methods

arity() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 490
def arity
  arity = required_args

  if @keywords and @keywords.required?
    arity += 1
  end

  if @splat or not @optional.empty? or
      (@keywords and not @keywords.required?)
    arity = -arity - 1
  end

  arity
end
block_arg=(block) click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 452
def block_arg=(block)
  case block
  when BlockArgument
    @block_arg = block
  when nil
    return
  else
    @block_arg = BlockArgument.new @line, block
  end

  @locals.pop if @locals.last.kind_of? BlockArgument
  @names.pop if @names.last.kind_of? BlockArgument

  @block_index = @locals.size
  @locals << @block_arg
  @names << @block_arg.name
end
bytecode(g) click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 522
def bytecode(g)
  g.state.check_for_locals = false
  map_arguments g.state.scope

  @required.each_with_index do |arg, index|
    if arg.kind_of? MultipleAssignment
      g.push_local index
      arg.bytecode(g)
      g.pop
    end
  end

  @defaults.bytecode(g) if @defaults

  index = @required.size + @optional.size
  index += 1 if @splat_index

  @post.each do |arg|
    if arg.kind_of? MultipleAssignment
      g.push_local index
      index += 1
      arg.bytecode(g)
      g.pop
    end
  end

  @keywords.bytecode(g) if @keywords

  @block_arg.bytecode(g) if @block_arg

  g.state.check_for_locals = true
end
local_placeholder() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 448
def local_placeholder
  :"_:#{@local_index += 1}"
end
map_arguments(scope) click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 505
def map_arguments(scope)
  @locals.map do |v|
    case v
    when Symbol
      scope.new_local v
    when MultipleAssignment
      scope.assign_local_reference v.right
    when LocalVariable
      scope.assign_local_reference v
    when nil
      STDERR.puts @locals.inspect, self.inspect
    end
  end

  @keywords.map_arguments(scope) if @keywords
end
post_args() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 474
def post_args
  @post.size
end
process_fixed_arguments(array, arguments, names) click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 424
def process_fixed_arguments(array, arguments, names)
  if array
    array.each do |arg|
      case arg
      when :_
        var = names.include?(:_) ? local_placeholder : arg
        names << arg
      when Symbol
        var = arg
        names << arg
      when MultipleAssignment
        var = arg
        var.right = LocalVariableAccess.new line, local_placeholder
      when VariableAssignment
        var = arg
        names << var.name
      end

      arguments << var
      @locals << var
    end
  end
end
required_args() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 470
def required_args
  @required.size + @post.size
end
splat_index() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 484
def splat_index
  return @splat_index if @splat_index

  return @required.size + @optional.size if @splat
end
to_sexp() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 555
def to_sexp
  sexp = [:args]

  @required.each do |a|
    case a
    when Symbol
      sexp << a
    when Node
      sexp << a.to_sexp
    end
  end

  sexp += @defaults.names if @defaults

  if @splat == :*
    sexp << :*
  elsif @splat
    sexp << :"*#{@splat}"
  end

  if @post
    @post.each do |a|
      case a
      when Symbol
        sexp << a
      when Node
        sexp << a.to_sexp
      end
    end
  end

  sexp += @keywords.names if @keywords

  sexp << :"&#{@block_arg.name}" if @block_arg

  sexp << [:block] + @defaults.to_sexp if @defaults
  sexp << @keywords.to_sexp if @keywords

  sexp
end
total_args() click to toggle source
# File lib/rubinius/code/ast/definitions.rb, line 478
def total_args
  args = @required.size + @optional.size + @post.size
  args += 1 if @keywords
  args
end