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