Class: RuboCop::Cop::Style::AccessModifierDeclarations
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/access_modifier_declarations.rb |
Overview
Access modifiers should be declared to apply to a group of methods
or inline before each method, depending on configuration.
EnforcedStyle config covers only method definitions.
Applications of visibility methods to symbols can be controlled
using AllowModifiersOnSymbols config.
Also, the visibility of attr*
methods can be controlled using
AllowModifiersOnAttrs config.
In Ruby 3.0, attr*
methods now return an array of defined method names
as symbols. So we can write the modifier and attr*
in inline style.
AllowModifiersOnAttrs config allows attr*
methods to be written in
inline style without modifying applications that have been maintained
for a long time in group style. Furthermore, developers who are not very
familiar with Ruby may know that the modifier applies to def
, but they
may not know that it also applies to attr*
methods. It would be easier
to understand if we could write attr*
methods in inline style.
Constant Summary
-
ALLOWED_NODE_TYPES =
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 153%i[pair block].freeze
-
GROUP_STYLE_MESSAGE =
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 141[ '`%<access_modifier>s` should not be', 'inlined in method definitions.' ].join(' ')
-
INLINE_STYLE_MESSAGE =
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 146[ '`%<access_modifier>s` should be', 'inlined in method definitions.' ].join(' ')
-
RESTRICT_ON_SEND =
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 151%i[private protected public module_function].freeze
::RuboCop::Cop::Base
- Inherited
EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::RangeHelp
- 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
- #group_style? ⇒ Boolean readonly private
- #inline_style? ⇒ Boolean readonly private
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
::RuboCop::Cop::AutocorrectLogic
- Included
Instance Method Summary
- #access_modifier_with_alias_method?
- #access_modifier_with_attr?(node)
- #access_modifier_with_symbol?(node)
- #on_send(node)
- #access_modifier_is_inlined?(node) ⇒ Boolean private
- #access_modifier_is_not_inlined?(node) ⇒ Boolean private
- #allow_modifiers_on_alias_method?(node) ⇒ Boolean private
- #allow_modifiers_on_attrs?(node) ⇒ Boolean private
- #allow_modifiers_on_symbols?(node) ⇒ Boolean private
- #allowed?(node) ⇒ Boolean private
- #autocorrect(corrector, node) private
- #correctable_group_offense?(node) ⇒ Boolean private
- #def_source(node, def_nodes) private
- #find_argument_less_modifier_node(node) private
- #find_corresponding_def_nodes(node) private
- #insert_inline_modifier(corrector, node, modifier_name) private
- #message(range) private
- #offense?(node) ⇒ Boolean private
- #percent_symbol_array?(node) ⇒ Boolean private
- #remove_nodes(corrector, *nodes) private
- #replace_defs(corrector, node, def_nodes) private
- #right_siblings_same_inline_method?(node) ⇒ Boolean private
- #select_grouped_def_nodes(node) private
::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
#group_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 241
def group_style? style == :group end
#inline_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 245
def inline_style? style == :inline end
Instance Method Details
#access_modifier_is_inlined?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 249
def access_modifier_is_inlined?(node) node.arguments.any? end
#access_modifier_is_not_inlined?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 253
def access_modifier_is_not_inlined?(node) !access_modifier_is_inlined?(node) end
#access_modifier_with_alias_method?
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 169
def_node_matcher :access_modifier_with_alias_method?, <<~PATTERN (send nil? {:private :protected :public :module_function} (send nil? :alias_method _ _)) PATTERN
#access_modifier_with_attr?(node)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 163
def_node_matcher :access_modifier_with_attr?, <<~PATTERN (send nil? {:private :protected :public :module_function} (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _+)) PATTERN
#access_modifier_with_symbol?(node)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 156
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN (send nil? {:private :protected :public :module_function} {(sym _)+ (splat {#percent_symbol_array? const send})} ) PATTERN
#allow_modifiers_on_alias_method?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 224
def allow_modifiers_on_alias_method?(node) cop_config['AllowModifiersOnAliasMethod'] && access_modifier_with_alias_method?(node) end
#allow_modifiers_on_attrs?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 220
def allow_modifiers_on_attrs?(node) cop_config['AllowModifiersOnAttrs'] && access_modifier_with_attr?(node) end
#allow_modifiers_on_symbols?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 216
def allow_modifiers_on_symbols?(node) cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node) end
#allowed?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 189
def allowed?(node) !node.access_modifier? || ALLOWED_NODE_TYPES.include?(node.parent&.type) || allow_modifiers_on_symbols?(node) || allow_modifiers_on_attrs?(node) || allow_modifiers_on_alias_method?(node) end
#autocorrect(corrector, node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 197
def autocorrect(corrector, node) case style when :group def_nodes = find_corresponding_def_nodes(node) return unless def_nodes.any? replace_defs(corrector, node, def_nodes) when :inline remove_nodes(corrector, node) select_grouped_def_nodes(node).each do |grouped_def_node| insert_inline_modifier(corrector, grouped_def_node, node.method_name) end end end
#correctable_group_offense?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 234
def correctable_group_offense?(node) return false unless group_style? return false if allowed?(node) access_modifier_is_inlined?(node) && find_corresponding_def_nodes(node).any? end
#def_source(node, def_nodes) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 336
def def_source(node, def_nodes) [ *processed_source.ast_with_comments[node].map(&:text), *def_nodes.map(&:source) ].join("\n") end
#find_argument_less_modifier_node(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 296
def find_argument_less_modifier_node(node) return unless (parent = node.parent) parent.each_child_node(:send).find do |child| child.method?(node.method_name) && child.arguments.empty? end end
#find_corresponding_def_nodes(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 277
def find_corresponding_def_nodes(node) if access_modifier_with_symbol?(node) method_names = node.arguments.filter_map do |argument| next unless argument.sym_type? argument.respond_to?(:value) && argument.value end def_nodes = node.parent.each_child_node(:def).select do |child| method_names.include?(child.method_name) end # If there isn't a `def` node for each symbol, we will skip autocorrection. def_nodes.size == method_names.size ? def_nodes : [] else [node.first_argument] end end
#insert_inline_modifier(corrector, node, modifier_name) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 326
def insert_inline_modifier(corrector, node, modifier_name) corrector.insert_before(node, "#{modifier_name} ") end
#message(range) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 267
def (range) access_modifier = range.source if group_style? format(GROUP_STYLE_MESSAGE, access_modifier: access_modifier) elsif inline_style? format(INLINE_STYLE_MESSAGE, access_modifier: access_modifier) end end
#offense?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 228
def offense?(node) (group_style? && access_modifier_is_inlined?(node) && !node.parent&.if_type? && !right_siblings_same_inline_method?(node)) || (inline_style? && access_modifier_is_not_inlined?(node)) end
#on_send(node)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 174
def on_send(node) return if allowed?(node) if offense?(node) add_offense(node.loc.selector) do |corrector| autocorrect(corrector, node) end opposite_style_detected else correct_style_detected end end
#percent_symbol_array?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 212
def percent_symbol_array?(node) node.array_type? && node.percent_literal?(:symbol) end
#remove_nodes(corrector, *nodes) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 330
def remove_nodes(corrector, *nodes) nodes.each do |node| corrector.remove(range_with_comments_and_lines(node)) end end
#replace_defs(corrector, node, def_nodes) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 310
def replace_defs(corrector, node, def_nodes) source = def_source(node, def_nodes) argument_less_modifier_node = find_argument_less_modifier_node(node) if argument_less_modifier_node corrector.insert_after(argument_less_modifier_node, "\n\n#{source}") elsif (ancestor = node.each_ancestor(:block, :class, :module).first) corrector.insert_before(ancestor.loc.end, "#{node.method_name}\n\n#{source}\n") else corrector.replace(node, "#{node.method_name}\n\n#{source}") return end remove_nodes(corrector, *def_nodes, node) end
#right_siblings_same_inline_method?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 257
def right_siblings_same_inline_method?(node) node.right_siblings.any? do |sibling| sibling.send_type? && correctable_group_offense?(sibling) && sibling.method?(node.method_name) && !sibling.arguments.empty? && find_corresponding_def_nodes(sibling).any? end end
#select_grouped_def_nodes(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/style/access_modifier_declarations.rb', line 304
def select_grouped_def_nodes(node) node.right_siblings.take_while do |sibling| !(sibling.send_type? && sibling. ) end.select(&:def_type?) end