lib/rubocop/cop/layout/access_modifier_indentation.rb
# frozen_string_literal: true
module RuboCop
module Cop
module Layout
# Bare access modifiers (those not applying to specific methods) should be
# indented as deep as method definitions, or as deep as the class/module
# keyword, depending on configuration.
#
# @example EnforcedStyle: indent (default)
# # bad
# class Plumbus
# private
# def smooth; end
# end
#
# # good
# class Plumbus
# private
# def smooth; end
# end
#
# @example EnforcedStyle: outdent
# # bad
# class Plumbus
# private
# def smooth; end
# end
#
# # good
# class Plumbus
# private
# def smooth; end
# end
class AccessModifierIndentation < Base
include Alignment
include ConfigurableEnforcedStyle
include RangeHelp
extend AutoCorrector
MSG = '%<style>s access modifiers like `%<node>s`.'
def on_class(node)
return unless node.body&.begin_type?
check_body(node.body, node)
end
alias on_sclass on_class
alias on_module on_class
alias on_block on_class
private
def autocorrect(corrector, node)
AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
end
def check_body(body, node)
modifiers = body.each_child_node(:send).select(&:bare_access_modifier?)
end_range = node.loc.end
modifiers.each { |modifier| check_modifier(modifier, end_range) }
end
def check_modifier(send_node, end_range)
offset = column_offset_between(send_node.source_range, end_range)
@column_delta = expected_indent_offset - offset
if @column_delta.zero?
correct_style_detected
else
add_offense(send_node) do |corrector|
if offset == unexpected_indent_offset
opposite_style_detected
else
unrecognized_style_detected
end
autocorrect(corrector, send_node)
end
end
end
def message(range)
format(MSG, style: style.capitalize, node: range.source)
end
def expected_indent_offset
style == :outdent ? 0 : configured_indentation_width
end
# An offset that is not expected, but correct if the configuration is
# changed.
def unexpected_indent_offset
configured_indentation_width - expected_indent_offset
end
end
end
end
end