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. |
Note
|
If there is a RBS::Inline annotation comment just after the accessor method it is always allowed. |
Constant Summary
-
GROUPED_MSG =
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 59'Group together all `%<accessor>s` attributes.'
-
SEPARATED_MSG =
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 60'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 |
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 | Returns a url to view this cops documentation online. |
.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
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
- #group_accessors(node, accessors) private
-
#groupable_accessor?(node) ⇒ Boolean
private
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
- #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_gem_version | Returns a gems locked versions (i.e. |
#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 | Actually private methods. |
#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, #heredoc_range, #max_line_length, #multiline_ranges, #multiline_string?, | |
#range_by_lines | Expand the given range to include all of any lines it covers. |
#range_of_first_line, #range_overlaps_offense?, #string_continuation?, #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 134
def grouped_style? style == :grouped end
#separated_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 138
def separated_style? style == :separated end
Instance Method Details
#autocorrect(corrector, node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 85
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 74
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)
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 122
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 165
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)
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 99
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? # Accessors with RBS::Inline annotations shouldn't be groupable. return false if processed_source.comments.any? do |c| same_line?(c, previous_expression) && c.text.start_with?('#:') end 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 142
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 151
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 62
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 70
alias on_module on_class
#on_sclass(node)
Alias for #on_class.
# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 69
alias on_sclass on_class
#preferred_accessors(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/accessor_grouping.rb', line 156
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 94
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 171
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