class RuboCop::Cop::Layout::MultilineBlockLayout
Checks whether the multiline do end blocks have a newline after the start of the block. Additionally, it checks whether the block arguments, if any, are on the same line as the start of the block. Putting block arguments on separate lines, because the whole line would otherwise be too long, is accepted.
@example
# bad blah do |i| foo(i) bar(i) end # 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) } # good blah { | long_list, of_parameters, that_would_not, fit_on_one_line | foo(i) bar(i) }
Constants
- ARG_MSG
- MSG
- PIPE_SIZE
Public Instance Methods
on_block(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 59 def on_block(node) return if node.single_line? unless args_on_beginning_line?(node) || line_break_necessary_in_args?(node) add_offense_for_expression(node, node.arguments, ARG_MSG) end return unless node.body && same_line?(node.loc.begin, node.body) add_offense_for_expression(node, node.body, MSG) end
Also aliased as: on_numblock
Private Instance Methods
add_offense_for_expression(node, expr, msg)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 98 def add_offense_for_expression(node, expr, msg) expression = expr.source_range range = range_between(expression.begin_pos, expression.end_pos) add_offense(range, message: msg) { |corrector| autocorrect(corrector, node) } end
args_on_beginning_line?(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 75 def args_on_beginning_line?(node) !node.arguments? || node.loc.begin.line == node.arguments.loc.last_line end
autocorrect(corrector, node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 105 def autocorrect(corrector, node) unless args_on_beginning_line?(node) autocorrect_arguments(corrector, node) expr_before_body = node.arguments.source_range.end end return unless node.body expr_before_body ||= node.loc.begin return unless same_line?(expr_before_body, node.body) autocorrect_body(corrector, node, node.body) end
autocorrect_arguments(corrector, node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 120 def autocorrect_arguments(corrector, node) end_pos = range_with_surrounding_space( node.arguments.source_range, side: :right, newlines: false ).end_pos range = range_between(node.loc.begin.end.begin_pos, end_pos) corrector.replace(range, " |#{block_arg_string(node, node.arguments)}|") end
autocorrect_body(corrector, node, block_body)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 130 def autocorrect_body(corrector, node, block_body) first_node = if block_body.begin_type? && !block_body.source.start_with?('(') block_body.children.first else block_body end block_start_col = node.source_range.column corrector.insert_before(first_node, "\n #{' ' * block_start_col}") end
block_arg_string(node, args)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 142 def block_arg_string(node, args) arg_string = args.children.map do |arg| if arg.mlhs_type? "(#{block_arg_string(node, arg)})" else arg.source end end.join(', ') arg_string += ',' if include_trailing_comma?(node.arguments) arg_string end
characters_needed_for_space_and_pipes(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 90 def characters_needed_for_space_and_pipes(node) if node.source.lines.first.end_with?("|\n") PIPE_SIZE else 1 + (PIPE_SIZE * 2) end end
include_trailing_comma?(args)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 154 def include_trailing_comma?(args) arg_count = args.each_descendant(:arg).to_a.size arg_count == 1 && args.source.include?(',') end
line_break_necessary_in_args?(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 79 def line_break_necessary_in_args?(node) needed_length_for_args(node) > max_line_length end
needed_length_for_args(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 83 def needed_length_for_args(node) node.source_range.column + characters_needed_for_space_and_pipes(node) + node.source.lines.first.chomp.length + block_arg_string(node, node.arguments).length end