class RuboCop::Cop::Lint::NestedMethodDefinition


end
end
end
def bar
obj.do_baz do
def foo(obj)
# good
@example AllowedPatterns: [‘baz’]
end
end
end
def bar
obj.do_baz do
def foo(obj)
# bad
@example AllowedPatterns: [] (default)
end
end
end
def find_or_create_by_name(name)
has_many :articles do
def do_something
# bad
@example AllowedMethods: [‘has_many’]
end
end
end
def find_or_create_by_name(name)
has_many :articles do
def do_something
# bad
@example AllowedMethods: [] (default)
end
end
end
def bar
class << self
def foo
# good
end
end
end
def bar
self.class.module_exec do
def foo
end
end
end
def bar
self.class.class_eval do
def foo
# ‘module_exec` blocks are allowed by default.
# `class_eval`, `instance_eval`, `module_eval`, `class_exec`, `instance_exec`, and
# good
end
bar.call
bar = -> { puts ’hello’ }
def foo
# good
end
end
def bar
def foo
# will be redefined every time ‘foo` is invoked.
# as the outer `foo` method. Furthermore, the `bar` method
# `bar` definition actually produces methods in the same scope
# bad
@example
Checks for nested method definitions.

def allowed_method_name?(node)

def allowed_method_name?(node)
  name = node.method_name
  allowed_method?(name) || matches_allowed_pattern?(name)
end

def allowed_subject_type?(subject)

def allowed_subject_type?(subject)
  subject.variable? || subject.const_type? || subject.call_type?
end

def on_def(node)

def on_def(node)
  subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
  return if node.defs_type? && allowed_subject_type?(subject)
  def_ancestor = node.each_ancestor(:any_def).first
  return unless def_ancestor
  within_scoping_def =
    node.each_ancestor(:any_block, :sclass).any? do |ancestor|
      scoping_method_call?(ancestor)
    end
  add_offense(node) if def_ancestor && !within_scoping_def
end

def scoping_method_call?(child)

def scoping_method_call?(child)
  child.sclass_type? || eval_call?(child) || exec_call?(child) ||
    child.class_constructor? || allowed_method_name?(child)
end