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.
See also the IndentationConsistency cop which is the companion to this one.
Constant Summary
-
MSG =
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 53'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 |
.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
- #indented_internal_methods_style? ⇒ Boolean readonly private
::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) (also: #on_resbody, #on_for)
-
#on_for(node)
Alias for #on_ensure.
- #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)
Alias for #on_ensure.
- #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
::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, #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
#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 57
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 341
def check_rescue?(rescue_node) rescue_node.body end
#configured_indentation_width (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 377
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 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 381
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 360
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.each_when 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) Also known as: #on_resbody, #on_for
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 66
def on_ensure(node) check_indentation(node.loc.keyword, node.body) end
#on_for(node)
Alias for #on_ensure.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 71
alias on_for on_ensure
#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)
Alias for #on_ensure.
# File 'lib/rubocop/cop/layout/indentation_width.rb', line 70
alias on_resbody on_ensure
#on_rescue(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/indentation_width.rb', line 61
def on_rescue(node) _begin_node, *_rescue_nodes, else_node = *node check_indentation(node.loc.else, else_node) 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 345
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 368
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