lib/rubocop/cop/style/line_end_concatenation.rb in rubocop-0.21.0 vs lib/rubocop/cop/style/line_end_concatenation.rb in rubocop-0.22.0
- old
+ new
@@ -18,11 +18,11 @@
# # good
# some_str = 'ala' \
# 'bala'
#
class LineEndConcatenation < Cop
- MSG = 'Use \\ instead of + or << to concatenate those strings.'
+ MSG = 'Use `\\` instead of `+` or `<<` to concatenate those strings.'
def on_send(node)
add_offense(node, :selector) if offending_node?(node)
end
@@ -33,19 +33,22 @@
end
end
private
+ def concat?(method)
+ [:+, :<<].include?(method)
+ end
+
def offending_node?(node)
- receiver, method, arg = *node
+ receiver, method, first_arg = *node
- # TODO: Report Emacs bug.
- return false unless [:+, :<<].include?(method)
+ return false unless concat?(method)
- return false unless string_type?(receiver)
+ return false unless final_node_is_string_type?(receiver)
- return false unless string_type?(arg)
+ return false unless root_node_is_string_type?(first_arg)
expression = node.loc.expression.source
concatenator_at_line_end?(expression)
end
@@ -54,12 +57,32 @@
expression =~ /.+(\+|<<)\s*$/
end
def string_type?(node)
return false unless [:str, :dstr].include?(node.type)
+ # strings like __FILE__ are of no interest
+ return false unless node.loc.respond_to?(:begin)
# we care only about quotes-delimited literals
node.loc.begin && ["'", '"'].include?(node.loc.begin.source)
+ end
+
+ def final_node_is_string_type?(node)
+ if node.type == :send
+ _, method, first_arg = *node
+ concat?(method) && final_node_is_string_type?(first_arg)
+ else
+ string_type?(node)
+ end
+ end
+
+ def root_node_is_string_type?(node)
+ if node.type == :send
+ receiver, method, _ = *node
+ concat?(method) && root_node_is_string_type?(receiver)
+ else
+ string_type?(node)
+ end
end
end
end
end
end