Skip to content

Commit

Permalink
Fix infinite loop between Layout/IndentationWidth and `Layout/Rescu…
Browse files Browse the repository at this point in the history
…eEnsureAlignment` autocorrection.
  • Loading branch information
dvandersluis committed Mar 19, 2021
1 parent 709e5ee commit 455cf0a
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelog/fix_fix_infinite_loop_between.md
@@ -0,0 +1 @@
* [#9619](https://github.com/rubocop/rubocop/pull/9619): Fix infinite loop between `Layout/IndentationWidth` and `Layout/RescueEnsureAlignment` autocorrection. ([@dvandersluis][])
12 changes: 10 additions & 2 deletions lib/rubocop/cop/layout/indentation_width.rb
Expand Up @@ -310,12 +310,20 @@ def other_offense_in_same_range?(node)
def indentation_to_check?(base_loc, body_node)
return false if skip_check?(base_loc, body_node)

if %i[rescue ensure].include?(body_node.type)
if body_node.rescue_type?
check_rescue?(body_node)
elsif body_node.ensure_type?
block_body, = *body_node
return unless block_body

check_rescue?(block_body) if block_body.rescue_type?
else
true
end
end

true
def check_rescue?(rescue_node)
rescue_node.body
end

def skip_check?(base_loc, body_node)
Expand Down
45 changes: 45 additions & 0 deletions spec/rubocop/cli/autocorrect_spec.rb
Expand Up @@ -1885,4 +1885,49 @@ def do_even_more_stuff
expect(status).to eq(0)
expect(source_file.read).to eq(source)
end

it 'corrects indentation for a begin/rescue/else/ensure/end block properly' do
source_file = Pathname('example.rb')
create_file(source_file, <<~RUBY)
def my_func
puts 'do something outside block'
begin
puts 'do something error prone'
rescue SomeException, SomeOther
puts 'wrongly indented error handling'
rescue StandardError
puts 'another wrongly indented error handling'
else
puts 'wrongly indented normal case handling'
ensure
puts 'wrongly indented common handling'
end
end
RUBY

status = cli.run(
[
'--auto-correct',
'--only',
'Layout/IndentationWidth,Layout/RescueEnsureAlignment,Layout/ElseAlignment'
]
)
expect(status).to eq(0)
expect(source_file.read).to eq(<<~RUBY)
def my_func
puts 'do something outside block'
begin
puts 'do something error prone'
rescue SomeException, SomeOther
puts 'wrongly indented error handling'
rescue StandardError
puts 'another wrongly indented error handling'
else
puts 'wrongly indented normal case handling'
ensure
puts 'wrongly indented common handling'
end
end
RUBY
end
end
66 changes: 58 additions & 8 deletions spec/rubocop/cop/layout/indentation_width_spec.rb
Expand Up @@ -213,6 +213,46 @@ class Test
RUBY
end

it 'accepts `rescue`/`ensure` after an empty body' do
expect_no_offenses(<<~RUBY)
begin
rescue
handle_error
ensure
something
end
RUBY
end

it 'accepts `rescue` after an empty def' do
expect_no_offenses(<<~RUBY)
def foo
rescue
handle_error
end
RUBY
end

it 'accepts `ensure` after an empty def' do
expect_no_offenses(<<~RUBY)
def foo
ensure
something
end
RUBY
end

it 'accepts `rescue`/`ensure` after an empty def' do
expect_no_offenses(<<~RUBY)
def foo
rescue
handle_error
ensure
something
end
RUBY
end

it 'does not raise any error with empty braces' do
expect_no_offenses(<<~RUBY)
if cond
Expand Down Expand Up @@ -1294,16 +1334,16 @@ def my_func
puts 'do something error prone'
^{} Use 2 (not 0) spaces for indentation.
rescue SomeException, SomeOther => e
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
rescue
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
else
puts 'wrongly intended normal case handling'
puts 'wrongly indented normal case handling'
^^^ Use 2 (not 3) spaces for indentation.
ensure
puts 'wrongly intended common handling'
puts 'wrongly indented common handling'
^^^^ Use 2 (not 4) spaces for indentation.
end
end
Expand All @@ -1317,24 +1357,34 @@ def my_func
def my_func
puts 'do something error prone'
rescue SomeException
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
rescue
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
end
RUBY

expect_correction(<<~RUBY)
def my_func
puts 'do something error prone'
rescue SomeException
puts 'wrongly indented error handling'
rescue
puts 'wrongly indented error handling'
end
RUBY
end

it 'registers an offense for bad indent of defs bodies with a modifier' do
expect_offense(<<~RUBY)
foo def self.my_func
puts 'do something error prone'
rescue SomeException
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
rescue
puts 'wrongly intended error handling'
puts 'wrongly indented error handling'
^ Use 2 (not 1) spaces for indentation.
end
RUBY
Expand Down
23 changes: 23 additions & 0 deletions spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb
Expand Up @@ -408,6 +408,29 @@ def method2
RUBY
end

it 'accepts correctly aligned rescue/ensure with def' do
expect_no_offenses(<<~RUBY)
def foo
something
rescue StandardError
handle_error
ensure
error
end
RUBY
end

it 'accepts correctly aligned rescue/ensure with def with no body' do
expect_no_offenses(<<~RUBY)
def foo
rescue StandardError
handle_error
ensure
error
end
RUBY
end

it 'accepts correctly aligned rescue in assigned begin-end block' do
expect_no_offenses(<<-RUBY)
foo = begin
Expand Down

0 comments on commit 455cf0a

Please sign in to comment.