Skip to content

Commit

Permalink
[Fix #7193] Fix string_source for symbol case (%i)
Browse files Browse the repository at this point in the history
This actually follows up on #5020
  • Loading branch information
buehmann authored and bbatsov committed Dec 21, 2019
1 parent 3d63f19 commit 3bcfb93
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions lib/rubocop/cop/style/percent_literal_delimiters.rb
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions spec/rubocop/cop/style/percent_literal_delimiters_spec.rb
Expand Up @@ -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)
Expand Down

0 comments on commit 3bcfb93

Please sign in to comment.