Class: RuboCop::Cop::VariableForce::VariableTable Private
- Inherits:
-
Object
- Object
- RuboCop::Cop::VariableForce::VariableTable
- Defined in:
- lib/rubocop/cop/variable_force/variable_table.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
A VariableTable manages the lifetime of all scopes and local variables in a program. This holds scopes as stack structure, provides a way to add local variables to current scope, and find local variables by considering variable visibility of the current scope.
Instance Method Summary collapse
- #accessible_variables ⇒ Object private
- #assign_to_variable(name, node) ⇒ Object private
- #current_scope ⇒ Object private
- #current_scope_level ⇒ Object private
- #declare_variable(name, node) ⇒ Object private
- #find_variable(name) ⇒ Object private
-
#initialize(hook_receiver = nil) ⇒ VariableTable
constructor
private
A new instance of VariableTable.
- #invoke_hook(hook_name, *args) ⇒ Object private
- #pop_scope ⇒ Object private
- #push_scope(scope_node) ⇒ Object private
- #reference_variable(name, node) ⇒ Object private
- #scope_stack ⇒ Object private
- #variable_exist?(name) ⇒ Boolean private
Constructor Details
#initialize(hook_receiver = nil) ⇒ VariableTable
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of VariableTable.
12 13 14 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 12 def initialize(hook_receiver = nil) @hook_receiver = hook_receiver end |
Instance Method Details
#accessible_variables ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
113 114 115 116 117 118 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 113 def accessible_variables scope_stack.reverse_each.with_object([]) do |scope, variables| variables.concat(scope.variables.values) break variables unless scope.node.block_type? || scope.node.numblock_type? end end |
#assign_to_variable(name, node) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 56 def assign_to_variable(name, node) variable = find_variable(name) unless variable raise "Assigning to undeclared local variable \"#{name}\" " \ "at #{node.source_range}, #{node.inspect}" end mark_variable_as_captured_by_block_if_so(variable) variable.assign(node) end |
#current_scope ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
40 41 42 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 40 def current_scope scope_stack.last end |
#current_scope_level ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
44 45 46 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 44 def current_scope_level scope_stack.count end |
#declare_variable(name, node) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
48 49 50 51 52 53 54 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 48 def declare_variable(name, node) variable = Variable.new(name, node, current_scope) invoke_hook(:before_declaring_variable, variable) current_scope.variables[variable.name] = variable invoke_hook(:after_declaring_variable, variable) variable end |
#find_variable(name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 94 def find_variable(name) name = name.to_sym scope_stack.reverse_each do |scope| variable = scope.variables[name] return variable if variable # Only block scope allows referencing outer scope variables. node = scope.node return nil unless node.block_type? || node.numblock_type? end nil end |
#invoke_hook(hook_name, *args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 16 def invoke_hook(hook_name, *args) @hook_receiver&.send(hook_name, *args) end |
#pop_scope ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
32 33 34 35 36 37 38 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 32 def pop_scope scope = current_scope invoke_hook(:before_leaving_scope, scope) scope_stack.pop invoke_hook(:after_leaving_scope, scope) scope end |
#push_scope(scope_node) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
24 25 26 27 28 29 30 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 24 def push_scope(scope_node) scope = Scope.new(scope_node) invoke_hook(:before_entering_scope, scope) scope_stack.push(scope) invoke_hook(:after_entering_scope, scope) scope end |
#reference_variable(name, node) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 68 def reference_variable(name, node) variable = find_variable(name) # In this code: # # foo = 1 unless foo # # (if # (lvar :foo) nil # (lvasgn :foo # (int 1))) # # Parser knows whether the foo is a variable or method invocation. # This means that if a :lvar node is shown in AST, the variable is # assumed to be already declared, even if we haven't seen any :lvasgn # or :arg node before the :lvar node. # # We don't invoke #declare_variable here otherwise # Variable#declaration_node will be :lvar node, that is actually not. # So just skip. return unless variable mark_variable_as_captured_by_block_if_so(variable) variable.reference!(node) end |
#scope_stack ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
20 21 22 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 20 def scope_stack @scope_stack ||= [] end |
#variable_exist?(name) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
109 110 111 |
# File 'lib/rubocop/cop/variable_force/variable_table.rb', line 109 def variable_exist?(name) find_variable(name) end |