Skip to content

Commit ebd90fb

Browse files
dvandersluisbbatsov
authored andcommitted
[Fix #8897] Change Style/StringConcatenation to accept line-end concatenation between two strings so that Style/LineEndConcatenation can handle it instead.
1 parent dbd9aca commit ebd90fb

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#8897](https://github.com/rubocop-hq/rubocop/issues/8897): Change `Style/StringConcatenation` to accept line-end concatenation between two strings so that `Style/LineEndConcatenation` can handle it instead. ([@dvandersluis][])

config/default.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4347,6 +4347,7 @@ Style/StringConcatenation:
43474347
Enabled: true
43484348
Safe: false
43494349
VersionAdded: '0.89'
4350+
VersionChanged: <<next>>
43504351

43514352
Style/StringHashKeys:
43524353
Description: 'Prefer symbols instead of strings as hash keys.'

lib/rubocop/cop/style/string_concatenation.rb

+19
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ module Style
1111
# In those cases, it might be useful to extract statements to local
1212
# variables or methods which you can then interpolate in a string.
1313
#
14+
# NOTE: When concatenation between two strings is broken over multiple
15+
# lines, this cop does not register an offense; instead,
16+
# `Style/LineEndConcatenation` will pick up the offense if enabled.
17+
#
1418
# @example
1519
# # bad
1620
# email_with_name = user.name + ' <' + user.email + '>'
@@ -19,6 +23,10 @@ module Style
1923
# email_with_name = "#{user.name} <#{user.email}>"
2024
# email_with_name = format('%s <%s>', user.name, user.email)
2125
#
26+
# # accepted, line-end concatenation
27+
# name = 'First' +
28+
# 'Last'
29+
#
2230
class StringConcatenation < Base
2331
include Util
2432
extend AutoCorrector
@@ -39,6 +47,7 @@ def on_new_investigation
3947

4048
def on_send(node)
4149
return unless string_concatenation?(node)
50+
return if line_end_concatenation?(node)
4251

4352
topmost_plus_node = find_topmost_plus_node(node)
4453

@@ -58,6 +67,16 @@ def on_send(node)
5867

5968
private
6069

70+
def line_end_concatenation?(node)
71+
# If the concatenation happens at the end of the line,
72+
# and both the receiver and argument are strings, allow
73+
# `Style/LineEndConcatenation` to handle it instead.
74+
node.receiver.str_type? &&
75+
node.first_argument.str_type? &&
76+
node.multiline? &&
77+
node.source =~ /\+\s*\n/
78+
end
79+
6180
def find_topmost_plus_node(node)
6281
current = node
6382
while (parent = current.parent) && plus_node?(parent)

spec/rubocop/cop/style/string_concatenation_spec.rb

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@
5555
end
5656

5757
context 'multiline' do
58+
context 'string continuation' do
59+
it 'does not register an offense' do
60+
# handled by `Style/LineEndConcatenation` instead.
61+
expect_no_offenses(<<~RUBY)
62+
"this is a long string " +
63+
"this is a continuation"
64+
RUBY
65+
end
66+
end
67+
5868
context 'simple expressions' do
5969
it 'registers an offense and corrects' do
6070
expect_offense(<<-RUBY)

0 commit comments

Comments
 (0)