Class: RuboCop::Cop::VariableForce::Variable

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/cop/variable_force/variable.rb

Overview

A Variable represents existence of a local variable. This holds a variable declaration node, and some states of the variable.

Constant Summary collapse

VARIABLE_DECLARATION_TYPES =
(VARIABLE_ASSIGNMENT_TYPES + ARGUMENT_DECLARATION_TYPES).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, declaration_node, scope) ⇒ Variable



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rubocop/cop/variable_force/variable.rb', line 18

def initialize(name, declaration_node, scope)
  unless VARIABLE_DECLARATION_TYPES.include?(declaration_node.type)
    raise ArgumentError,
          "Node type must be any of #{VARIABLE_DECLARATION_TYPES}, " \
          "passed #{declaration_node.type}"
  end

  @name = name.to_sym
  @declaration_node = declaration_node
  @scope = scope

  @assignments = []
  @references = []
  @captured_by_block = false
end

Instance Attribute Details

#assignmentsObject (readonly)

Returns the value of attribute assignments.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def assignments
  @assignments
end

#captured_by_blockObject (readonly) Also known as: captured_by_block?

Returns the value of attribute captured_by_block.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def captured_by_block
  @captured_by_block
end

#declaration_nodeObject (readonly)

Returns the value of attribute declaration_node.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def declaration_node
  @declaration_node
end

#nameObject (readonly)

Returns the value of attribute name.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def name
  @name
end

#referencesObject (readonly)

Returns the value of attribute references.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def references
  @references
end

#scopeObject (readonly)

Returns the value of attribute scope.



14
15
16
# File 'lib/rubocop/cop/variable_force/variable.rb', line 14

def scope
  @scope
end

Instance Method Details

#argument?Boolean



81
82
83
# File 'lib/rubocop/cop/variable_force/variable.rb', line 81

def argument?
  ARGUMENT_DECLARATION_TYPES.include?(@declaration_node.type)
end

#assign(node) ⇒ Object



34
35
36
# File 'lib/rubocop/cop/variable_force/variable.rb', line 34

def assign(node)
  @assignments << Assignment.new(node, self)
end

#block_argument?Boolean



89
90
91
# File 'lib/rubocop/cop/variable_force/variable.rb', line 89

def block_argument?
  argument? && @scope.node.type == :block
end

#capture_with_block!Object



61
62
63
# File 'lib/rubocop/cop/variable_force/variable.rb', line 61

def capture_with_block!
  @captured_by_block = true
end

#explicit_block_local_variable?Boolean



97
98
99
# File 'lib/rubocop/cop/variable_force/variable.rb', line 97

def explicit_block_local_variable?
  @declaration_node.type == :shadowarg
end

#keyword_argument?Boolean



93
94
95
# File 'lib/rubocop/cop/variable_force/variable.rb', line 93

def keyword_argument?
  [:kwarg, :kwoptarg].include?(@declaration_node.type)
end

#method_argument?Boolean



85
86
87
# File 'lib/rubocop/cop/variable_force/variable.rb', line 85

def method_argument?
  argument? && [:def, :defs].include?(@scope.node.type)
end

#reference!(node) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rubocop/cop/variable_force/variable.rb', line 42

def reference!(node)
  reference = Reference.new(node, @scope)
  @references << reference
  consumed_branch_ids = Set.new

  @assignments.reverse_each do |assignment|
    next if consumed_branch_ids.include?(assignment.branch_id)

    unless assignment.run_exclusively_with?(reference)
      assignment.reference!
    end

    break unless assignment.inside_of_branch?
    break if assignment.branch_id == reference.branch_id
    next if assignment.reference_penetrable?
    consumed_branch_ids << assignment.branch_id
  end
end

#referenced?Boolean



38
39
40
# File 'lib/rubocop/cop/variable_force/variable.rb', line 38

def referenced?
  !@references.empty?
end

#should_be_unused?Boolean



77
78
79
# File 'lib/rubocop/cop/variable_force/variable.rb', line 77

def should_be_unused?
  name.to_s.start_with?('_')
end

#used?Boolean

This is a convenient way to check whether the variable is used in its entire variable lifetime. For more precise usage check, refer Assignment#used?.

Once the variable is captured by a block, we have no idea when, where and how many times the block would be invoked and it means we cannot track the usage of the variable. So we consider it’s used to suppress false positive offenses.



73
74
75
# File 'lib/rubocop/cop/variable_force/variable.rb', line 73

def used?
  @captured_by_block || referenced?
end