Skip to content

Commit

Permalink
Merge pull request #10063 from koic/fix_a_false_positive_for_layout_s…
Browse files Browse the repository at this point in the history
…ingle_line_block_chain

Fix a false positive for `Layout/SingleLineBlockChain`
  • Loading branch information
koic committed Sep 6, 2021
2 parents 27f2c59 + e834c82 commit 8585c75
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
@@ -0,0 +1 @@
* [#10063](https://github.com/rubocop/rubocop/pull/10063): Fix a false positive for `Layout/SingleLineBlockChain` when method call chained on a new line after a single line block with trailing dot. ([@koic][])
19 changes: 15 additions & 4 deletions lib/rubocop/cop/layout/single_line_block_chain.rb
Expand Up @@ -37,15 +37,26 @@ def offending_range(node)
return unless receiver&.block_type?

receiver_location = receiver.loc
closing_block_delimiter_line_number = receiver_location.end.line
return if receiver_location.begin.line < closing_block_delimiter_line_number
closing_block_delimiter_line_num = receiver_location.end.line
return if receiver_location.begin.line < closing_block_delimiter_line_num

node_location = node.loc
dot_range = node_location.dot
return unless dot_range
return if dot_range.line > closing_block_delimiter_line_number
return unless call_method_after_block?(node, dot_range, closing_block_delimiter_line_num)

range_between(dot_range.begin_pos, node_location.selector.end_pos)
range_between(dot_range.begin_pos, selector_range(node).end_pos)
end

def call_method_after_block?(node, dot_range, closing_block_delimiter_line_num)
return false if dot_range.line > closing_block_delimiter_line_num

dot_range.column < selector_range(node).column
end

def selector_range(node)
# l.(1) has no selector, so we use the opening parenthesis instead
node.loc.selector || node.loc.begin
end
end
end
Expand Down
15 changes: 15 additions & 0 deletions spec/rubocop/cli/autocorrect_spec.rb
Expand Up @@ -2070,6 +2070,21 @@ def do_even_more_stuff
RUBY
end

it 'corrects `Layout/DotPosition` and `Layout/SingleLineBlockChain` offenses' do
source_file = Pathname('example.rb')
create_file(source_file, <<~RUBY)
example.select { |item| item.cond? }.
join('-')
RUBY

expect(cli.run(['-a', '--only', 'Layout/DotPosition,Layout/SingleLineBlockChain'])).to eq(0)

expect(source_file.read).to eq(<<~RUBY)
example.select { |item| item.cond? }
.join('-')
RUBY
end

it 'does not correct Style/IfUnlessModifier offense disabled by a comment directive and ' \
'does not fire Lint/RedundantCopDisableDirective offense even though that directive ' \
'would make the modifier form too long' do
Expand Down
19 changes: 19 additions & 0 deletions spec/rubocop/cop/layout/single_line_block_chain_spec.rb
Expand Up @@ -13,13 +13,32 @@
RUBY
end

it 'registers an offense for no selector method call chained on the same line as a block' do
expect_offense(<<~RUBY)
example.select { |item| item.cond? }.(42)
^^ Put method call on a separate line if chained to a single line block.
RUBY

expect_correction(<<~RUBY)
example.select { |item| item.cond? }
.(42)
RUBY
end

it 'does not register an offense for method call chained on a new line after a single line block' do
expect_no_offenses(<<~RUBY)
example.select { |item| item.cond? }
.join('-')
RUBY
end

it 'does not register an offense for method call chained on a new line after a single line block with trailing dot' do
expect_no_offenses(<<~RUBY)
example.select { |item| item.cond? }.
join('-')
RUBY
end

it 'does not register an offense for method call chained without a dot' do
expect_no_offenses(<<~RUBY)
example.select { |item| item.cond? } + 2
Expand Down

0 comments on commit 8585c75

Please sign in to comment.