class RuboCop::Cop::Lint::SelfAssignment
= hash[foo]
# good (method calls possibly can return different results)
obj.attr = obj.attr2<br>hash = hash[‘bar’]
Foo = Bar
foo, bar = bar, foo
foo = bar
# good
obj.attr = obj.attr<br>hash = hash[‘foo’]
Foo = Foo
foo, bar = foo, bar
foo = foo
# bad
@example
Checks for self-assignments.
def handle_attribute_assignment(node)
def handle_attribute_assignment(node) first_argument = node.first_argument return unless first_argument.respond_to?(:arguments) && first_argument.arguments.empty? if first_argument.call_type? && node.receiver == first_argument.receiver && first_argument.method_name.to_s == node.method_name.to_s.delete_suffix('=') add_offense(node) end end
def handle_key_assignment(node)
def handle_key_assignment(node) value_node = node.arguments[1] if value_node.send_type? && value_node.method?(:[]) && node.receiver == value_node.receiver && !node.first_argument.call_type? && node.first_argument == value_node.first_argument add_offense(node) end end
def multiple_self_assignment?(node)
def multiple_self_assignment?(node) lhs = node.lhs rhs = node.rhs return false unless rhs.array_type? return false unless lhs.children.size == rhs.children.size lhs.children.zip(rhs.children).all? do |lhs_item, rhs_item| rhs_matches_lhs?(rhs_item, lhs_item) end end
def on_casgn(node)
def on_casgn(node) return unless node.rhs&.const_type? add_offense(node) if node.namespace == node.rhs.namespace && node.short_name == node.rhs.short_name end
def on_lvasgn(node)
def on_lvasgn(node) return unless node.rhs rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type] add_offense(node) if node.rhs.type == rhs_type && node.rhs.source == node.lhs.to_s end
def on_masgn(node)
def on_masgn(node) add_offense(node) if multiple_self_assignment?(node) end
def on_or_asgn(node)
def on_or_asgn(node) add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs) end
def on_send(node)
def on_send(node) if node.method?(:[]=) handle_key_assignment(node) if node.arguments.size == 2 elsif node.assignment_method? handle_attribute_assignment(node) if node.arguments.size == 1 end end
def rhs_matches_lhs?(rhs, lhs)
def rhs_matches_lhs?(rhs, lhs) rhs.type == ASSIGNMENT_TYPE_TO_RHS_TYPE[lhs.type] && rhs.children.first == lhs.children.first end