class RuboCop::Cop::Layout::SpaceInsideHashLiteralBraces

Checks that braces used for hash literals have or don't have surrounding space depending on configuration.

Constants

MSG

Public Instance Methods

on_hash(node) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 13
def on_hash(node)
  tokens = processed_source.tokens

  hash_literal_with_braces(node) do |begin_index, end_index|
    check(tokens[begin_index], tokens[begin_index + 1])
    return if begin_index == end_index - 1

    check(tokens[end_index - 1], tokens[end_index])
  end
end

Private Instance Methods

ambiguous_or_unexpected_style_detected(style, is_match) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 86
def ambiguous_or_unexpected_style_detected(style, is_match)
  if is_match
    ambiguous_style_detected(style, :compact)
  else
    unexpected_style_detected(style)
  end
end
autocorrect(range) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 109
def autocorrect(range)
  lambda do |corrector|
    # It is possible that BracesAroundHashParameters will remove the
    # braces while this cop inserts spaces. This can lead to unwanted
    # changes to the inspected code. If we replace the brace with a
    # brace plus space (rather than just inserting a space), then any
    # removal of the same brace will give us a clobbering error. This
    # in turn will make RuboCop fall back on cop-by-cop
    # auto-correction.  Problem solved.
    case range.source
    when /\s/ then corrector.remove(range)
    when '{' then corrector.replace(range, '{ ')
    else corrector.replace(range, ' }')
    end
  end
end
check(t1, t2) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 45
def check(t1, t2)
  # No offense if line break inside.
  return if t1.pos.line < t2.pos.line
  return if t2.type == :tCOMMENT # Also indicates there's a line break.

  is_empty_braces = left_brace?(t1) && right_brace?(t2)
  expect_space    = expect_space?(t1, t2)

  if offense?(t1, t2, expect_space)
    incorrect_style_detected(t1, t2, expect_space, is_empty_braces)
  else
    correct_style_detected
  end
end
expect_space?(t1, t2) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 60
def expect_space?(t1, t2)
  is_same_braces  = t1.type == t2.type
  is_empty_braces = left_brace?(t1) && right_brace?(t2)

  if is_same_braces && style == :compact
    false
  elsif is_empty_braces
    cop_config['EnforcedStyleForEmptyBraces'] != 'no_space'
  else
    style != :no_space
  end
end
hash_literal_with_braces(node) { |begin_index, end_index| ... } click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 26
def hash_literal_with_braces(node)
  tokens = processed_source.tokens
  begin_index = index_of_first_token(node)
  return unless left_brace?(tokens[begin_index])

  end_index = index_of_last_token(node)
  return unless right_brace?(tokens[end_index])

  yield begin_index, end_index
end
incorrect_style_detected(t1, t2, expect_space, is_empty_braces) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 73
def incorrect_style_detected(t1, t2, expect_space, is_empty_braces)
  brace = (t1.text == '{' ? t1 : t2).pos
  range = expect_space ? brace : space_range(brace)
  add_offense(
    range,
    location: range,
    message: message(brace, is_empty_braces, expect_space)
  ) do
    style = expect_space ? :no_space : :space
    ambiguous_or_unexpected_style_detected(style, t1.text == t2.text)
  end
end
left_brace?(token) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 37
def left_brace?(token)
  token.type == :tLBRACE
end
message(brace, is_empty_braces, expect_space) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 99
def message(brace, is_empty_braces, expect_space)
  inside_what = if is_empty_braces
                  'empty hash literal braces'
                else
                  brace.source
                end
  problem = expect_space ? 'missing' : 'detected'
  format(MSG, "#{inside_what} #{problem}")
end
offense?(t1, t2, expect_space) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 94
def offense?(t1, t2, expect_space)
  has_space = space_between?(t1, t2)
  expect_space ? !has_space : has_space
end
range_of_space_to_the_left(range) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 142
def range_of_space_to_the_left(range)
  src = range.source_buffer.source
  begin_pos = range.begin_pos
  begin_pos -= 1 while src[begin_pos - 1] =~ /[ \t]/

  range_between(begin_pos, range.end_pos - 1)
end
range_of_space_to_the_right(range) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 134
def range_of_space_to_the_right(range)
  src = range.source_buffer.source
  end_pos = range.end_pos
  end_pos += 1 while src[end_pos] =~ /[ \t]/

  range_between(range.begin_pos + 1, end_pos)
end
right_brace?(token) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 41
def right_brace?(token)
  token.type == :tRCURLY
end
space_range(token_range) click to toggle source
# File lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb, line 126
def space_range(token_range)
  if token_range.source == '{'
    range_of_space_to_the_right(token_range)
  else
    range_of_space_to_the_left(token_range)
  end
end