class RuboCop::Cop::Layout::SpaceAroundKeyword

something = 123 if test
end
while (something)
end
something ‘test’ do |x|
# good
something = 123if test
end
while(something)
end
something ‘test’do|x|
# bad
@example
Checks the spacing around the keywords.

def accept_left_parenthesis?(range)

def accept_left_parenthesis?(range)
  ACCEPT_LEFT_PAREN.include?(range.source)
end

def accept_left_square_bracket?(range)

def accept_left_square_bracket?(range)
  ACCEPT_LEFT_SQUARE_BRACKET.include?(range.source)
end

def accepted_opening_delimiter?(range, char)

def accepted_opening_delimiter?(range, char)
  return true unless char
  accept_left_square_bracket?(range) && char == '[' ||
    accept_left_parenthesis?(range) && char == '('
end

def autocorrect(range)

def autocorrect(range)
  if space_before_missing?(range)
    ->(corrector) { corrector.insert_before(range, ' '.freeze) }
  else
    ->(corrector) { corrector.insert_after(range, ' '.freeze) }
  end
end

def check(node, locations, begin_keyword = DO)

def check(node, locations, begin_keyword = DO)
  locations.each do |loc|
    next unless node.loc.respond_to?(loc)
    range = node.loc.public_send(loc)
    next unless range
    case loc
    when :begin then check_begin(node, range, begin_keyword)
    when :end then check_end(node, range, begin_keyword)
    else check_keyword(node, range)
    end
  end
end

def check_begin(node, range, begin_keyword)

def check_begin(node, range, begin_keyword)
  return if begin_keyword && !range.is?(begin_keyword)
  check_keyword(node, range)
end

def check_end(node, range, begin_keyword)

def check_end(node, range, begin_keyword)
  return if begin_keyword == DO && !do?(node)
  offense(range, MSG_BEFORE) if space_before_missing?(range)
end

def check_keyword(node, range)

def check_keyword(node, range)
  offense(range, MSG_BEFORE) if space_before_missing?(range) &&
                                !preceded_by_operator?(node, range)
  offense(range, MSG_AFTER) if space_after_missing?(range)
end

def do?(node)

def do?(node)
  node.loc.begin && node.loc.begin.is?(DO)
end

def offense(range, msg)

def offense(range, msg)
  add_offense(range,
              location: range,
              message: format(msg, range: range.source))
end

def on_and(node)

def on_and(node)
  check(node, [:operator].freeze) if node.keyword?
end

def on_block(node)

def on_block(node)
  check(node, %i[begin end].freeze)
end

def on_break(node)

def on_break(node)
  check(node, [:keyword].freeze)
end

def on_case(node)

def on_case(node)
  check(node, %i[keyword else].freeze)
end

def on_defined?(node)

def on_defined?(node)
  check(node, [:keyword].freeze)
end

def on_ensure(node)

def on_ensure(node)
  check(node, [:keyword].freeze)
end

def on_for(node)

def on_for(node)
  check(node, %i[begin end].freeze)
end

def on_if(node)

def on_if(node)
  check(node, %i[keyword else begin end].freeze, 'then'.freeze)
end

def on_kwbegin(node)

def on_kwbegin(node)
  check(node, %i[begin end].freeze, nil)
end

def on_next(node)

def on_next(node)
  check(node, [:keyword].freeze)
end

def on_or(node)

def on_or(node)
  check(node, [:operator].freeze) if node.keyword?
end

def on_postexe(node)

def on_postexe(node)
  check(node, [:keyword].freeze)
end

def on_preexe(node)

def on_preexe(node)
  check(node, [:keyword].freeze)
end

def on_resbody(node)

def on_resbody(node)
  check(node, [:keyword].freeze)
end

def on_rescue(node)

def on_rescue(node)
  check(node, [:else].freeze)
end

def on_return(node)

def on_return(node)
  check(node, [:keyword].freeze)
end

def on_send(node)

def on_send(node)
  check(node, [:selector].freeze) if node.keyword_not?
end

def on_super(node)

def on_super(node)
  check(node, [:keyword].freeze)
end

def on_until(node)

def on_until(node)
  check(node, %i[begin end keyword].freeze)
end

def on_when(node)

def on_when(node)
  check(node, [:keyword].freeze)
end

def on_while(node)

def on_while(node)
  check(node, %i[begin end keyword].freeze)
end

def on_yield(node)

def on_yield(node)
  check(node, [:keyword].freeze)
end

def on_zsuper(node)

def on_zsuper(node)
  check(node, [:keyword].freeze)
end

def preceded_by_operator?(node, _range)

def preceded_by_operator?(node, _range)
  # regular dotted method calls bind more tightly than operators
  # so we need to climb up the AST past them
  node.each_ancestor do |ancestor|
    return true if ancestor.and_type? || ancestor.or_type?
    return false unless ancestor.send_type?
    return true if operator?(ancestor.method_name)
  end
  false
end

def safe_navigation_call?(range, pos)

def safe_navigation_call?(range, pos)
  range.source_buffer.source[pos, 2].start_with?(SAFE_NAVIGATION)
end

def space_after_missing?(range)

def space_after_missing?(range)
  pos = range.end_pos
  char = range.source_buffer.source[pos]
  return false if accepted_opening_delimiter?(range, char)
  return false if safe_navigation_call?(range, pos)
  char !~ /[\s;,#\\\)\}\]\.]/
end

def space_before_missing?(range)

def space_before_missing?(range)
  pos = range.begin_pos - 1
  return false if pos < 0
  range.source_buffer.source[pos] !~ /[\s\(\|\{\[;,\*\=]/
end