Class: RuboCop::Cop::Style::AccessorGrouping
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::RuboCop::Cop::AutoCorrector ,
::RuboCop::Cop::Base ,
::RuboCop::ExcludeLimit ,
NodePattern::Macros,
RuboCop::AST::Sexp
|
|
Instance Chain:
|
|
Inherits: |
RuboCop::Cop::Base
|
Defined in: | lib/rubocop/cop/style/accessor_grouping.rb |
Overview
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
|
If there is a method call before the accessor method it is always allowed as it might be intended like Sorbet. |
Constant Summary
-
GROUPED_MSG =
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 56'Group together all `%<accessor>s` attributes.'
-
SEPARATED_MSG =
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 57'Use one attribute per `%<accessor>s`.'
::RuboCop::Cop::Base
- Inherited
EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::RangeHelp
- Included
::RuboCop::Cop::VisibilityHelp
- Included
Class Attribute Summary
::RuboCop::Cop::AutoCorrector
- Extended
::RuboCop::Cop::Base
- Inherited
.gem_requirements, .lint?, | |
.support_autocorrect? | Returns if class supports autocorrect. |
.support_multiple_source? | Override if your cop should be called repeatedly for multiple investigations Between calls to |
.builtin? |
Class Method Summary
::RuboCop::Cop::Base
- Inherited
.autocorrect_incompatible_with | List of cops that should not try to autocorrect at the same time as this cop. |
.badge | Naming. |
.callbacks_needed, .cop_name, .department, | |
.documentation_url | Cops (other than builtin) are encouraged to implement this. |
.exclude_from_registry | Call for abstract Cop classes. |
.inherited, | |
.joining_forces | Override and return the Force class(es) you need to join. |
.match? | Returns true if the cop name or the cop namespace matches any of the given names. |
.new, | |
.requires_gem | Register a version requirement for the given gem name. |
.restrict_on_send |
::RuboCop::ExcludeLimit
- Extended
exclude_limit | Sets up a configuration option to have an exclude limit tracked. |
transform |
Instance Attribute Summary
- #grouped_style? ⇒ Boolean readonly private
- #separated_style? ⇒ Boolean readonly private
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
::RuboCop::Cop::AutocorrectLogic
- Included
Instance Method Summary
- #on_class(node) (also: #on_sclass, #on_module)
-
#on_module(node)
Alias for #on_class.
-
#on_sclass(node)
Alias for #on_class.
- #autocorrect(corrector, node) private
- #check(send_node) private
- #class_send_elements(class_node) private
- #group_accessors(node, accessors) private
- #groupable_accessor?(node) ⇒ Boolean private
- #groupable_sibling_accessors(send_node) private
- #message(send_node) private
- #preferred_accessors(node) private
- #previous_line_comment?(node) ⇒ Boolean private
- #separate_accessors(node) private
::RuboCop::Cop::VisibilityHelp
- Included
::RuboCop::Cop::RangeHelp
- Included
#add_range, #column_offset_between, | |
#contents_range | A range containing only the contents of a literal with delimiters (e.g. |
#directions, | |
#effective_column | Returns the column attribute of the range, except if the range is on the first line and there’s a byte order mark at the beginning of that line, in which case 1 is subtracted from the column value. |
#final_pos, #move_pos, #move_pos_str, #range_between, #range_by_whole_lines, #range_with_comments, #range_with_comments_and_lines, #range_with_surrounding_comma, #range_with_surrounding_space, #source_range |
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
#add_global_offense | Adds an offense that has no particular location. |
#add_offense | Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense. |
#begin_investigation | Called before any investigation. |
#callbacks_needed, | |
#cop_config | Configuration Helpers. |
#cop_name, #excluded_file?, | |
#external_dependency_checksum | This method should be overridden when a cop’s behavior depends on state that lives outside of these locations: |
#inspect, | |
#message | Gets called if no message is specified when calling |
#name | Alias for Base#cop_name. |
#offenses, | |
#on_investigation_end | Called after all on_… |
#on_new_investigation | Called before all on_… |
#on_other_file | Called instead of all on_… |
#parse | There should be very limited reasons for a Cop to do it’s own parsing. |
#parser_engine, | |
#ready | Called between investigations. |
#relevant_file?, #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction, | |
#callback_argument | Reserved for Cop::Cop. |
#complete_investigation | Called to complete an investigation. |
#correct, #current_corrector, | |
#current_offense_locations | Reserved for Commissioner: |
#current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, #file_name_matches_any?, #find_message, #find_severity, #range_for_original, #range_from_node_or_range, #reset_investigation, #use_corrector |
::RuboCop::Cop::AutocorrectLogic
- Included
#disable_offense, #disable_offense_at_end_of_line, #disable_offense_before_and_after, #disable_offense_with_eol_or_surround_comment, #max_line_length, | |
#range_by_lines | Expand the given range to include all of any lines it covers. |
#range_of_first_line, #surrounding_heredoc, #surrounding_percent_array |
::RuboCop::Cop::IgnoredNode
- Included
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Attribute Details
#grouped_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 126
def grouped_style? style == :grouped end
#separated_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 130
def separated_style? style == :separated end
Instance Method Details
#autocorrect(corrector, node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 82
def autocorrect(corrector, node) if (preferred_accessors = preferred_accessors(node)) corrector.replace(node, preferred_accessors) else range = range_with_surrounding_space(node.source_range, side: :left) corrector.remove(range) end end
#check(send_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 71
def check(send_node) return if previous_line_comment?(send_node) || !groupable_accessor?(send_node) return unless (grouped_style? && groupable_sibling_accessors(send_node).size > 1) || (separated_style? && send_node.arguments.size > 1) = (send_node) add_offense(send_node, message: ) do |corrector| autocorrect(corrector, send_node) end end
#class_send_elements(class_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 114
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) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 157
def group_accessors(node, accessors) accessor_names = accessors.flat_map { |accessor| accessor.arguments.map(&:source) }.uniq "#{node.method_name} #{accessor_names.join(', ')}" end
#groupable_accessor?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 96
def groupable_accessor?(node) return true unless (previous_expression = node.left_siblings.last) # Accessors with Sorbet `sig { ... }` blocks shouldn't be groupable. if previous_expression.block_type? previous_expression.child_nodes.each do |child_node| break previous_expression = child_node if child_node.send_type? end end return true unless previous_expression.send_type? previous_expression.attribute_accessor? || previous_expression.access_modifier? || node.first_line - previous_expression.last_line > 1 # there is a space between nodes end
#groupable_sibling_accessors(send_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 134
def groupable_sibling_accessors(send_node) send_node.parent.each_child_node(:send).select do |sibling| sibling.attribute_accessor? && sibling.method?(send_node.method_name) && node_visibility(sibling) == node_visibility(send_node) && groupable_accessor?(sibling) && !previous_line_comment?(sibling) end end
#message(send_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 143
def (send_node) msg = grouped_style? ? GROUPED_MSG : SEPARATED_MSG format(msg, accessor: send_node.method_name) end
#on_class(node) Also known as: #on_sclass, #on_module
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 59
def on_class(node) class_send_elements(node).each do |macro| next unless macro.attribute_accessor? check(macro) end end
#on_module(node)
Alias for #on_class.
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 67
alias on_module on_class
#on_sclass(node)
Alias for #on_class.
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 66
alias on_sclass on_class
#preferred_accessors(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 148
def preferred_accessors(node) if grouped_style? accessors = groupable_sibling_accessors(node) group_accessors(node, accessors) if node.loc == accessors.first.loc else separate_accessors(node) end end
#previous_line_comment?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 91
def previous_line_comment?(node) comment_line?(processed_source[node.first_line - 2]) end
#separate_accessors(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 163
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.first_argument lines else indent = ' ' * node.loc.column lines.map { |line| "#{indent}#{line}" } end end.join("\n") end