class Opal::Parser::Scope

along with the scope implementation.
temp variables and ivars so they can be processed and output
being processed. It is used to keep track of used variables,
Instances of Scope are used by the parser when a new scope is

def add_arg(arg)

def add_arg(arg)
  @args << arg unless @args.include? arg
end

def add_ivar(ivar)

def add_ivar(ivar)
  if def_in_class?
    @parent.add_proto_ivar ivar
  else
    @ivars << ivar unless @ivars.include? ivar
  end
end

def add_local(local)

def add_local(local)
  return if has_local? local
  @locals << local
end

def add_proto_ivar(ivar)

def add_proto_ivar(ivar)
  @proto_ivars << ivar unless @proto_ivars.include? ivar
end

def add_temp(*tmps)

def add_temp(*tmps)
  @temps.push *tmps
end

def class?

def class?
  @type == :class
end

def class_scope?

Returns true if this scope is a class/module body scope
def class_scope?
  @type == :class or @type == :module
end

def def_in_class?

class body
used for optimizing ivars as we can set them to nil in the
Is this a normal def method directly inside a class? This is
def def_in_class?
  !@defs && @type == :def && @parent && @parent.class?
end

def get_super_chain

def get_super_chain
  chain, scope, defn, mid = [], self, 'null', 'null'
  while scope
    if scope.type == :iter
      chain << scope.identify!
      scope = scope.parent if scope.parent
    elsif scope.type == :def
      defn = scope.identify!
      mid  = "'$#{scope.mid}'"
      break
    else
      break
    end
  end
  [chain, defn, mid]
end

def has_local?(local)

def has_local?(local)
  return true if @locals.include? local or @args.include? local
  return @parent.has_local?(local) if @parent and @type == :iter
  false
end

def has_temp?(tmp)

def has_temp?(tmp)
  @temps.include? tmp
end

def identify!

def identify!
  return @identity if @identity
  @identity = @parser.unique_temp
  @parent.add_temp @identity if @parent
  @identity
end

def identity

def identity
  @identity
end

def in_while?

def in_while?
  !@while_stack.empty?
end

def initialize(type, parser)

def initialize(type, parser)
  @parser  = parser
  @type    = type
  @locals  = []
  @temps   = []
  @args    = []
  @ivars   = []
  @parent  = nil
  @queue   = []
  @unique  = "a"
  @while_stack = []
  @defines_defs = false
  @defines_defn = false
  @methods  = []
  @smethods = []
  @uses_block = false
  # used by classes to store all ivars used in direct def methods
  @proto_ivars = []
end

def iter?

def iter?
  @type == :iter
end

def module?

def module?
  @type == :module
end

def new_temp

def new_temp
  return @queue.pop unless @queue.empty?
  tmp = "_#{@unique}"
  @unique = @unique.succ
  @temps << tmp
  tmp
end

def pop_while

def pop_while
  @while_stack.pop
end

def proto

def proto
  "def"
end

def push_while

def push_while
  info = {}
  @while_stack.push info
  info
end

def queue_temp(name)

def queue_temp(name)
  @queue << name
end

def should_donate?

def should_donate?
  @type == :module or @name.to_s == 'Object'
end

def to_donate_methods

Generates code for this module to donate methods
def to_donate_methods
  out = ""
  if should_donate? and !@methods.empty?
  # unless @methods.empty?
    out += "%s;#{@name}._donate([%s]);" %
      [@parser.parser_indent, @methods.map(&:inspect).join(', ')]
  end
  unless @smethods.empty?
    out += "%s;#{@name}._sdonate([%s]);" %
      [@parser.parser_indent, @smethods.map(&:inspect).join(', ')]
  end
  out
end

def to_vars

Vars to use inside each scope
#
def to_vars
  vars = @locals.map { |l| "#{l} = nil" }
  vars.push *@temps
  current_self = @parser.current_self
  iv = ivars.map do |ivar|
   "if (#{current_self}#{ivar} == null) #{current_self}#{ivar} = nil;\n"
  end
  indent = @parser.parser_indent
  res = vars.empty? ? '' : "var #{vars.join ', '};"
  str = ivars.empty? ? res : "#{res}\n#{indent}#{iv.join indent}"
  if class? and !@proto_ivars.empty?
    pvars = @proto_ivars.map { |i| "#{proto}#{i}"}.join(' = ')
    "%s\n%s%s = nil;" % [str, indent, pvars]
  else
    str
  end
end

def top?

def top?
  @type == :top
end

def uses_block!

def uses_block!
  if @type == :iter && @parent
    @parent.uses_block!
  else
    @uses_block = true
    # identify!
  end
end

def uses_block?

def uses_block?
  @uses_block
end