class RuboCop::Cop::Style::ClassAndModuleChildren

The compact style is only forced for classes/modules with one child.
end
class Foo::Bar
# combine definitions as much as possible
# good
@example EnforcedStyle: compact
end
end
class Bar
class Foo
# have each child on its own line
# good
@example EnforcedStyle: nested (default)
modules. Basically there are two different styles:
This cop checks the style of children definitions at classes and

def add_trailing_end(corrector, node, padding)

def add_trailing_end(corrector, node, padding)
  replacement = "#{padding}end\n#{leading_spaces(node)}end".freeze
  corrector.replace(node.loc.end, replacement)
end

def autocorrect(node)

def autocorrect(node)
  lambda do |corrector|
    return if node.class_type? && node.parent_class && style != :nested
    nest_or_compact(corrector, node)
  end
end

def check_compact_style(node, body)

def check_compact_style(node, body)
  return unless one_child?(body) && !compact_node_name?(node)
  add_offense(node, location: :name, message: COMPACT_MSG)
end

def check_nested_style(node)

def check_nested_style(node)
  return unless compact_node_name?(node)
  add_offense(node, location: :name, message: NESTED_MSG)
end

def check_style(node, body)

def check_style(node, body)
  if style == :nested
    check_nested_style(node)
  else
    check_compact_style(node, body)
  end
end

def compact_definition(corrector, node)

def compact_definition(corrector, node)
  compact_node(corrector, node)
  remove_end(corrector, node.body)
end

def compact_identifier_name(node)

def compact_identifier_name(node)
  "#{node.identifier.const_name}::" \
    "#{node.body.children.first.const_name}"
end

def compact_node(corrector, node)

def compact_node(corrector, node)
  replacement = "#{node.body.type} #{compact_identifier_name(node)}"
  range = range_between(node.loc.keyword.begin_pos,
                        node.body.loc.name.end_pos)
  corrector.replace(range, replacement)
end

def compact_node_name?(node)

def compact_node_name?(node)
  node.loc.name.source =~ /::/
end

def indent_width

def indent_width
  @config.for_cop('IndentationWidth')['Width'] || 2
end

def leading_spaces(node)

def leading_spaces(node)
  node.source_range.source_line[/\A\s*/]
end

def nest_definition(corrector, node)

def nest_definition(corrector, node)
  padding = ((' ' * indent_width) + leading_spaces(node)).to_s
  padding_for_trailing_end = padding.sub(' ' * node.loc.end.column, '')
  replace_keyword_with_module(corrector, node)
  split_on_double_colon(corrector, node, padding)
  add_trailing_end(corrector, node, padding_for_trailing_end)
end

def nest_or_compact(corrector, node)

def nest_or_compact(corrector, node)
  if style == :nested
    nest_definition(corrector, node)
  else
    compact_definition(corrector, node)
  end
end

def on_class(node)

def on_class(node)
  return if node.parent_class && style != :nested
  check_style(node, node.body)
end

def on_module(node)

def on_module(node)
  check_style(node, node.body)
end

def one_child?(body)

def one_child?(body)
  body && %i[module class].include?(body.type)
end

def remove_end(corrector, body)

def remove_end(corrector, body)
  range = range_between(
    body.loc.end.begin_pos - leading_spaces(body).size,
    body.loc.end.end_pos + 1
  )
  corrector.remove(range)
end

def replace_keyword_with_module(corrector, node)

def replace_keyword_with_module(corrector, node)
  corrector.replace(node.loc.keyword, 'module'.freeze)
end

def split_on_double_colon(corrector, node, padding)

def split_on_double_colon(corrector, node, padding)
  children_definition = node.children.first
  range = range_between(children_definition.loc.double_colon.begin_pos,
                        children_definition.loc.double_colon.end_pos)
  replacement = "\n#{padding}#{node.loc.keyword.source} ".freeze
  corrector.replace(range, replacement)
end