Class: RipperPlus::ScopeStack

Inherits:
Object
  • Object
show all
Defined in:
lib/ripper-plus/scope_stack.rb

Overview

internal class that manages the current scopes.

Constant Summary collapse

SCOPE_BLOCKER_9000 =
:scope_block

Instance Method Summary collapse

Constructor Details

#initializeScopeStack

Returns a new instance of ScopeStack.



6
7
8
9
10
# File 'lib/ripper-plus/scope_stack.rb', line 6

def initialize
  # simplifies algorithm to have the scope blocker be the stack base
  @stack = [SCOPE_BLOCKER_9000, Set.new]
  @in_method = false
end

Instance Method Details

#add_variable(var, allow_duplicates = true) ⇒ Object



28
29
30
31
32
33
# File 'lib/ripper-plus/scope_stack.rb', line 28

def add_variable(var, allow_duplicates=true)
  if !allow_duplicates && @stack.last.include?(var)
    raise DuplicateArgumentError.new("duplicated argument name (#{var})")
  end
  @stack.last << var
end

#has_variable?(var) ⇒ Boolean

Checks if the given variable is in scope.

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
# File 'lib/ripper-plus/scope_stack.rb', line 57

def has_variable?(var)
  @stack.reverse_each do |scope|
    if SCOPE_BLOCKER_9000 == scope
      return false
    elsif scope.include?(var)
      return true
    end
  end
end

#in_method?Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/ripper-plus/scope_stack.rb', line 12

def in_method?
  @in_method
end

#inspectObject

For debugging purposes



17
18
19
20
21
22
23
24
25
26
# File 'lib/ripper-plus/scope_stack.rb', line 17

def inspect
  middle = @stack.map do |scope|
    if SCOPE_BLOCKER_9000 == scope
      '||'
    else
      "[ #{scope.to_a.sort.join(', ')} ]"
    end
  end.join(' ')
  "< #{middle} >"
end

#with_closed_scope(is_method = false) ⇒ Object

An open scope denies reference to local variables in enclosing scopes.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ripper-plus/scope_stack.rb', line 44

def with_closed_scope(is_method = false)
  old_in_method = @in_method
  @in_method ||= is_method
  @stack.push(SCOPE_BLOCKER_9000)
  @stack.push(Set.new)
  yield
ensure
  @stack.pop  # pop closed scope
  @stack.pop  # pop scope blocker
  @in_method = old_in_method
end

#with_open_scopeObject

An open scope permits reference to local variables in enclosing scopes.



36
37
38
39
40
41
# File 'lib/ripper-plus/scope_stack.rb', line 36

def with_open_scope
  @stack.push(Set.new)
  yield
ensure
  @stack.pop  # pops open scope
end