class RuboCop::Cop::Layout::FirstHashElementIndentation
Checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys’ indentations are handled by the HashAlignment
cop.
By default, ‘Hash` literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.
Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.
This default style is called ‘special_inside_parentheses’. Alternative styles are ‘consistent’ and ‘align_braces’. Here are examples:
@example EnforcedStyle: special_inside_parentheses (default)
# The `special_inside_parentheses` style enforces that the first key # in a hash literal where the opening brace and the first key are on # separate lines is indented one step (two spaces) more than the # position inside the opening parentheses. # bad hash = { key: :value } and_in_a_method_call({ no: :difference }) takes_multi_pairs_hash(x: { a: 1, b: 2 }, y: { c: 1, d: 2 }) # good special_inside_parentheses hash = { key: :value } but_in_a_method_call({ its_like: :this }) takes_multi_pairs_hash(x: { a: 1, b: 2 }, y: { c: 1, d: 2 })
@example EnforcedStyle: consistent
# The `consistent` style enforces that the first key in a hash # literal where the opening brace and the first key are on # separate lines is indented the same as a hash literal which is not # defined inside a method call. # bad hash = { key: :value } but_in_a_method_call({ its_like: :this }) # good hash = { key: :value } and_in_a_method_call({ no: :difference })
@example EnforcedStyle: align_braces
# The `align_brackets` style enforces that the opening and closing # braces are indented to the same position. # bad and_now_for_something = { completely: :different } takes_multi_pairs_hash(x: { a: 1, b: 2 }, y: { c: 1, d: 2 }) # good and_now_for_something = { completely: :different } takes_multi_pairs_hash(x: { a: 1, b: 2 }, y: { c: 1, d: 2 })
Constants
- MSG
Public Instance Methods
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 122 def on_hash(node) check(node, nil) if node.loc.begin end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 126 def on_send(node) return if enforce_first_argument_with_fixed_indentation? each_argument_node(node, :hash) do |hash_node, left_parenthesis| check(hash_node, left_parenthesis) end end
Private Instance Methods
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 137 def autocorrect(corrector, node) AlignmentCorrector.correct(corrector, processed_source, node, @column_delta) end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 191 def base_description(indent_base_type) case indent_base_type when :left_brace_or_bracket 'the position of the opening brace' when :first_column_after_left_parenthesis 'the first position after the preceding left parenthesis' when :parent_hash_key 'the parent hash key' else 'the start of the line where the left curly brace is' end end
Returns the description of what the correct indentation is based on.
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 141 def brace_alignment_style :align_braces end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 145 def check(hash_node, left_parenthesis) return if ignored_node?(hash_node) left_brace = hash_node.loc.begin first_pair = hash_node.pairs.first if first_pair return if same_line?(first_pair, left_brace) if separator_style?(first_pair) check_based_on_longest_key(hash_node, left_brace, left_parenthesis) else check_first(first_pair, left_brace, left_parenthesis, 0) end end check_right_brace(hash_node.loc.end, first_pair, left_brace, left_parenthesis) end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 184 def check_based_on_longest_key(hash_node, left_brace, left_parenthesis) key_lengths = hash_node.keys.map { |key| key.source_range.length } check_first(hash_node.pairs.first, left_brace, left_parenthesis, key_lengths.max - key_lengths.first) end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 164 def check_right_brace(right_brace, first_pair, left_brace, left_parenthesis) # if the right brace is on the same line as the last value, accept return if /\S/.match?(right_brace.source_line[0...right_brace.column]) expected_column, indent_base_type = indent_base(left_brace, first_pair, left_parenthesis) @column_delta = expected_column - right_brace.column return if @column_delta.zero? message = message_for_right_brace(indent_base_type) add_offense(right_brace, message: message) do |corrector| autocorrect(corrector, right_brace) end end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 227 def enforce_first_argument_with_fixed_indentation? argument_alignment_config = config.for_enabled_cop('Layout/ArgumentAlignment') argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation' end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 204 def message(base_description) format( MSG, configured_indentation_width: configured_indentation_width, base_description: base_description ) end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 212 def message_for_right_brace(indent_base_type) case indent_base_type when :left_brace_or_bracket 'Indent the right brace the same as the left brace.' when :first_column_after_left_parenthesis 'Indent the right brace the same as the first position ' \ 'after the preceding left parenthesis.' when :parent_hash_key 'Indent the right brace the same as the parent hash key.' else 'Indent the right brace the same as the start of the line ' \ 'where the left brace is.' end end
Source
# File lib/rubocop/cop/layout/first_hash_element_indentation.rb, line 178 def separator_style?(first_pair) separator = first_pair.loc.operator key = "Enforced#{separator.is?(':') ? 'Colon' : 'HashRocket'}Style" config.for_cop('Layout/HashAlignment')[key] == 'separator' end