Class: RuboCop::Cop::Lint::UselessSetterCall::MethodVariableTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/cop/lint/useless_setter_call.rb

Overview

This class tracks variable assignments in a method body and if a variable contains object passed as argument at the end of the method.

Instance Method Summary collapse

Constructor Details

#initialize(body_node) ⇒ MethodVariableTracker

Returns a new instance of MethodVariableTracker.



64
65
66
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 64

def initialize(body_node)
  @body_node = body_node
end

Instance Method Details

#constructor?(node) ⇒ Boolean

Returns:

  • (Boolean)


148
149
150
151
152
153
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 148

def constructor?(node)
  return true if LITERAL_TYPES.include?(node.type)
  return false unless node.type == :send
  _receiver, method = *node
  method == :new
end

#contain_local_object?(variable_name) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 68

def contain_local_object?(variable_name)
  return @local[variable_name] if @local

  @local = {}

  scan(@body_node) do |node|
    case node.type
    when :masgn
      process_multiple_assignment(node)
    when :or_asgn, :and_asgn
      process_logical_operator_assignment(node)
    when :op_asgn
      process_binary_operator_assignment(node)
    when *ASSIGNMENT_TYPES
      _, rhs_node = *node
      process_assignment(node, rhs_node)
    end
  end

  @local[variable_name]
end

#process_assignment(asgn_node, rhs_node) ⇒ Object



137
138
139
140
141
142
143
144
145
146
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 137

def process_assignment(asgn_node, rhs_node)
  lhs_variable_name, = *asgn_node

  if [:lvar, :ivar, :cvar, :gvar].include?(rhs_node.type)
    rhs_variable_name, = *rhs_node
    @local[lhs_variable_name] = @local[rhs_variable_name]
  else
    @local[lhs_variable_name] = constructor?(rhs_node)
  end
end

#process_binary_operator_assignment(op_asgn_node) ⇒ Object



128
129
130
131
132
133
134
135
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 128

def process_binary_operator_assignment(op_asgn_node)
  lhs_node, = *op_asgn_node
  return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
  lhs_variable_name, = *lhs_node
  @local[lhs_variable_name] = true

  throw :skip_children
end

#process_logical_operator_assignment(asgn_node) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 120

def process_logical_operator_assignment(asgn_node)
  lhs_node, rhs_node = *asgn_node
  return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
  process_assignment(lhs_node, rhs_node)

  throw :skip_children
end

#process_multiple_assignment(masgn_node) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 101

def process_multiple_assignment(masgn_node)
  mlhs_node, mrhs_node = *masgn_node

  mlhs_node.children.each_with_index do |lhs_node, index|
    next unless ASSIGNMENT_TYPES.include?(lhs_node.type)

    lhs_variable_name, = *lhs_node
    rhs_node = mrhs_node.children[index]

    if mrhs_node.type == :array && rhs_node
      process_assignment(lhs_variable_name, rhs_node)
    else
      @local[lhs_variable_name] = true
    end
  end

  throw :skip_children
end

#scan(node, &block) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/rubocop/cop/lint/useless_setter_call.rb', line 90

def scan(node, &block)
  catch(:skip_children) do
    yield node

    node.children.each do |child|
      next unless child.is_a?(Parser::AST::Node)
      scan(child, &block)
    end
  end
end