From 3bcfb9373d8e7df8bcfe6fbe67018afeca0208ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20B=C3=BChmann?= Date: Wed, 18 Dec 2019 20:42:38 +0100 Subject: [PATCH] [Fix #7193] Fix string_source for symbol case (%i) This actually follows up on https://github.com/rubocop-hq/rubocop/pull/5020 --- CHANGELOG.md | 4 ++++ .../cop/style/percent_literal_delimiters.rb | 14 +++++++------- .../cop/style/percent_literal_delimiters_spec.rb | 5 +++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66c621f5595..21fe49366f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### Bug fixes + +* [#7193](https://github.com/rubocop-hq/rubocop/issues/7193): Prevent `Style/PercentLiteralDelimiters` from changing `%i` literals that contain escaped delimiters. ([@buehmann][]) + ## 0.78.0 (2019-12-18) ### New features diff --git a/lib/rubocop/cop/style/percent_literal_delimiters.rb b/lib/rubocop/cop/style/percent_literal_delimiters.rb index e075ecb06d0..8896456817a 100644 --- a/lib/rubocop/cop/style/percent_literal_delimiters.rb +++ b/lib/rubocop/cop/style/percent_literal_delimiters.rb @@ -88,27 +88,27 @@ def uses_preferred_delimiter?(node, type) end def contains_preferred_delimiter?(node, type) - preferred_delimiters = preferred_delimiters_for(type) - node - .children.map { |n| string_source(n) }.compact - .any? { |s| preferred_delimiters.any? { |d| s.include?(d) } } + contains_delimiter?(node, preferred_delimiters_for(type)) end def include_same_character_as_used_for_delimiter?(node, type) return false unless %w[%w %i].include?(type) used_delimiters = matchpairs(begin_source(node)[-1]) - escaped_delimiters = used_delimiters.map { |d| "\\#{d}" }.join('|') + contains_delimiter?(node, used_delimiters) + end + def contains_delimiter?(node, delimiters) + delimiters_regexp = Regexp.union(delimiters) node .children.map { |n| string_source(n) }.compact - .any? { |s| Regexp.new(escaped_delimiters) =~ s } + .any? { |s| delimiters_regexp =~ s } end def string_source(node) if node.is_a?(String) node - elsif node.respond_to?(:type) && node.str_type? + elsif node.respond_to?(:type) && (node.str_type? || node.sym_type?) node.source end end diff --git a/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb b/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb index b4f632dbfc1..852da34b970 100644 --- a/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +++ b/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb @@ -200,6 +200,11 @@ expect_no_offenses('%i[some symbols]') end + it 'does not register an offense for non-preferred delimiters ' \ + 'enclosing escaped delimiters' do + expect_no_offenses('%i(\(\) each)') + end + it 'registers an offense for other delimiters' do expect_offense(<<~RUBY) %i(some symbols)