diff --git a/lib/rubocop/cop/internal_affairs/single_line_comparison.rb b/lib/rubocop/cop/internal_affairs/single_line_comparison.rb index 121aa275c03..937f3982992 100644 --- a/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +++ b/lib/rubocop/cop/internal_affairs/single_line_comparison.rb @@ -29,20 +29,21 @@ class SingleLineComparison < Base extend AutoCorrector MSG = 'Use `%s`.' - RESTRICT_ON_SEND = %i[==].freeze + RESTRICT_ON_SEND = %i[== !=].freeze # @!method single_line_comparison(node) def_node_matcher :single_line_comparison, <<~PATTERN { - (send (send $_receiver {:line :first_line}) :== (send _receiver :last_line)) - (send (send $_receiver :last_line) :== (send _receiver {:line :first_line})) + (send (send $_receiver {:line :first_line}) {:== :!=} (send _receiver :last_line)) + (send (send $_receiver :last_line) {:== :!=} (send _receiver {:line :first_line})) } PATTERN def on_send(node) return unless (receiver = single_line_comparison(node)) - preferred = "#{extract_receiver(receiver)}.single_line?" + bang = node.method?(:!=) ? '!' : '' + preferred = "#{bang}#{extract_receiver(receiver)}.single_line?" add_offense(node, message: format(MSG, preferred: preferred)) do |corrector| corrector.replace(node, preferred) diff --git a/lib/rubocop/cop/layout/redundant_line_break.rb b/lib/rubocop/cop/layout/redundant_line_break.rb index 4dc136ed88f..d895b3bd2db 100644 --- a/lib/rubocop/cop/layout/redundant_line_break.rb +++ b/lib/rubocop/cop/layout/redundant_line_break.rb @@ -101,7 +101,7 @@ def suitable_as_single_line?(node) !comment_within?(node) && node.each_descendant(:if, :case, :kwbegin, :def).none? && node.each_descendant(:dstr, :str).none?(&:heredoc?) && - node.each_descendant(:begin).none? { |b| b.first_line != b.last_line } + node.each_descendant(:begin).none? { |b| !b.single_line? } end def convertible_block?(node) diff --git a/lib/rubocop/cop/mixin/check_line_breakable.rb b/lib/rubocop/cop/mixin/check_line_breakable.rb index b6fdb4d804c..34c5325b286 100644 --- a/lib/rubocop/cop/mixin/check_line_breakable.rb +++ b/lib/rubocop/cop/mixin/check_line_breakable.rb @@ -220,7 +220,7 @@ def process_args(args) def already_on_multiple_lines?(node) return node.first_line != node.arguments.last.last_line if node.def_type? - node.first_line != node.last_line + !node.single_line? end end end diff --git a/lib/rubocop/cop/style/multiline_in_pattern_then.rb b/lib/rubocop/cop/style/multiline_in_pattern_then.rb index 7775a83fc27..fa398b87e93 100644 --- a/lib/rubocop/cop/style/multiline_in_pattern_then.rb +++ b/lib/rubocop/cop/style/multiline_in_pattern_then.rb @@ -49,7 +49,7 @@ def on_in_pattern(node) # Requires `then` for write `in` and its body on the same line. def require_then?(in_pattern_node) - return true if in_pattern_node.pattern.first_line != in_pattern_node.pattern.last_line + return true unless in_pattern_node.pattern.single_line? return false unless in_pattern_node.body same_line?(in_pattern_node, in_pattern_node.body) diff --git a/spec/rubocop/cop/internal_affairs/single_line_comparison_spec.rb b/spec/rubocop/cop/internal_affairs/single_line_comparison_spec.rb index cfc82a2f92f..162b748b57b 100644 --- a/spec/rubocop/cop/internal_affairs/single_line_comparison_spec.rb +++ b/spec/rubocop/cop/internal_affairs/single_line_comparison_spec.rb @@ -89,6 +89,28 @@ RUBY end + it 'registers and corrects an offense when negative comparing `first_line` with `last_line`' do + expect_offense(<<~RUBY) + node.first_line != node.last_line + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!node.single_line?`. + RUBY + + expect_correction(<<~RUBY) + !node.single_line? + RUBY + end + + it 'registers and corrects an offense when negative comparing `last_line` with `first_line`' do + expect_offense(<<~RUBY) + node.last_line != node.first_line + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!node.single_line?`. + RUBY + + expect_correction(<<~RUBY) + !node.single_line? + RUBY + end + it 'does not register an offense when comparing the same line' do expect_no_offenses(<<~RUBY) node.loc.first_line == node.loc.line