class RuboCop::Cop::Style::MethodCallWithoutArgsParentheses


object.foo()
# good
@example AllowedMethods: [foo]
object.foo()
# bad
@example AllowedMethods: [] (default)
object.some_method
# good
object.some_method()
# bad
@example
as in ‘0.times { it() }`, following `Lint/ItWithoutArgumentsInBlock` cop.
NOTE: This cop allows the use of `it()` without arguments in blocks,
By default, there are no allowed methods.
This cop’s allowed methods can be customized with ‘AllowedMethods`.
Checks for unwanted parentheses in parameterless method calls.

def allowed_method_name?(name)

def allowed_method_name?(name)
  allowed_method?(name) || matches_allowed_pattern?(name)
end

def any_assignment?(node)

def any_assignment?(node)
  node.each_ancestor(*AST::Node::ASSIGNMENTS).any? do |asgn_node|
    # `obj.method = value` parses as (send ... :method= ...), and will
    # not be returned as an `asgn_node` here, however,
    # `obj.method ||= value` parses as (or-asgn (send ...) ...)
    # which IS an `asgn_node`. Similarly, `obj.method += value` parses
    # as (op-asgn (send ...) ...), which is also an `asgn_node`.
    next if asgn_node.shorthand_asgn? && asgn_node.lhs.call_type?
    yield asgn_node
  end
end

def default_argument?(node)

def default_argument?(node)
  node.parent&.optarg_type?
end

def ineligible_node?(node)

def ineligible_node?(node)
  node.camel_case_method? || node.implicit_call? || node.prefix_not?
end

def offense_range(node)

def offense_range(node)
  node.loc.begin.join(node.loc.end)
end

def on_send(node)

rubocop:disable Metrics/CyclomaticComplexity
def on_send(node)
  return unless !node.arguments? && node.parenthesized?
  return if ineligible_node?(node)
  return if default_argument?(node)
  return if allowed_method_name?(node.method_name)
  return if same_name_assignment?(node)
  return if parenthesized_it_method_in_block?(node)
  register_offense(node)
end

def parenthesized_it_method_in_block?(node)


Ruby 3.4; use it() or self.it
-e:1: warning: `it` calls without arguments will refer to the first block param in
$ ruby -e '0.times { begin; it; end }'

Respects `Lint/ItWithoutArgumentsInBlock` cop and the following Ruby 3.3's warning:
def parenthesized_it_method_in_block?(node)
  return false unless node.method?(:it)
  return false unless (block_node = node.each_ancestor(:block).first)
  return false unless block_node.arguments.empty_and_without_delimiters?
  !node.receiver && node.arguments.empty? && !node.block_literal?
end

def register_offense(node)

def register_offense(node)
  add_offense(offense_range(node)) do |corrector|
    corrector.remove(node.loc.begin)
    corrector.remove(node.loc.end)
  end
end

def same_name_assignment?(node)

def same_name_assignment?(node)
  return false if node.receiver
  any_assignment?(node) do |asgn_node|
    if asgn_node.masgn_type?
      variable_in_mass_assignment?(node.method_name, asgn_node)
    else
      asgn_node.loc.name.source == node.method_name.to_s
    end
  end
end

def variable_in_mass_assignment?(variable_name, node)

def variable_in_mass_assignment?(variable_name, node)
  node.assignments.reject(&:send_type?).any? { |n| n.name == variable_name }
end