Class: RuboCop::Cop::Layout::IndentationWidth
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:
self,
::RuboCop::Cop::AllowedPattern ,
::RuboCop::Cop::CheckAssignment ,
::RuboCop::Cop::Alignment ,
::RuboCop::Cop::EndKeywordAlignment ,
::RuboCop::Cop::RangeHelp ,
::RuboCop::Cop::ConfigurableEnforcedStyle ,
::RuboCop::Cop::Base ,
::RuboCop::Cop::AutocorrectLogic ,
::RuboCop::Cop::IgnoredNode ,
::RuboCop::Util ,
RuboCop::AST::Sexp
|
|
Inherits: |
RuboCop::Cop::Base
|
Defined in: | lib/rubocop/cop/layout/indentation_width.rb |
Overview
Checks for indentation that doesn’t use the specified number of spaces.
The indentation width can be configured using the Width
setting. The default width is 2.
See also the Layout/IndentationConsistency
cop which is the companion to this one.
Constant Summary
-
MSG =
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 52'Use %<configured_indentation_width>d (not %<indentation>d) ' \ 'spaces for%<name>s indentation.'
::RuboCop::Cop::Base
- Inherited
EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::RangeHelp
- Included
::RuboCop::Cop::EndKeywordAlignment
- Included
::RuboCop::Cop::Alignment
- 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
- #indented_internal_methods_style? ⇒ Boolean readonly private
::RuboCop::Cop::AllowedPattern
- Included
::RuboCop::Cop::Alignment
- Included
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
::RuboCop::Cop::AutocorrectLogic
- Included
Instance Method Summary
- #access_modifier?(node)
- #on_block(node) (also: #on_numblock)
- #on_case(case_node)
- #on_case_match(case_match)
- #on_class(node) (also: #on_sclass, #on_module)
-
#on_csend(node)
Alias for #on_send.
- #on_def(node) (also: #on_defs)
-
#on_defs(node)
Alias for #on_def.
- #on_ensure(node)
-
#on_for(node)
Alias for #on_resbody.
- #on_if(node, base = node)
- #on_kwbegin(node)
-
#on_module(node)
Alias for #on_class.
-
#on_numblock(node)
Alias for #on_block.
- #on_resbody(node) (also: #on_for)
- #on_rescue(node)
-
#on_sclass(node)
Alias for #on_class.
- #on_send(node) (also: #on_csend)
-
#on_until(node, base = node)
Alias for #on_while.
- #on_while(node, base = node) (also: #on_until)
- #access_modifier_indentation_style private
- #autocorrect(corrector, node) private
- #check_assignment(node, rhs) private
- #check_if(node, body, else_clause, base_loc) private
- #check_indentation(base_loc, body_node, style = 'normal') private
- #check_members(base, members) private
- #check_members_for_indented_internal_methods_style(members) private
- #check_members_for_normal_style(base, members) private
- #check_rescue?(rescue_node) ⇒ Boolean private
- #configured_indentation_width private
- #each_member(members) private
- #indentation_consistency_style private
- #indentation_to_check?(base_loc, body_node) ⇒ Boolean private
- #leftmost_modifier_of(node) private
- #message(configured_indentation_width, indentation, name) private
- #offending_range(body_node, indentation) private
- #offense(body_node, indentation, style) private
-
#other_offense_in_same_range?(node) ⇒ Boolean
private
Returns true if the given node is within another node that has already been marked for autocorrection by this cop.
- #select_check_member(member) private
- #skip_check?(base_loc, body_node) ⇒ Boolean private
- #special_modifier?(node) ⇒ Boolean private
- #starts_with_access_modifier?(body_node) ⇒ Boolean private
::RuboCop::Cop::AllowedPattern
- Included
#allowed_line?, #allowed_patterns, #cop_config_deprecated_methods_values, #cop_config_patterns_values, #matches_allowed_pattern? |
::RuboCop::Cop::CheckAssignment
- Included
#on_and_asgn | Alias for CheckAssignment#on_lvasgn. |
#on_casgn | Alias for CheckAssignment#on_lvasgn. |
#on_cvasgn | Alias for CheckAssignment#on_lvasgn. |
#on_gvasgn | Alias for CheckAssignment#on_lvasgn. |
#on_ivasgn | Alias for CheckAssignment#on_lvasgn. |
#on_lvasgn, | |
#on_masgn | Alias for CheckAssignment#on_lvasgn. |
#on_op_asgn | Alias for CheckAssignment#on_lvasgn. |
#on_or_asgn | Alias for CheckAssignment#on_lvasgn. |
#on_send, #extract_rhs |
::RuboCop::Cop::Alignment
- Included
#check_alignment, #configured_indentation_width, #display_column, #each_bad_alignment, #end_of_line_comment, #indentation, #offset, #register_offense, #within? |
::RuboCop::Cop::EndKeywordAlignment
- 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 | 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, #max_line_length, | |
#range_by_lines | Expand the given range to include all of any lines it covers. |
#range_of_first_line, #range_overlaps_offense?, #string_continuation, #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
#indented_internal_methods_style? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 219
def indented_internal_methods_style? indentation_consistency_style == 'indented_internal_methods' end
Instance Method Details
#access_modifier?(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 56
def_node_matcher :access_modifier?, <<~PATTERN [(send ...) access_modifier?] PATTERN
#access_modifier_indentation_style (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 227
def access_modifier_indentation_style config.for_cop('Layout/AccessModifierIndentation')['EnforcedStyle'] end
#autocorrect(corrector, node) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 165
def autocorrect(corrector, node) AlignmentCorrector.correct(corrector, processed_source, node, @column_delta) end
#check_assignment(node, rhs) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 235
def check_assignment(node, rhs) # If there are method calls chained to the right hand side of the # assignment, we let rhs be the receiver of those method calls before # we check its indentation. rhs = first_part_of_call_chain(rhs) return unless rhs end_config = config.for_cop('Layout/EndAlignment') style = end_config['EnforcedStyleAlignWith'] || 'keyword' base = variable_alignment?(node.loc, rhs, style.to_sym) ? node : rhs case rhs.type when :if then on_if(rhs, base) when :while, :until then on_while(rhs, base) else return end ignore_node(rhs) end
#check_if(node, body, else_clause, base_loc) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 255
def check_if(node, body, else_clause, base_loc) return if node.ternary? check_indentation(base_loc, body) return unless else_clause # If the else clause is an elsif, it will get its own on_if call so # we don't need to process it here. return if else_clause.if_type? && else_clause.elsif? check_indentation(node.loc.else, else_clause) end
#check_indentation(base_loc, body_node, style = 'normal') (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 268
def check_indentation(base_loc, body_node, style = 'normal') return unless indentation_to_check?(base_loc, body_node) indentation = column_offset_between(body_node.loc, base_loc) @column_delta = configured_indentation_width - indentation return if @column_delta.zero? offense(body_node, indentation, style) end
#check_members(base, members) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 169
def check_members(base, members) check_indentation(base, select_check_member(members.first)) return unless members.any? && members.first.begin_type? if indentation_consistency_style == 'indented_internal_methods' check_members_for_indented_internal_methods_style(members) else check_members_for_normal_style(base, members) end end
#check_members_for_indented_internal_methods_style(members) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 193
def check_members_for_indented_internal_methods_style(members) each_member(members) do |member, previous_modifier| check_indentation(previous_modifier, member, indentation_consistency_style) end end
#check_members_for_normal_style(base, members) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 199
def check_members_for_normal_style(base, members) members.first.children.each do |member| next if member.send_type? && member.access_modifier? check_indentation(base, member) end end
#check_rescue?(rescue_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 340
def check_rescue?(rescue_node) rescue_node.body end
#configured_indentation_width (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 376
def configured_indentation_width cop_config['Width'] end
#each_member(members) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 207
def each_member(members) previous_modifier = nil members.first.children.each do |member| if member.send_type? && member.special_modifier? previous_modifier = member elsif previous_modifier yield member, previous_modifier.source_range previous_modifier = nil end end end
#indentation_consistency_style (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 231
def indentation_consistency_style config.for_cop('Layout/IndentationConsistency')['EnforcedStyle'] end
#indentation_to_check?(base_loc, body_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 323
def indentation_to_check?(base_loc, body_node) return false if skip_check?(base_loc, body_node) if body_node.rescue_type? check_rescue?(body_node) elsif body_node.ensure_type? block_body, = *body_node # rubocop:disable InternalAffairs/NodeDestructuring if block_body&.rescue_type? check_rescue?(block_body) else !block_body.nil? end else true end end
#leftmost_modifier_of(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 380
def leftmost_modifier_of(node) return node unless node.parent&.send_type? leftmost_modifier_of(node.parent) end
#message(configured_indentation_width, indentation, name) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 302
def (configured_indentation_width, indentation, name) format( MSG, configured_indentation_width: configured_indentation_width, indentation: indentation, name: name ) end
#offending_range(body_node, indentation) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 359
def offending_range(body_node, indentation) expr = body_node.source_range begin_pos = expr.begin_pos ind = expr.begin_pos - indentation pos = indentation >= 0 ? ind..begin_pos : begin_pos..ind range_between(pos.begin, pos.end) end
#offense(body_node, indentation, style) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 278
def offense(body_node, indentation, style) # This cop only autocorrects the first statement in a def body, for # example. body_node = body_node.children.first if body_node.begin_type? && !parentheses?(body_node) # Since autocorrect changes a number of lines, and not only the line # where the reported offending range is, we avoid autocorrection if # this cop has already found other offenses is the same # range. Otherwise, two corrections can interfere with each other, # resulting in corrupted code. node = if autocorrect? && other_offense_in_same_range?(body_node) nil else body_node end name = style == 'normal' ? '' : " #{style}" = (configured_indentation_width, indentation, name) add_offense(offending_range(body_node, indentation), message: ) do |corrector| autocorrect(corrector, node) end end
#on_block(node) Also known as: #on_numblock
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 81
def on_block(node) end_loc = node.loc.end return unless begins_its_line?(end_loc) check_indentation(end_loc, node.body) return unless indented_internal_methods_style? check_members(end_loc, [node.body]) end
#on_case(case_node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 138
def on_case(case_node) case_node.when_branches.each do |when_node| check_indentation(when_node.loc.keyword, when_node.body) end check_indentation(case_node.when_branches.last.loc.keyword, case_node.else_branch) end
#on_case_match(case_match)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 146
def on_case_match(case_match) case_match.each_in_pattern do |in_pattern_node| check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body) end else_branch = case_match.else_branch&.empty_else_type? ? nil : case_match.else_branch check_indentation(case_match.in_pattern_branches.last.loc.keyword, else_branch) end
#on_class(node) Also known as: #on_sclass, #on_module
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 95
def on_class(node) base = node.loc.keyword return if same_line?(base, node.body) check_members(base, [node.body]) end
#on_csend(node)
Alias for #on_send.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 119
alias on_csend on_send
#on_def(node) Also known as: #on_defs
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 121
def on_def(node) return if ignored_node?(node) check_indentation(node.loc.keyword, node.body) end
#on_defs(node)
Alias for #on_def.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 126
alias on_defs on_def
#on_ensure(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 69
def on_ensure(node) check_indentation(node.loc.keyword, node.branch) end
#on_for(node)
Alias for #on_resbody.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 67
alias on_for on_resbody
#on_if(node, base = node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 156
def on_if(node, base = node) return if ignored_node?(node) return if node.ternary? || node.modifier_form? check_if(node, node.body, node.else_branch, base.loc) end
#on_kwbegin(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 73
def on_kwbegin(node) # Check indentation against end keyword but only if it's first on its # line. return unless begins_its_line?(node.loc.end) check_indentation(node.loc.end, node.children.first) end
#on_module(node)
Alias for #on_class.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 102
alias on_module on_class
#on_numblock(node)
Alias for #on_block.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 93
alias on_numblock on_block
#on_resbody(node) Also known as: #on_for
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 64
def on_resbody(node) check_indentation(node.loc.keyword, node.body) end
#on_rescue(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 60
def on_rescue(node) check_indentation(node.loc.else, node.else_branch) end
#on_sclass(node)
Alias for #on_class.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 101
alias on_sclass on_class
#on_send(node) Also known as: #on_csend
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 104
def on_send(node) super return unless node.adjacent_def_modifier? def_end_config = config.for_cop('Layout/DefEndAlignment') style = def_end_config['EnforcedStyleAlignWith'] || 'start_of_line' base = if style == 'def' node.first_argument else leftmost_modifier_of(node) || node end check_indentation(base.source_range, node.first_argument.body) ignore_node(node.first_argument) end
#on_until(node, base = node)
Alias for #on_while.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 136
alias on_until on_while
#on_while(node, base = node) Also known as: #on_until
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 128
def on_while(node, base = node) return if ignored_node?(node) return unless node.single_line_condition? check_indentation(base.loc, node.body) end
#other_offense_in_same_range?(node) ⇒ Boolean
(private)
Returns true if the given node is within another node that has already been marked for autocorrection by this cop.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 313
def other_offense_in_same_range?(node) expr = node.source_range @offense_ranges ||= [] return true if @offense_ranges.any? { |r| within?(expr, r) } @offense_ranges << expr false end
#select_check_member(member) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 181
def select_check_member(member) return unless member if access_modifier?(member.children.first) return if access_modifier_indentation_style == 'outdent' member.children.first else member end end
#skip_check?(base_loc, body_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 344
def skip_check?(base_loc, body_node) return true if allowed_line?(base_loc) return true unless body_node # Don't check if expression is on same line as "then" keyword, etc. return true if same_line?(body_node, base_loc) return true if starts_with_access_modifier?(body_node) # Don't check indentation if the line doesn't start with the body. # For example, lines like "else do_something". first_char_pos_on_line = body_node.source_range.source_line =~ /\S/ body_node.loc.column != first_char_pos_on_line end
#special_modifier?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 223
def special_modifier?(node) node. && SPECIAL_MODIFIERS.include?(node.source) end
#starts_with_access_modifier?(body_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 367
def starts_with_access_modifier?(body_node) return false unless body_node.begin_type? starting_node = body_node.children.first return false unless starting_node starting_node.send_type? && starting_node. end