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
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, on_itblock
Private Instance Methods
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 99 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
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 76 def args_on_beginning_line?(node) !node.arguments? || node.loc.begin.line == node.arguments.loc.last_line end
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 106 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
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 121 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
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 131 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
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 143 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
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 91 def characters_needed_for_space_and_pipes(node) if node.source.lines.first.end_with?("|\n") PIPE_SIZE else (PIPE_SIZE * 2) + 1 end end
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 155 def include_trailing_comma?(args) arg_count = args.each_descendant(:arg).to_a.size arg_count == 1 && args.source.include?(',') end
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 80 def line_break_necessary_in_args?(node) needed_length_for_args(node) > max_line_length end
Source
# File lib/rubocop/cop/layout/multiline_block_layout.rb, line 84 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