class RuboCop::Cop::Layout::SpaceBeforeBlockBraces

Checks that block braces have or don’t have a space before the opening brace depending on configuration.

@example EnforcedStyle: space (default)

# bad
foo.map{ |a|
  a.bar.to_s
}

# good
foo.map { |a|
  a.bar.to_s
}

@example EnforcedStyle: no_space

# bad
foo.map { |a|
  a.bar.to_s
}

# good
foo.map{ |a|
  a.bar.to_s
}

@example EnforcedStyleForEmptyBraces: space (default)

# bad
7.times{}

# good
7.times {}

@example EnforcedStyleForEmptyBraces: no_space

# bad
7.times {}

# good
7.times{}

Constants

DETECTED_MSG
MISSING_MSG

Public Class Methods

autocorrect_incompatible_with() click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 52
def self.autocorrect_incompatible_with
  [Style::SymbolProc]
end

Public Instance Methods

on_block(node) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 56
def on_block(node)
  return if node.keywords?

  # Do not register an offense for multi-line braces when specifying
  # `EnforcedStyle: no_space`. It will conflict with autocorrection
  # by `EnforcedStyle: line_count_based` of `Style/BlockDelimiters` cop.
  # That means preventing autocorrection to incorrect autocorrected
  # code.
  # See: https://github.com/rubocop/rubocop/issues/7534
  return if conflict_with_block_delimiters?(node)

  left_brace = node.loc.begin
  space_plus_brace = range_with_surrounding_space(left_brace)
  used_style =
    space_plus_brace.source.start_with?('{') ? :no_space : :space

  if empty_braces?(node.loc)
    check_empty(left_brace, space_plus_brace, used_style)
  else
    check_non_empty(left_brace, space_plus_brace, used_style)
  end
end
Also aliased as: on_numblock
on_numblock(node)
Alias for: on_block

Private Instance Methods

autocorrect(corrector, range) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 124
def autocorrect(corrector, range)
  case range.source
  when /\s/ then corrector.remove(range)
  else           corrector.insert_before(range, ' ')
  end
end
block_delimiters_style() click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 144
def block_delimiters_style
  config.for_cop('Style/BlockDelimiters')['EnforcedStyle']
end
check_empty(left_brace, space_plus_brace, used_style) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 83
def check_empty(left_brace, space_plus_brace, used_style)
  return if style_for_empty_braces == used_style

  config_to_allow_offenses['EnforcedStyleForEmptyBraces'] = used_style.to_s

  if style_for_empty_braces == :space
    add_offense(left_brace, message: MISSING_MSG) do |corrector|
      autocorrect(corrector, left_brace)
    end
  else
    space = range_between(space_plus_brace.begin_pos, left_brace.begin_pos)
    add_offense(space, message: DETECTED_MSG) do |corrector|
      autocorrect(corrector, space)
    end
  end
end
check_non_empty(left_brace, space_plus_brace, used_style) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 100
def check_non_empty(left_brace, space_plus_brace, used_style)
  case used_style
  when style  then correct_style_detected
  when :space then space_detected(left_brace, space_plus_brace)
  else             space_missing(left_brace)
  end
end
conflict_with_block_delimiters?(node) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 140
def conflict_with_block_delimiters?(node)
  block_delimiters_style == 'line_count_based' && style == :no_space && node.multiline?
end
empty_braces?(loc) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 148
def empty_braces?(loc)
  loc.begin.end_pos == loc.end.begin_pos
end
space_detected(left_brace, space_plus_brace) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 115
def space_detected(left_brace, space_plus_brace)
  space = range_between(space_plus_brace.begin_pos, left_brace.begin_pos)

  add_offense(space, message: DETECTED_MSG) do |corrector|
    autocorrect(corrector, space)
    opposite_style_detected
  end
end
space_missing(left_brace) click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 108
def space_missing(left_brace)
  add_offense(left_brace, message: MISSING_MSG) do |corrector|
    autocorrect(corrector, left_brace)
    opposite_style_detected
  end
end
style_for_empty_braces() click to toggle source
# File lib/rubocop/cop/layout/space_before_block_braces.rb, line 131
def style_for_empty_braces
  case cop_config['EnforcedStyleForEmptyBraces']
  when 'space'    then :space
  when 'no_space' then :no_space
  when nil then style
  else raise 'Unknown EnforcedStyleForEmptyBraces selected!'
  end
end