module RuboCop::Cop::VariableForce::Locatable

def ancestor_nodes_in_scope

def ancestor_nodes_in_scope
  node.each_ancestor.take_while do |ancestor_node|
    !ancestor_node.equal?(scope.node)
  end
end

def body_index

def body_index
  branch_point_node.children.index(branch_body_node)
end

def branch?(parent_node, child_node)

def branch?(parent_node, child_node)
  child_index = parent_node.children.index(child_node)
  case parent_node.type
  when *BRANCH_TYPES
    child_index != CONDITION_INDEX_OF_BRANCH_NODE
  when *LOGICAL_OPERATOR_TYPES
    child_index != LEFT_SIDE_INDEX_OF_LOGICAL_OPERATOR_NODE
  when RESCUE_TYPE
    true
  when ENSURE_TYPE
    child_index != ENSURE_INDEX_OF_ENSURE_NODE
  else
    false
  end
end

def branch_body_name

def branch_body_name
  case branch_point_node.type
  when :if                     then if_body_name
  when :case                   then case_body_name
  when *LOGICAL_OPERATOR_TYPES then logical_operator_body_name
  when RESCUE_TYPE             then rescue_body_name
  when ENSURE_TYPE             then ensure_body_name
  else fail InvalidBranchBodyError
  end
rescue InvalidBranchBodyError
  raise InvalidBranchBodyError,
        "Invalid body index #{body_index} of #{branch_point_node.type}"
end

def branch_body_node

A child node of #branch_point_node this assignment belongs.
def branch_body_node
  if instance_variable_defined?(:@branch_body_node)
    return @branch_body_node
  end
  set_branch_point_and_body_nodes!
  @branch_body_node
end

def branch_id

def branch_id
  return nil unless inside_of_branch?
  @branch_id ||= [branch_point_node.object_id, branch_type].join('_')
end

def branch_point_node

Inner if, case, rescue, or ensure node.
def branch_point_node
  if instance_variable_defined?(:@branch_point_node)
    return @branch_point_node
  end
  set_branch_point_and_body_nodes!
  @branch_point_node
end

def branch_type

def branch_type
  return nil unless inside_of_branch?
  @branch_type ||= [branch_point_node.type, branch_body_name].join('_')
end

def case_body_name

def case_body_name
  if branch_body_node.type == :when
    "when#{body_index - 1}"
  else
    'else'
  end
end

def ensure_body_name

def ensure_body_name
  case body_index
  when 0 then 'main'
  else fail InvalidBranchBodyError
  end
end

def if_body_name

def if_body_name
  case body_index
  when 1 then 'true'
  when 2 then 'false'
  else fail InvalidBranchBodyError
  end
end

def inside_of_branch?

def inside_of_branch?
  branch_point_node
end

def logical_operator_body_name

def logical_operator_body_name
  case body_index
  when 1 then 'right'
  else fail InvalidBranchBodyError
  end
end

def node

def node
  fail '#node must be declared!'
end

def rescue_body_name

def rescue_body_name
  if body_index == 0
    'main'
  elsif branch_body_node.type == :resbody
    "rescue#{body_index - 1}"
  else
    'else'
  end
end

def run_exclusively_with?(other)

def run_exclusively_with?(other)
  return false unless branch_point_node.equal?(other.branch_point_node)
  return false if branch_body_node.equal?(other.branch_body_node)
  # Main body of rescue is always run:
  #
  #   begin
  #     # main
  #   rescue
  #     # resbody
  #   end
  if branch_point_node.type == :rescue &&
     (branch_body_name == 'main' || other.branch_body_name == 'main')
    return false
  end
  true
end

def scope

def scope
  fail '#scope must be declared!'
end

def set_branch_point_and_body_nodes!

def set_branch_point_and_body_nodes!
  self_and_ancestor_nodes = [node] + ancestor_nodes_in_scope
  self_and_ancestor_nodes.each_cons(2) do |child, parent|
    next unless branch?(parent, child)
    @branch_point_node = parent
    @branch_body_node = child
    break
  end
end