class RuboCop::Cop::Style::AccessorGrouping
Checks for grouping of accessors in `class` and `module` bodies. By default it enforces accessors to be placed in grouped declarations, but it can be configured to enforce separating them in multiple declarations.
NOTE: `Sorbet` is not compatible with “grouped” style. Consider “separated” style or disabling this cop.
@example EnforcedStyle: grouped (default)
# bad class Foo attr_reader :bar attr_reader :baz end # good class Foo attr_reader :bar, :baz end
@example EnforcedStyle: separated
# bad class Foo attr_reader :bar, :baz end # good class Foo attr_reader :bar attr_reader :baz end
Constants
- ACCESSOR_METHODS
- GROUPED_MSG
- SEPARATED_MSG
Public Instance Methods
on_class(node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 48 def on_class(node) class_send_elements(node).each do |macro| next unless accessor?(macro) check(macro) end end
Private Instance Methods
accessor?(send_node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 96 def accessor?(send_node) send_node.macro? && ACCESSOR_METHODS.include?(send_node.method_name) end
autocorrect(corrector, node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 71 def autocorrect(corrector, node) if (preferred_accessors = preferred_accessors(node)) corrector.replace(node, preferred_accessors) else range = range_with_surrounding_space(node.loc.expression, side: :left) corrector.remove(range) end end
check(send_node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 60 def check(send_node) return if previous_line_comment?(send_node) return unless (grouped_style? && sibling_accessors(send_node).size > 1) || (separated_style? && send_node.arguments.size > 1) message = message(send_node) add_offense(send_node, message: message) do |corrector| autocorrect(corrector, send_node) end end
class_send_elements(class_node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 84 def class_send_elements(class_node) class_def = class_node.body if !class_def || class_def.def_type? [] elsif class_def.send_type? [class_def] else class_def.each_child_node(:send).to_a end end
group_accessors(node, accessors)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 131 def group_accessors(node, accessors) accessor_names = accessors.flat_map { |accessor| accessor.arguments.map(&:source) }.uniq "#{node.method_name} #{accessor_names.join(', ')}" end
grouped_style?()
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 100 def grouped_style? style == :grouped end
message(send_node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 117 def message(send_node) msg = grouped_style? ? GROUPED_MSG : SEPARATED_MSG format(msg, accessor: send_node.method_name) end
preferred_accessors(node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 122 def preferred_accessors(node) if grouped_style? accessors = sibling_accessors(node) group_accessors(node, accessors) if node.loc == accessors.first.loc else separate_accessors(node) end end
previous_line_comment?(node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 80 def previous_line_comment?(node) comment_line?(processed_source[node.first_line - 2]) end
separate_accessors(node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 137 def separate_accessors(node) node.arguments.flat_map do |arg| lines = [ *processed_source.ast_with_comments[arg].map(&:text), "#{node.method_name} #{arg.source}" ] if arg == node.arguments.first lines else indent = ' ' * node.loc.column lines.map { |line| "#{indent}#{line}" } end end.join("\n") end
separated_style?()
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 104 def separated_style? style == :separated end
sibling_accessors(send_node)
click to toggle source
# File lib/rubocop/cop/style/accessor_grouping.rb, line 108 def sibling_accessors(send_node) send_node.parent.each_child_node(:send).select do |sibling| accessor?(sibling) && sibling.method?(send_node.method_name) && node_visibility(sibling) == node_visibility(send_node) && !previous_line_comment?(sibling) end end