/
redundant_self_assignment_branch.rb
88 lines (74 loc) · 2.6 KB
/
redundant_self_assignment_branch.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# This cop checks for places where conditional branch makes redundant self-assignment.
#
# @example
#
# # bad
# foo = condition ? bar : foo
#
# # good
# foo = bar if condition
#
# # bad
# foo = condition ? foo : bar
#
# # good
# foo = bar unless condition
#
class RedundantSelfAssignmentBranch < Base
include RangeHelp
extend AutoCorrector
MSG = 'Remove the self-assignment branch.'
# @!method bad_method?(node)
def_node_matcher :bad_method?, <<~PATTERN
(send nil? :bad_method ...)
PATTERN
def on_lvasgn(node)
variable, expression = *node
return unless expression&.if_type?
return unless expression.ternary? || expression.else?
if_branch = expression.if_branch
else_branch = expression.else_branch
if self_assign?(variable, if_branch)
register_offense(expression, if_branch, else_branch, 'unless')
elsif self_assign?(variable, else_branch)
register_offense(expression, else_branch, if_branch, 'if')
end
end
alias on_ivasgn on_lvasgn
alias on_cvasgn on_lvasgn
alias on_gvasgn on_lvasgn
private
def self_assign?(variable, branch)
variable.to_s == branch&.source
end
def register_offense(if_node, offense_branch, opposite_branch, keyword)
add_offense(offense_branch) do |corrector|
if if_node.ternary?
replacement = "#{opposite_branch.source} #{keyword} #{if_node.condition.source}"
corrector.replace(if_node, replacement)
else
if_node_loc = if_node.loc
range = range_by_whole_lines(offense_branch.source_range, include_final_newline: true)
corrector.remove(range)
range = range_by_whole_lines(if_node_loc.else, include_final_newline: true)
corrector.remove(range)
autocorrect_if_condition(corrector, if_node, if_node_loc, keyword)
end
end
end
def autocorrect_if_condition(corrector, if_node, if_node_loc, keyword)
else_branch = if_node.else_branch
if else_branch.respond_to?(:elsif?) && else_branch.elsif?
corrector.replace(if_node.condition, else_branch.condition.source)
else
corrector.replace(if_node_loc.keyword, keyword)
end
end
end
end
end
end