Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support autocorrect for Lint/Loop cop #8383

Merged
merged 1 commit into from Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,7 @@
* [#8432](https://github.com/rubocop-hq/rubocop/pull/8432): Add new `Lint/FloatComparison` cop. ([@fatkodima][])
* [#8376](https://github.com/rubocop-hq/rubocop/pull/8376): Add new `Lint/MissingSuper` cop. ([@fatkodima][])
* [#8415](https://github.com/rubocop-hq/rubocop/pull/8415): Add new `Style/ExplicitBlockArgument` cop. ([@fatkodima][])
* [#8383](https://github.com/rubocop-hq/rubocop/pull/8383): Support autocorrect for `Lint/Loop` cop. ([@fatkodima][])
* [#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][])
* [#5067](https://github.com/rubocop-hq/rubocop/issues/5067): Add new `Style/StringConcatenation` cop. ([@fatkodima][])
* [#7425](https://github.com/rubocop-hq/rubocop/pull/7425): Add new `Lint/TopLevelReturnWithArgument` cop. ([@iamravitejag][])
Expand Down
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -1559,6 +1559,7 @@ Lint/Loop:
StyleGuide: '#loop-with-break'
Enabled: true
VersionAdded: '0.9'
VersionChanged: '0.89'

Lint/MissingCopEnableDirective:
Description: 'Checks for a `# rubocop:enable` after `# rubocop:disable`.'
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/cops_lint.adoc
Expand Up @@ -1711,9 +1711,9 @@ This cop checks for interpolated literals.

| Enabled
| Yes
| No
| Yes
| 0.9
| -
| 0.89
|===

This cop checks for uses of `begin...end while/until something`.
Expand Down
23 changes: 22 additions & 1 deletion lib/rubocop/cop/lint/loop.rb
Expand Up @@ -43,6 +43,8 @@ module Lint
# break if some_condition
# end
class Loop < Base
extend AutoCorrector

MSG = 'Use `Kernel#loop` with `break` rather than ' \
'`begin/end/until`(or `while`).'

Expand All @@ -57,7 +59,26 @@ def on_until_post(node)
private

def register_offense(node)
add_offense(node.loc.keyword)
body = node.body

add_offense(node.loc.keyword) do |corrector|
corrector.replace(body.loc.begin, 'loop do')
corrector.remove(keyword_and_condition_range(node))
corrector.insert_before(body.loc.end, build_break_line(node))
end
end

def keyword_and_condition_range(node)
node.body.loc.end.end.join(node.source_range.end)
end

def build_break_line(node)
conditional_keyword = node.while_post_type? ? 'unless' : 'if'
"break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
end

def indent(node)
' ' * node.loc.column
end
end
end
Expand Down
28 changes: 23 additions & 5 deletions spec/rubocop/cop/lint/loop_spec.rb
Expand Up @@ -3,17 +3,35 @@
RSpec.describe RuboCop::Cop::Lint::Loop do
subject(:cop) { described_class.new }

it 'registers an offense for begin/end/while' do
it 'registers an offense and corrects for begin/end/while' do
expect_offense(<<~RUBY)
begin something; top; end while test
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
begin
something
end while test
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
RUBY

expect_correction(<<~RUBY)
loop do
something
break unless test
end
RUBY
end

it 'registers an offense for begin/end/until' do
expect_offense(<<~RUBY)
begin something; top; end until test
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
begin
something
end until test
^^^^^ Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).
RUBY

expect_correction(<<~RUBY)
loop do
something
break if test
end
RUBY
end

Expand Down