class RuboCop::Cop::Lint::UselessAccessModifier

end
delegate :method_a, to: :method_b
private
# this is not redundant because ‘delegate` creates methods
class Foo
require ’active_support/core_ext/module/delegation’
# - delegate
# MethodCreatingMethods:
# Lint/UselessAccessModifier:
@example
end
end
def some_other_private_method
private
# this is not redundant because ‘concerning` created its own context
end
end
def some_private_method
private
end
def some_public_method
concerning :Bar do
class Foo
require ’active_support/concern’
# - concerning
# ContextCreatingMethods:
# Lint/UselessAccessModifier:
@example
end
end
def self.method3
public
# singleton class are not affected by the public modifier)
# The following is redundant (methods defined on the class’
end
end
define_method(“foo#{i}”) do<br>.each do |i|
protected # this is redundant (repeated from previous modifier)
end
define_method(:method2) do
protected # this is not redundant (method is defined)
end
end
def method
if condition?
private
# considered as always defining a method)
# The following is not redundant (conditionally defined methods are
class Foo
@example
end
private # this is redundant (no following methods are defined)
end
def method2
private # this is not redundant (a method is defined)
end
def method
public # this is redundant (default access is public)
class Foo
@example
are not redundant.
always being defined, and thus access modifiers guarding such methods
class or module body. Conditionally-defined methods are considered as
code, those which are repeated, and leading ‘public` modifiers in a
This cop checks for redundant access modifiers, including those with no

def access_modifier?(node)

def access_modifier?(node)
  node.bare_access_modifier? ||
    node.method_name == :private_class_method
end

def any_context_creating_methods?(child)

def any_context_creating_methods?(child)
  cop_config.fetch('ContextCreatingMethods', []).any? do |m|
    matcher_name = "#{m}_block?".to_sym
    unless respond_to?(matcher_name)
      self.class.def_node_matcher matcher_name, <<-PATTERN
        (block (send {nil? const} {:#{m}} ...) ...)
      PATTERN
    end
    send(matcher_name, child)
  end
end

def any_method_definition?(child)

def any_method_definition?(child)
  cop_config.fetch('MethodCreatingMethods', []).any? do |m|
    matcher_name = "#{m}_method?".to_sym
    unless respond_to?(matcher_name)
      self.class.def_node_matcher matcher_name, <<-PATTERN
        {def (send nil? :#{m} ...)}
      PATTERN
    end
    send(matcher_name, child)
  end
end

def check_child_nodes(node, unused, cur_vis)

def check_child_nodes(node, unused, cur_vis)
  node.child_nodes.each do |child|
    if child.send_type? && access_modifier?(child)
      cur_vis, unused = check_send_node(child, cur_vis, unused)
    elsif method_definition?(child)
      unused = nil
    elsif start_of_new_scope?(child)
      check_scope(child)
    elsif !child.defs_type?
      cur_vis, unused = check_child_nodes(child, unused, cur_vis)
    end
  end
  [cur_vis, unused]
end

def check_new_visibility(node, unused, new_vis, cur_vis)

def check_new_visibility(node, unused, new_vis, cur_vis)
  # does this modifier just repeat the existing visibility?
  if new_vis == cur_vis
    add_offense(node, message: format(MSG, current: cur_vis))
  else
    # was the previous modifier never applied to any defs?
    if unused
      add_offense(unused, message: format(MSG, current: cur_vis))
    end
    # once we have already warned about a certain modifier, don't
    # warn again even if it is never applied to any method defs
    unused = node
  end
  [new_vis, unused]
end

def check_node(node)

def check_node(node)
  return if node.nil?
  if node.begin_type?
    check_scope(node)
  elsif node.send_type? && node.bare_access_modifier?
    add_offense(node, message: format(MSG, current: node.method_name))
  end
end

def check_scope(node)

def check_scope(node)
  cur_vis, unused = check_child_nodes(node, nil, :public)
  add_offense(unused, message: format(MSG, current: cur_vis)) if unused
end

def check_send_node(node, cur_vis, unused)

def check_send_node(node, cur_vis, unused)
  if node.bare_access_modifier?
    check_new_visibility(node, unused, node.method_name, cur_vis)
  elsif node.method_name == :private_class_method && !node.arguments?
    add_offense(node, message: format(MSG, current: node.method_name))
    [cur_vis, unused]
  end
end

def eval_call?(child)

def eval_call?(child)
  class_or_instance_eval?(child) ||
    class_or_module_or_struct_new_call?(child) ||
    any_context_creating_methods?(child)
end

def method_definition?(child)

def method_definition?(child)
  static_method_definition?(child) ||
    dynamic_method_definition?(child) ||
    any_method_definition?(child)
end

def on_block(node)

def on_block(node)
  return unless eval_call?(node)
  check_node(node.body)
end

def on_class(node)

def on_class(node)
  check_node(node.children[2]) # class body
end

def on_module(node)

def on_module(node)
  check_node(node.children[1]) # module body
end

def on_sclass(node)

def on_sclass(node)
  check_node(node.children[1]) # singleton class body
end

def start_of_new_scope?(child)

def start_of_new_scope?(child)
  child.module_type? || child.class_type? ||
    child.sclass_type? || eval_call?(child)
end