lib/rubocop/cop/style/multiline_block_layout.rb
# encoding: utf-8 module RuboCop module Cop module Style # This cop checks whether the multiline do end blocks have a newline # after the start of the block. # # @example # # bad # blah do |i| foo(i) # bar(i) # end # # # good # blah do |i| # foo(i) # bar(i) # end # # # bad # blah { |i| foo(i) # bar(i) # } # # # good # blah { |i| # foo(i) # bar(i) # } class MultilineBlockLayout < Cop MSG = 'Block body expression is on the same line as the block start.' def on_block(node) end_loc = node.loc.end do_loc = node.loc.begin # Actually it's either do or {. return if do_loc.line == end_loc.line # One-liner, no newline needed. # A block node has three children: the block start, # the arguments, and the expression. We care if the block start # and the expression start on the same line. last_expression = node.children.last return unless last_expression expression_loc = last_expression.loc return unless do_loc.line == expression_loc.line expression = last_expression.loc.expression range = Parser::Source::Range.new(expression.source_buffer, expression.begin_pos, expression.end_pos) add_offense(node, range) end def autocorrect(node) @corrections << lambda do |corrector| _method, _args, block_body = *node first_node = if block_body.type == :begin block_body.children.first else block_body end block_start_col = node.loc.expression.column corrector.insert_before(first_node.loc.expression, "\n #{' ' * block_start_col}") end end end end end end