class RuboCop::Cop::Style::RedundantSelf

end
end
self.bar == bar # Resolves name clash with argument of the block.
%w[x y z].select do |bar|
def foo
end
self.bar # Resolves name clash with the local variable.
bar = 1
def foo
end
self.bar # Resolves name clash with the argument.
def foo(bar)
# good
end
self.baz
def foo(bar)
# bad
@example
otherwise.
Note we allow uses of ‘self` with operators because it would be awkward
protected scope, you cannot send private messages this way.
Note, with using explicit self you can only send messages with public or
* Calling an attribute writer to prevent a local variable assignment.
variable.
presence of a method name clash with an argument or a local
* Sending a message to same object with zero arguments in
The usage of `self` is only needed when:
Checks for redundant uses of `self`.

def self.autocorrect_incompatible_with

def self.autocorrect_incompatible_with
  [ColonMethodCall, Layout::DotPosition]
end

def add_lhs_to_local_variables_scopes(rhs, lhs)

def add_lhs_to_local_variables_scopes(rhs, lhs)
  if rhs&.send_type? && !rhs.arguments.empty?
    rhs.arguments.each { |argument| @local_variables_scopes[argument] << lhs }
  else
    @local_variables_scopes[rhs] << lhs
  end
end

def add_masgn_lhs_variables(rhs, lhs)

def add_masgn_lhs_variables(rhs, lhs)
  lhs.children.each do |child|
    add_lhs_to_local_variables_scopes(rhs, child.to_a.first)
  end
end

def add_match_var_scopes(in_pattern_node)

def add_match_var_scopes(in_pattern_node)
  in_pattern_node.each_descendant(:match_var) do |match_var_node|
    @local_variables_scopes[in_pattern_node] << match_var_node.children.first
  end
end

def add_scope(node, local_variables = [])

def add_scope(node, local_variables = [])
  node.each_descendant do |child_node|
    @local_variables_scopes[child_node] = local_variables
  end
end

def allow_self(node)

def allow_self(node)
  return unless node.send_type? && node.self_receiver?
  @allowed_send_nodes << node
end

def allowed_send_node?(node)

def allowed_send_node?(node)
  @allowed_send_nodes.include?(node) ||
    @local_variables_scopes[node].include?(node.method_name) ||
    node.each_ancestor.any? do |ancestor|
      @local_variables_scopes[ancestor].include?(node.method_name)
    end ||
    KERNEL_METHODS.include?(node.method_name)
end

def initialize(config = nil, options = nil)

def initialize(config = nil, options = nil)
  super
  @allowed_send_nodes = []
  @local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }.compare_by_identity
end

def on_args(node)

def on_args(node)
  node.children.each { |arg| on_argument(arg) }
end

def on_argument(node)

def on_argument(node)
  if node.mlhs_type?
    on_args(node)
  else
    name, = *node
    @local_variables_scopes[node] << name
  end
end

def on_block(node)

def on_block(node)
  add_scope(node, @local_variables_scopes[node])
end

def on_blockarg(node)

def on_blockarg(node)
  on_argument(node)
end

def on_def(node)

def on_def(node)
  add_scope(node)
end

def on_if(node)

def on_if(node)
  # Allow conditional nodes to use `self` in the condition if that variable
  # name is used in an `lvasgn` or `masgn` within the `if`.
  node.child_nodes.each do |child_node|
    lhs, _rhs = *child_node
    if child_node.lvasgn_type?
      add_lhs_to_local_variables_scopes(node.condition, lhs)
    elsif child_node.masgn_type?
      add_masgn_lhs_variables(node.condition, lhs)
    end
  end
end

def on_in_pattern(node)

def on_in_pattern(node)
  add_match_var_scopes(node)
end

def on_lvasgn(node)

def on_lvasgn(node)
  lhs, rhs = *node
  add_lhs_to_local_variables_scopes(rhs, lhs)
end

def on_masgn(node)

def on_masgn(node)
  lhs, rhs = *node
  add_masgn_lhs_variables(rhs, lhs)
end

def on_op_asgn(node)

def on_op_asgn(node)
  lhs, _op, _rhs = *node
  allow_self(lhs)
end

def on_or_asgn(node)

def on_or_asgn(node)
  lhs, _rhs = *node
  allow_self(lhs)
end

def on_send(node)

def on_send(node)
  return unless node.self_receiver? && regular_method_call?(node)
  return if node.parent&.mlhs_type?
  return if allowed_send_node?(node)
  add_offense(node.receiver) do |corrector|
    corrector.remove(node.receiver)
    corrector.remove(node.loc.dot)
  end
end

def regular_method_call?(node)

def regular_method_call?(node)
  !(node.operator_method? ||
    KEYWORDS.include?(node.method_name) ||
    node.camel_case_method? ||
    node.setter_method? ||
    node.implicit_call?)
end