Skip to content

Commit 426814e

Browse files
fatkodimabbatsov
authored andcommitted
Support autocorrect for Lint/Loop cop
1 parent c29441f commit 426814e

File tree

5 files changed

+49
-8
lines changed

5 files changed

+49
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* [#8432](https://github.com/rubocop-hq/rubocop/pull/8432): Add new `Lint/FloatComparison` cop. ([@fatkodima][])
1414
* [#8376](https://github.com/rubocop-hq/rubocop/pull/8376): Add new `Lint/MissingSuper` cop. ([@fatkodima][])
1515
* [#8415](https://github.com/rubocop-hq/rubocop/pull/8415): Add new `Style/ExplicitBlockArgument` cop. ([@fatkodima][])
16+
* [#8383](https://github.com/rubocop-hq/rubocop/pull/8383): Support autocorrect for `Lint/Loop` cop. ([@fatkodima][])
1617
* [#8339](https://github.com/rubocop-hq/rubocop/pull/8339): Add `Config#for_badge` as an efficient way to get a cop's config merged with its department's. ([@marcandre][])
1718
* [#5067](https://github.com/rubocop-hq/rubocop/issues/5067): Add new `Style/StringConcatenation` cop. ([@fatkodima][])
1819
* [#7425](https://github.com/rubocop-hq/rubocop/pull/7425): Add new `Lint/TopLevelReturnWithArgument` cop. ([@iamravitejag][])

config/default.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,7 @@ Lint/Loop:
15591559
StyleGuide: '#loop-with-break'
15601560
Enabled: true
15611561
VersionAdded: '0.9'
1562+
VersionChanged: '0.89'
15621563

15631564
Lint/MissingCopEnableDirective:
15641565
Description: 'Checks for a `# rubocop:enable` after `# rubocop:disable`.'

docs/modules/ROOT/pages/cops_lint.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,9 +1711,9 @@ This cop checks for interpolated literals.
17111711

17121712
| Enabled
17131713
| Yes
1714-
| No
1714+
| Yes
17151715
| 0.9
1716-
| -
1716+
| 0.89
17171717
|===
17181718

17191719
This cop checks for uses of `begin...end while/until something`.

lib/rubocop/cop/lint/loop.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ module Lint
4343
# break if some_condition
4444
# end
4545
class Loop < Base
46+
extend AutoCorrector
47+
4648
MSG = 'Use `Kernel#loop` with `break` rather than ' \
4749
'`begin/end/until`(or `while`).'
4850

@@ -57,7 +59,26 @@ def on_until_post(node)
5759
private
5860

5961
def register_offense(node)
60-
add_offense(node.loc.keyword)
62+
body = node.body
63+
64+
add_offense(node.loc.keyword) do |corrector|
65+
corrector.replace(body.loc.begin, 'loop do')
66+
corrector.remove(keyword_and_condition_range(node))
67+
corrector.insert_before(body.loc.end, build_break_line(node))
68+
end
69+
end
70+
71+
def keyword_and_condition_range(node)
72+
node.body.loc.end.end.join(node.source_range.end)
73+
end
74+
75+
def build_break_line(node)
76+
conditional_keyword = node.while_post_type? ? 'unless' : 'if'
77+
"break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
78+
end
79+
80+
def indent(node)
81+
' ' * node.loc.column
6182
end
6283
end
6384
end

spec/rubocop/cop/lint/loop_spec.rb

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,35 @@
33
RSpec.describe RuboCop::Cop::Lint::Loop do
44
subject(:cop) { described_class.new }
55

6-
it 'registers an offense for begin/end/while' do
6+
it 'registers an offense and corrects for begin/end/while' do
77
expect_offense(<<~RUBY)
8-
begin something; top; end while test
9-
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
8+
begin
9+
something
10+
end while test
11+
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
12+
RUBY
13+
14+
expect_correction(<<~RUBY)
15+
loop do
16+
something
17+
break unless test
18+
end
1019
RUBY
1120
end
1221

1322
it 'registers an offense for begin/end/until' do
1423
expect_offense(<<~RUBY)
15-
begin something; top; end until test
16-
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
24+
begin
25+
something
26+
end until test
27+
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
28+
RUBY
29+
30+
expect_correction(<<~RUBY)
31+
loop do
32+
something
33+
break if test
34+
end
1735
RUBY
1836
end
1937

0 commit comments

Comments
 (0)