class RuboCop::Cop::Style::BracesAroundHashParameters

This cop checks for braces around the last parameter in a method call if the last parameter is a hash. It supports `braces`, `no_braces` and `context_dependent` styles.

@example EnforcedStyle: braces

# The `braces` style enforces braces around all method
# parameters that are hashes.

# bad
some_method(x, y, a: 1, b: 2)

# good
some_method(x, y, {a: 1, b: 2})

@example EnforcedStyle: no_braces (default)

# The `no_braces` style checks that the last parameter doesn't
# have braces around it.

# bad
some_method(x, y, {a: 1, b: 2})

# good
some_method(x, y, a: 1, b: 2)

@example EnforcedStyle: context_dependent

# The `context_dependent` style checks that the last parameter
# doesn't have braces around it, but requires braces if the
# second to last parameter is also a hash literal.

# bad
some_method(x, y, {a: 1, b: 2})
some_method(x, y, {a: 1, b: 2}, a: 1, b: 2)

# good
some_method(x, y, a: 1, b: 2)
some_method(x, y, {a: 1, b: 2}, {a: 1, b: 2})

Constants

MSG

Public Instance Methods

autocorrect(send_node) click to toggle source

We let AutocorrectUnlessChangingAST#autocorrect work with the send node, because that context is needed. When parsing the code to see if the AST has changed, a braceless hash would not be parsed as a hash otherwise.

# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 62
def autocorrect(send_node)
  hash_node = send_node.last_argument

  lambda do |corrector|
    if hash_node.braces?
      remove_braces_with_whitespace(corrector,
                                    hash_node,
                                    extra_space(hash_node))
    else
      add_braces(corrector, hash_node)
    end
  end
end
on_csend(node)
Alias for: on_send
on_send(node) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 48
def on_send(node)
  return if node.assignment_method? || node.operator_method?

  return unless node.arguments? && node.last_argument.hash_type? &&
                !node.last_argument.empty?

  check(node.last_argument, node.arguments)
end
Also aliased as: on_csend

Private Instance Methods

add_arg_offense(arg, type) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 100
def add_arg_offense(arg, type)
  add_offense(arg.parent, location: arg.source_range,
                          message: format(MSG,
                                          type: type.to_s.capitalize))
end
add_braces(corrector, node) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 183
def add_braces(corrector, node)
  corrector.insert_before(node.source_range, '{')
  corrector.insert_after(node.source_range, '}')
end
check(arg, args) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 78
def check(arg, args)
  if style == :braces && !arg.braces?
    add_arg_offense(arg, :missing)
  elsif style == :no_braces && arg.braces?
    add_arg_offense(arg, :redundant)
  elsif style == :context_dependent
    check_context_dependent(arg, args)
  end
end
check_context_dependent(arg, args) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 88
def check_context_dependent(arg, args)
  braces_around_second_from_end = args.size > 1 && args[-2].hash_type?

  if arg.braces?
    unless braces_around_second_from_end
      add_arg_offense(arg, :redundant)
    end
  elsif braces_around_second_from_end
    add_arg_offense(arg, :missing)
  end
end
extra_left_space?(hash_node) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 115
def extra_left_space?(hash_node)
  @extra_left_space ||= begin
    top_line = hash_node.source_range.source_line
    top_line.delete(' ') == '{'
  end
end
extra_right_space?(hash_node) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 122
def extra_right_space?(hash_node)
  @extra_right_space ||= begin
    bottom_line_number = hash_node.source_range.last_line
    bottom_line = processed_source.lines[bottom_line_number - 1]
    bottom_line.delete(' ') == '}'
  end
end
extra_space(hash_node) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 106
def extra_space(hash_node)
  {
    newlines: extra_left_space?(hash_node) &&
      extra_right_space?(hash_node),
    left: extra_left_space?(hash_node),
    right: extra_right_space?(hash_node)
  }
end
left_brace_and_space(loc_begin, space) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 165
def left_brace_and_space(loc_begin, space)
  range_with_surrounding_space(range: loc_begin,
                               side: :right,
                               newlines: space[:newlines],
                               whitespace: space[:left])
end
left_whole_line_range(loc_begin) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 149
def left_whole_line_range(loc_begin)
  if range_by_whole_lines(loc_begin).source.strip == '{'
    range_by_whole_lines(loc_begin, include_final_newline: true)
  else
    loc_begin
  end
end
remove_braces_with_range(corrector, left_range, right_range) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 144
def remove_braces_with_range(corrector, left_range, right_range)
  corrector.remove(left_range)
  corrector.remove(right_range)
end
remove_braces_with_whitespace(corrector, node, space) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 130
def remove_braces_with_whitespace(corrector, node, space)
  if node.multiline?
    remove_braces_with_range(corrector,
                             left_whole_line_range(node.loc.begin),
                             right_whole_line_range(node.loc.end))
  else
    right_brace_and_space = right_brace_and_space(node.loc.end, space)
    left_brace_and_space = left_brace_and_space(node.loc.begin, space)
    remove_braces_with_range(corrector,
                             left_brace_and_space,
                             right_brace_and_space)
  end
end
right_brace_and_space(loc_end, space) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 172
def right_brace_and_space(loc_end, space)
  brace_and_space =
    range_with_surrounding_space(
      range: loc_end,
      side: :left,
      newlines: space[:newlines],
      whitespace: space[:right]
    )
  range_with_surrounding_comma(brace_and_space, :left)
end
right_whole_line_range(loc_end) click to toggle source
# File lib/rubocop/cop/style/braces_around_hash_parameters.rb, line 157
def right_whole_line_range(loc_end)
  if range_by_whole_lines(loc_end).source.strip =~ /\A}\s*,?\z/
    range_by_whole_lines(loc_end, include_final_newline: true)
  else
    loc_end
  end
end