From 4244b248a6458399dcdd4e77ea02fbb91d828875 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Mon, 27 Apr 2020 00:12:06 +0900 Subject: [PATCH] Fix a false positive for `Lint/LiteralAsCondition` This PR fixes a false positive for `Lint/LiteralAsCondition` when using `true` literal in `while` and similar cases. `while true` is a known idiom. Normally `loop` is used, OTOH `while true` may be selected for speeding up. Users use these methods depending on use case. That was introduced as part of RubyKaigi 2019. https://rubykaigi.org/2019/presentations/ktou.html --- CHANGELOG.md | 1 + lib/rubocop/cop/lint/literal_as_condition.rb | 23 ++++++------- manual/cops_lint.md | 15 +++++---- .../cop/lint/literal_as_condition_spec.rb | 32 +++++++++++++++++++ 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c92e5c411bf..67c79cfad1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ * [#7899](https://github.com/rubocop-hq/rubocop/issues/7899): Fix an infinite loop error for `Layout/SpaceAroundOperators` with `Layout/ExtraSpacing` when using `ForceEqualSignAlignment: true`. ([@koic][]) * [#7885](https://github.com/rubocop-hq/rubocop/issues/7885): Fix `Style/IfUnlessModifier` logic when tabs are used for indentation. ([@jonas054][]) * [#7909](https://github.com/rubocop-hq/rubocop/pull/7909): Fix a false positive for `Lint/ParenthesesAsGroupedExpression` when using an intended grouped parentheses. ([@koic][]) +* [#7913](https://github.com/rubocop-hq/rubocop/pull/7913): Fix a false positive for `Lint/LiteralAsCondition` when using `true` literal in `while` and similar cases. ([@koic][]) ### Changes diff --git a/lib/rubocop/cop/lint/literal_as_condition.rb b/lib/rubocop/cop/lint/literal_as_condition.rb index 1ab38d41fdb..f98925dd2ea 100644 --- a/lib/rubocop/cop/lint/literal_as_condition.rb +++ b/lib/rubocop/cop/lint/literal_as_condition.rb @@ -10,26 +10,25 @@ module Lint # @example # # # bad - # # if 20 # do_something # end # - # @example - # # # bad - # # if some_var && true # do_something # end # - # @example - # # # good - # # if some_var && some_condition # do_something # end + # + # # good + # # When using a boolean value for an infinite loop. + # while true + # break if condition + # end class LiteralAsCondition < Cop MSG = 'Literal `%s` appeared as a condition.' @@ -38,20 +37,18 @@ def on_if(node) end def on_while(node) - check_for_literal(node) - end + return if condition(node).true_type? - def on_while_post(node) check_for_literal(node) end + alias on_while_post on_while def on_until(node) - check_for_literal(node) - end + return if condition(node).false_type? - def on_until_post(node) check_for_literal(node) end + alias on_until_post on_until def on_case(case_node) if case_node.condition diff --git a/manual/cops_lint.md b/manual/cops_lint.md index 423e8817261..9693297739d 100644 --- a/manual/cops_lint.md +++ b/manual/cops_lint.md @@ -993,24 +993,25 @@ if/while/until. ```ruby # bad - if 20 do_something end -``` -```ruby -# bad +# bad if some_var && true do_something end -``` -```ruby -# good +# good if some_var && some_condition do_something end + +# good +# When using a boolean value for an infinite loop. +while true + break if condition +end ``` ## Lint/LiteralInInterpolation diff --git a/spec/rubocop/cop/lint/literal_as_condition_spec.rb b/spec/rubocop/cop/lint/literal_as_condition_spec.rb index 294f61cf32d..225d5f48722 100644 --- a/spec/rubocop/cop/lint/literal_as_condition_spec.rb +++ b/spec/rubocop/cop/lint/literal_as_condition_spec.rb @@ -176,4 +176,36 @@ end RUBY end + + it 'accepts `true` literal in `while`' do + expect_no_offenses(<<~RUBY) + while true + break if condition + end + RUBY + end + + it 'accepts `true` literal in post-loop `while`' do + expect_no_offenses(<<~RUBY) + begin + break if condition + end while true + RUBY + end + + it 'accepts `false` literal in `until`' do + expect_no_offenses(<<~RUBY) + until false + break if condition + end + RUBY + end + + it 'accepts `false` literal in post-loop `until`' do + expect_no_offenses(<<~RUBY) + begin + break if condition + end until false + RUBY + end end