class RuboCop::Cop::Style::BlockDelimiters


}
process(something)
something = thing.some_method
things.map { |thing|
# good
@example AllowedPatterns: [‘map’]
}
process(something)
something = thing.some_method
things.map { |thing|
# bad
@example AllowedPatterns: [] (default)
end
x * 100
foo = lambda do |x|
end
puts “Hello, #{x}”
foo = lambda do |x|
# good
@example AllowedMethods: [‘lambda’, ‘proc’, ‘it’ ] (default)
end
puts foo
def bar(foo)
}
).void
foo: string,
params(
sig {
# good
end
puts foo
def bar(foo)
end
).void
foo: string,
params(
sig do
# bad
# precedence over all other configurations except AllowedMethods.
# in this example, will require ‘{…}` braces. This option takes
# Methods listed in the BracesRequiredMethods list, such as ’sig’
@example BracesRequiredMethods: [‘sig’]
}
word.flip.flop
words.each { |word|
# good
end
word.flip.flop
words.each do |word|
# bad
@example EnforcedStyle: always_braces
}.join(“-”)
word.flip.flop
words.each { |word|
# good
end.join(“-”)
word.flip.flop
words.each do |word|
# bad
@example EnforcedStyle: braces_for_chaining
collection.each do |element| puts element end
# also good
collection.each { |element| puts element }
# good
# either style. (There is no setting for requiring braces on them.)
# any other truthy value, then one-line procedural blocks may use
# If the AllowBracesOnProceduralOneLiners option is set to ‘true`, or
collection.each do |element| puts element end
# good
collection.each { |element| puts element }
# bad
# braces.
# maintained, so one-line procedural blocks must use do-end, not
# set to `false` or any other falsey value, then semantic purity is
# If the AllowBracesOnProceduralOneLiners option is unspecified, or
# EnforcedStyle is set to `semantic`. If so:
# The AllowBracesOnProceduralOneLiners option is allowed unless the
}.inspect
x
map { |x|
}
x
foo = map { |x|
# good
# return value is used/assigned
}
x
each { |x|
# bad
# return value is not used out of scope
# Prefer `{…}` over `do…end` for functional blocks.
end
x
map do |x|
# good
# return value is not used out of scope
end)
x
puts (map do |x|
end
x
foo = map do |x|
# bad
# return value is used/assigned
# Prefer `do…end` over `{…}` for procedural blocks.
@example EnforcedStyle: semantic
end
process(something)
something = thing.some_method
things.map do |thing|
# good - multi-line block
}
process(something)
something = thing.some_method
things.map { |thing|
# bad - multi-line block
items.each { |item| item / 5 }
# good - single line block
items.each do |item| item / 5 end
# bad - single line block
@example EnforcedStyle: line_count_based (default)
Additional methods can be added to the `AllowedMethods`.
`lambda`, `proc`, and `it` are their defaults.
categorised from their usage alone is ignored.
Methods that can be either procedural or functional and cannot be
multi-line blocks.
Check for uses of braces or do/end around single line or

def array_or_range?(node)

def array_or_range?(node)
  node.array_type? || node.range_type?
end

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  return if correction_would_break_code?(node)
  if node.braces?
    replace_braces_with_do_end(corrector, node.loc)
  else
    replace_do_end_with_braces(corrector, node)
  end
end

def begin_required?(block_node)

def begin_required?(block_node)
  # If the block contains `rescue` or `ensure`, it needs to be wrapped in
  # `begin`...`end` when changing `do-end` to `{}`.
  block_node.each_child_node(:rescue, :ensure).any? && !block_node.single_line?
end

def braces_for_chaining_message(node)

def braces_for_chaining_message(node)
  if node.multiline?
    if node.chained?
      'Prefer `{...}` over `do...end` for multi-line chained blocks.'
    else
      'Prefer `do...end` for multi-line blocks without chaining.'
    end
  else
    'Prefer `{...}` over `do...end` for single-line blocks.'
  end
end

def braces_for_chaining_style?(node)

def braces_for_chaining_style?(node)
  block_begin = node.loc.begin.source
  block_begin == if node.multiline?
                   (node.chained? ? '{' : 'do')
                 else
                   '{'
                 end
end

def braces_required_message(node)

def braces_required_message(node)
  format(BRACES_REQUIRED_MESSAGE, method_name: node.method_name.to_s)
end

def braces_required_method?(method_name)

def braces_required_method?(method_name)
  braces_required_methods.include?(method_name.to_s)
end

def braces_required_methods

def braces_required_methods
  cop_config.fetch('BracesRequiredMethods', [])
end

def braces_style?(node)

def braces_style?(node)
  node.loc.begin.source == '{'
end

def conditional?(node)

def conditional?(node)
  node.if_type? || node.or_type? || node.and_type?
end

def correction_would_break_code?(node)

def correction_would_break_code?(node)
  return unless node.keywords?
  node.send_node.arguments? && !node.send_node.parenthesized?
end

def end_of_chain(node)

def end_of_chain(node)
  return end_of_chain(node.block_node) if with_block?(node)
  return node unless node.chained?
  end_of_chain(node.parent)
end

def functional_block?(node)

def functional_block?(node)
  return_value_used?(node) || return_value_of_scope?(node)
end

def functional_method?(method_name)

def functional_method?(method_name)
  cop_config['FunctionalMethods'].map(&:to_sym).include?(method_name)
end

def get_blocks(node, &block)

def get_blocks(node, &block)
  case node.type
  when :block, :numblock
    yield node
  when :send
    get_blocks(node.receiver, &block) if node.receiver
  when :hash
    # A hash which is passed as method argument may have no braces
    # In that case, one of the K/V pairs could contain a block node
    # which could change in meaning if do...end replaced {...}
    return if node.braces?
    node.each_child_node { |child| get_blocks(child, &block) }
  when :pair
    node.each_child_node { |child| get_blocks(child, &block) }
  end
end

def line_count_based_block_style?(node)

def line_count_based_block_style?(node)
  node.multiline? ^ node.braces?
end

def line_count_based_message(node)

def line_count_based_message(node)
  if node.multiline?
    'Avoid using `{...}` for multi-line blocks.'
  else
    'Prefer `{...}` over `do...end` for single-line blocks.'
  end
end

def message(node)

def message(node)
  return braces_required_message(node) if braces_required_method?(node.method_name)
  case style
  when :line_count_based    then line_count_based_message(node)
  when :semantic            then semantic_message(node)
  when :braces_for_chaining then braces_for_chaining_message(node)
  when :always_braces       then ALWAYS_BRACES_MESSAGE
  end
end

def move_comment_before_block(corrector, comment, block_node, closing_brace)

def move_comment_before_block(corrector, comment, block_node, closing_brace)
  range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
  corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
  remove_trailing_whitespace(corrector, range, comment)
  corrector.insert_after(range, "\n")
  corrector.insert_before(block_node, "#{comment.text}\n")
end

def on_block(node)

def on_block(node)
  return if ignored_node?(node)
  return if proper_block_style?(node)
  message = message(node)
  add_offense(node.loc.begin, message: message) do |corrector|
    autocorrect(corrector, node)
  end
end

def on_send(node)

def on_send(node)
  return unless node.arguments?
  return if node.parenthesized?
  return if node.operator_method? || node.assignment_method?
  node.arguments.each do |arg|
    get_blocks(arg) do |block|
      # If there are no parentheses around the arguments, then braces
      # and do-end have different meaning due to how they bind, so we
      # allow either.
      ignore_node(block)
    end
  end
end

def procedural_method?(method_name)

def procedural_method?(method_name)
  cop_config['ProceduralMethods'].map(&:to_sym).include?(method_name)
end

def procedural_oneliners_may_have_braces?

def procedural_oneliners_may_have_braces?
  cop_config['AllowBracesOnProceduralOneLiners']
end

def proper_block_style?(node)

def proper_block_style?(node)
  return true if require_braces?(node)
  return special_method_proper_block_style?(node) if special_method?(node.method_name)
  case style
  when :line_count_based    then line_count_based_block_style?(node)
  when :semantic            then semantic_block_style?(node)
  when :braces_for_chaining then braces_for_chaining_style?(node)
  when :always_braces       then braces_style?(node)
  end
end

def remove_trailing_whitespace(corrector, range, comment)

def remove_trailing_whitespace(corrector, range, comment)
  range_of_trailing = range.end.join(comment.source_range.begin)
  corrector.remove(range_of_trailing) if range_of_trailing.source.match?(/\A\s+\z/)
end

def replace_braces_with_do_end(corrector, loc)

def replace_braces_with_do_end(corrector, loc)
  b = loc.begin
  e = loc.end
  corrector.insert_before(b, ' ') unless whitespace_before?(b)
  corrector.insert_before(e, ' ') unless whitespace_before?(e)
  corrector.insert_after(b, ' ') unless whitespace_after?(b)
  corrector.replace(b, 'do')
  if (comment = processed_source.comment_at_line(e.line))
    move_comment_before_block(corrector, comment, loc.node, e)
  end
  corrector.replace(e, 'end')
end

def replace_do_end_with_braces(corrector, node)

def replace_do_end_with_braces(corrector, node)
  loc = node.loc
  b = loc.begin
  e = loc.end
  corrector.insert_after(b, ' ') unless whitespace_after?(b, 2)
  corrector.replace(b, '{')
  corrector.replace(e, '}')
  corrector.wrap(node.body, "begin\n", "\nend") if begin_required?(node)
end

def require_braces?(node)

def require_braces?(node)
  return false unless node.braces?
  node.each_ancestor(:send).any? do |send|
    send.arithmetic_operation? && node.source_range.end_pos < send.loc.selector.begin_pos
  end
end

def return_value_of_scope?(node)

def return_value_of_scope?(node)
  return unless node.parent
  conditional?(node.parent) || array_or_range?(node.parent) ||
    node.parent.children.last == node
end

def return_value_used?(node)

def return_value_used?(node)
  return unless node.parent
  # If there are parentheses around the block, check if that
  # is being used.
  if node.parent.begin_type?
    return_value_used?(node.parent)
  else
    node.parent.assignment? || node.parent.call_type?
  end
end

def semantic_block_style?(node)

def semantic_block_style?(node)
  method_name = node.method_name
  if node.braces?
    functional_method?(method_name) || functional_block?(node) ||
      (procedural_oneliners_may_have_braces? && !node.multiline?)
  else
    procedural_method?(method_name) || !return_value_used?(node)
  end
end

def semantic_message(node)

def semantic_message(node)
  block_begin = node.loc.begin.source
  if block_begin == '{'
    'Prefer `do...end` over `{...}` for procedural blocks.'
  else
    'Prefer `{...}` over `do...end` for functional blocks.'
  end
end

def special_method?(method_name)

def special_method?(method_name)
  allowed_method?(method_name) ||
    matches_allowed_pattern?(method_name) ||
    braces_required_method?(method_name)
end

def special_method_proper_block_style?(node)

def special_method_proper_block_style?(node)
  method_name = node.method_name
  return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
  return node.braces? if braces_required_method?(method_name)
end

def whitespace_after?(range, length = 1)

def whitespace_after?(range, length = 1)
  /\s/.match?(range.source_buffer.source[range.begin_pos + length, 1])
end

def whitespace_before?(range)

def whitespace_before?(range)
  /\s/.match?(range.source_buffer.source[range.begin_pos - 1, 1])
end

def with_block?(node)

def with_block?(node)
  node.respond_to?(:block_node) && node.block_node
end