From 98a5a12f61f387c6b9d792ea7e2de8dc5f09c81d Mon Sep 17 00:00:00 2001 From: Jonas Arvidsson Date: Sun, 4 Jul 2021 16:56:38 +0200 Subject: [PATCH] [Fix #9905] Fix single line concatenation false positive By checking that the inspected node is multiline, we should get rid of this false positive. Happens for code like puts 'a'"#{b}" We're also checking that none of the children is multiline. This is done to skip weird corner cases that are impossible to have a consistent alignment rule for. It turns out that the new multiline checks make it possible to remove a couple of old conditions when checking if it's a concatenation with backslashes we're inspecting. It is perhaps possible to search for backslash and newline in the code, but I'd like to avoid that, because I'm afraid of other weird corner cases if we take the regexp search approach. --- ...x_line_end_string_concatenation_indentation.md | 1 + .../line_end_string_concatenation_indentation.rb | 11 +++-------- ...e_end_string_concatenation_indentation_spec.rb | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 changelog/fix_line_end_string_concatenation_indentation.md diff --git a/changelog/fix_line_end_string_concatenation_indentation.md b/changelog/fix_line_end_string_concatenation_indentation.md new file mode 100644 index 00000000000..d5f0ba13b59 --- /dev/null +++ b/changelog/fix_line_end_string_concatenation_indentation.md @@ -0,0 +1 @@ +* [#9905](https://github.com/rubocop/rubocop/issues/9905): Fix false positive for single line concatenation in `Layout/LineEndStringConcatenationIndentation`. ([@jonas054][]) diff --git a/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb b/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb index 5e656357e3d..6c9b917f909 100644 --- a/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +++ b/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb @@ -85,14 +85,9 @@ def autocorrect(corrector, node) private def strings_concatenated_with_backslash?(dstr_node) - !dstr_node.heredoc? && - !single_string_literal?(dstr_node) && - dstr_node.children.length > 1 && - dstr_node.children.all? { |c| c.str_type? || c.dstr_type? } - end - - def single_string_literal?(dstr_node) - dstr_node.loc.respond_to?(:begin) && dstr_node.loc.begin + dstr_node.multiline? && + dstr_node.children.all? { |c| c.str_type? || c.dstr_type? } && + dstr_node.children.none?(&:multiline?) end def always_indented?(dstr_node) diff --git a/spec/rubocop/cop/layout/line_end_string_concatenation_indentation_spec.rb b/spec/rubocop/cop/layout/line_end_string_concatenation_indentation_spec.rb index 0cf25a4324d..26cbe7b5bac 100644 --- a/spec/rubocop/cop/layout/line_end_string_concatenation_indentation_spec.rb +++ b/spec/rubocop/cop/layout/line_end_string_concatenation_indentation_spec.rb @@ -14,6 +14,21 @@ let(:cop_indent) { nil } # use indentation width from Layout/IndentationWidth shared_examples 'common' do + it 'accepts single line string literal concatenation' do + expect_no_offenses(<<~'RUBY') + text = 'offense' + puts 'This probably should not be '"an #{text}" + RUBY + end + + it 'accepts string literal with line break concatenated with other string' do + expect_no_offenses(<<~'RUBY') + text = 'offense' + puts 'This probably + should not be '"an #{text}" + RUBY + end + it 'accepts a multiline string literal' do expect_no_offenses(<<~'RUBY') puts %(