class RuboCop::Cop::Style::ConditionalAssignment

end
bar = 2
some_other_method
else
bar = 1
some_method
if foo
end
bar += 2
else
bar += 1
when ‘a’
case foo
end
bar = 2
else
bar = 1
if foo
# good
end
2
some_other_method
else
1
some_method
bar << if foo
end
2
else
1
when ‘a’
bar += case foo
end
2
else
1
bar = if foo
# bad
@example EnforcedStyle: assign_inside_condition
end
2
some_other_method
else
1
some_method
bar << if foo
end
2
else
1
when ‘a’
bar += case foo
end
2
else
1
bar = if foo
# good
end
bar = 2
some_other_method
else
bar = 1
some_method
if foo
end
bar += 2
else
bar += 1
when ‘a’
case foo
end
bar = 2
else
bar = 1
if foo
# bad
@example EnforcedStyle: assign_to_condition (default)
condition can be used instead.
assignment to the same variable when using the return of the
Check for ‘if` and `case` statements where each branch is used for

def allowed_single_line?(branches)

def allowed_single_line?(branches)
  single_line_conditions_only? && branches.any?(&:begin_type?)
end

def allowed_statements?(branches)

def allowed_statements?(branches)
  return false unless branches.all?
  statements = branches.map { |branch| tail(branch) }.compact
  lhs_all_match?(statements) && statements.none?(&:masgn_type?) &&
    assignment_types_match?(*statements)
end

def allowed_ternary?(assignment)

def allowed_ternary?(assignment)
  assignment.if_type? && assignment.ternary? && !include_ternary?
end

def assignment_node(node)

def assignment_node(node)
  *_variable, assignment = *node
  # ignore pseudo-assignments without rhs in for nodes
  return if node.parent&.for_type?
  if assignment.begin_type? && assignment.children.one?
    assignment, = *assignment
  end
  assignment
end

def assignment_types_match?(*nodes)

def assignment_types_match?(*nodes)
  return unless assignment_type?(nodes.first)
  nodes.map(&:type).uniq.one?
end

def autocorrect(node)

def autocorrect(node)
  if assignment_type?(node)
    move_assignment_inside_condition(node)
  else
    move_assignment_outside_condition(node)
  end
end

def candidate_node?(node)

def candidate_node?(node)
  style == :assign_inside_condition && assignment_rhs_exist?(node)
end

def check_assignment_to_condition(node)

def check_assignment_to_condition(node)
  return unless candidate_node?(node)
  ignore_node(node)
  assignment = assignment_node(node)
  return unless candidate_condition?(assignment)
  _condition, *branches, else_branch = *assignment
  return unless else_branch
  return if allowed_single_line?([*branches, else_branch])
  add_offense(node, message: ASSIGN_TO_CONDITION_MSG)
end

def check_node(node, branches)

def check_node(node, branches)
  return if allowed_ternary?(node)
  return unless allowed_statements?(branches)
  return if allowed_single_line?(branches)
  return if correction_exceeds_line_limit?(node, branches)
  add_offense(node)
end

def correction_exceeds_line_limit?(node, branches)

greater than the max configured line length
of the longest line + the length of the corrected assignment is
correcting, this will not be on the line anymore. Check if the length
from lines that contain the offending assignment because after
length. Find the longest line of condition. Remove the assignment
offense by auto-correcting this cop. Find the max configured line
If `Metrics/LineLength` is enabled, we do not want to introduce an
def correction_exceeds_line_limit?(node, branches)
  return false unless line_length_cop_enabled?
  assignment = lhs(tail(branches[0]))
  longest_line_exceeds_line_limit?(node, assignment)
end

def include_ternary?

def include_ternary?
  cop_config['IncludeTernaryExpressions']
end

def indentation_width

def indentation_width
  config.for_cop(INDENTATION_WIDTH)[WIDTH] || 2
end

def lhs_all_match?(branches)

def lhs_all_match?(branches)
  return true if branches.empty?
  first_lhs = lhs(branches.first)
  branches.all? { |branch| lhs(branch) == first_lhs }
end

def line_length_cop_enabled?

def line_length_cop_enabled?
  config.for_cop(LINE_LENGTH)[ENABLED]
end

def longest_line(node, assignment)

def longest_line(node, assignment)
  assignment_regex = /\s*#{Regexp.escape(assignment).gsub('\ ', '\s*')}/
  lines = node.source.lines.map do |line|
    line.chomp.sub(assignment_regex, '')
  end
  longest_line = lines.max_by(&:length)
  assignment + longest_line
end

def longest_line_exceeds_line_limit?(node, assignment)

def longest_line_exceeds_line_limit?(node, assignment)
  longest_line(node, assignment).length > max_line_length
end

def max_line_length

def max_line_length
  config.for_cop(LINE_LENGTH)[MAX]
end

def move_assignment_inside_condition(node)

def move_assignment_inside_condition(node)
  *_assignment, condition = *node
  if ternary_condition?(condition)
    TernaryCorrector.move_assignment_inside_condition(node)
  elsif condition.case_type?
    CaseCorrector.move_assignment_inside_condition(node)
  elsif condition.if_type?
    IfCorrector.move_assignment_inside_condition(node)
  end
end

def move_assignment_outside_condition(node)

def move_assignment_outside_condition(node)
  if node.case_type?
    CaseCorrector.correct(self, node)
  elsif node.ternary?
    TernaryCorrector.correct(node)
  elsif node.if? || node.unless?
    IfCorrector.correct(self, node)
  end
end

def on_case(node)

def on_case(node)
  return unless style == :assign_to_condition
  return unless node.else_branch
  when_branches = expand_when_branches(node.when_branches)
  branches = [*when_branches, node.else_branch]
  check_node(node, branches)
end

def on_if(node)

def on_if(node)
  return unless style == :assign_to_condition
  return if node.elsif?
  else_branch = node.else_branch
  elsif_branches, else_branch = expand_elses(else_branch)
  return unless else_branch
  branches = [node.if_branch, *elsif_branches, else_branch]
  check_node(node, branches)
end

def on_send(node)

def on_send(node)
  return unless assignment_type?(node)
  check_assignment_to_condition(node)
end

def single_line_conditions_only?

def single_line_conditions_only?
  cop_config[SINGLE_LINE_CONDITIONS_ONLY]
end

def ternary_condition?(node)

def ternary_condition?(node)
  [node, node.children.first].any? { |n| n.if_type? && n.ternary? }
end