class RuboCop::Cop::Layout::FirstHashElementIndentation

})
d: 2
c: 1,
y: {
},
b: 2
a: 1,
takes_multi_pairs_hash(x: {
}
completely: :different
and_now_for_something = {
# good
})
d: 2
c: 1,
y: {
},
b: 2
a: 1,
takes_multi_pairs_hash(x: {
}
completely: :different
and_now_for_something = {
# bad
# braces are indented to the same position.
# The ‘align_brackets` style enforces that the opening and closing
@example EnforcedStyle: align_braces
})
no: :difference
and_in_a_method_call({
}
key: :value
hash = {
# good
})
its_like: :this
but_in_a_method_call({
}
key: :value
hash = {
# bad
# defined inside a method call.
# separate lines is indented the same as a hash literal which is not
# literal where the opening brace and the first key are on
# The `consistent` style enforces that the first key in a hash
@example EnforcedStyle: consistent
})
d: 2
c: 1,
y: {
},
b: 2
a: 1,
takes_multi_pairs_hash(x: {
})
its_like: :this
but_in_a_method_call({
}
key: :value
hash = {
special_inside_parentheses
# good
})
d: 2
c: 1,
y: {
},
b: 2
a: 1,
takes_multi_pairs_hash(x: {
})
no: :difference
and_in_a_method_call({
}
key: :value
hash = {
# bad
# position inside the opening parentheses.
# separate lines is indented one step (two spaces) more than the
# in a hash literal where the opening brace and the first key are on
# The `special_inside_parentheses` style enforces that the first key
@example EnforcedStyle: special_inside_parentheses (default)
styles are ’consistent’ and ‘align_braces’. Here are examples:
This default style is called ‘special_inside_parentheses’. Alternative
than the start of the line where the opening curly brace is.
Other hash literals shall have their first key indented one step more
inside the opening parenthesis.
their first key indented one step (two spaces) more than the position
same line as the opening parenthesis of the method call, shall have
parentheses, and where the opening curly brace of the hash is on the
By default, Hash literals that are arguments in a method call with
other keys’ indentations are handled by the HashAlignment cop.
where the opening brace and the first key are on separate lines. The
Checks the indentation of the first key in a hash literal

def argument_alignment_config

def argument_alignment_config
  config.for_cop('Layout/ArgumentAlignment')
end

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
end

def base_description(indent_base_type)

Returns the description of what the correct indentation is based on.
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

def brace_alignment_style

def brace_alignment_style
  :align_braces
end

def check(hash_node, left_parenthesis)

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

def check_based_on_longest_key(hash_node, left_brace, left_parenthesis)

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

def check_right_brace(right_brace, first_pair, left_brace, left_parenthesis)

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

def enforce_first_argument_with_fixed_indentation?

def enforce_first_argument_with_fixed_indentation?
  return false unless argument_alignment_config['Enabled']
  argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
end

def message(base_description)

def message(base_description)
  format(
    MSG,
    configured_indentation_width: configured_indentation_width,
    base_description: base_description
  )
end

def message_for_right_brace(indent_base_type)

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

def on_hash(node)

def on_hash(node)
  check(node, nil) if node.loc.begin
end

def on_send(node)

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

def separator_style?(first_pair)

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