class RuboCop::Cop::Layout::IndentationWidth
Checks for indentation that doesn’t use the specified number of spaces.
See also the IndentationConsistency
cop which is the companion to this one.
@example
# bad class A def test puts 'hello' end end # good class A def test puts 'hello' end end
@example AllowedPatterns: [‘^s*module’]
# bad module A class B def test puts 'hello' end end end # good module A class B def test puts 'hello' end end end
Constants
- MSG
Public Instance Methods
on_block(node)
click to toggle source
# 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
Also aliased as: on_numblock
on_case(case_node)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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_def(node)
click to toggle source
# 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
Also aliased as: on_defs
on_ensure(node)
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 66 def on_ensure(node) check_indentation(node.loc.keyword, node.body) end
Also aliased as: on_resbody, on_for
on_if(node, base = node)
click to toggle source
# 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)
click to toggle source
# 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_rescue(node)
click to toggle source
# 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_send(node)
click to toggle source
Calls superclass method
RuboCop::Cop::CheckAssignment#on_send
# 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
Also aliased as: on_csend
on_while(node, base = node)
click to toggle source
# 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
Also aliased as: on_until
Private Instance Methods
access_modifier_indentation_style()
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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')
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 341 def check_rescue?(rescue_node) rescue_node.body end
configured_indentation_width()
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 377 def configured_indentation_width cop_config['Width'] end
each_member(members) { |member, source_range| ... }
click to toggle source
# 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()
click to toggle source
# 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)
click to toggle source
# 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
indented_internal_methods_style?()
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 219 def indented_internal_methods_style? indentation_consistency_style == 'indented_internal_methods' end
leftmost_modifier_of(node)
click to toggle source
# 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)
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 302 def message(configured_indentation_width, indentation, name) format( MSG, configured_indentation_width: configured_indentation_width, indentation: indentation, name: name ) end
offending_range(body_node, indentation)
click to toggle source
# 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)
click to toggle source
# 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}" message = message(configured_indentation_width, indentation, name) add_offense(offending_range(body_node, indentation), message: message) do |corrector| autocorrect(corrector, node) end end
other_offense_in_same_range?(node)
click to toggle source
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)
click to toggle source
# 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)
click to toggle source
# 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/ return true unless body_node.loc.column == first_char_pos_on_line end
special_modifier?(node)
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 223 def special_modifier?(node) node.bare_access_modifier? && SPECIAL_MODIFIERS.include?(node.source) end
starts_with_access_modifier?(body_node)
click to toggle source
# File lib/rubocop/cop/layout/indentation_width.rb, line 368 def starts_with_access_modifier?(body_node) return unless body_node.begin_type? starting_node = body_node.children.first return unless starting_node starting_node.send_type? && starting_node.bare_access_modifier? end