Skip to content

Commit

Permalink
Add delimiters' and related predicates for RegexpNode` (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
owst committed Jun 22, 2020
1 parent 2817ae4 commit 41306ed
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@
* [#20](https://github.com/rubocop-hq/rubocop-ast/pull/20): Add option predicates for `RegexpNode`. ([@owst][])
* [#11](https://github.com/rubocop-hq/rubocop-ast/issues/11): Add `argument_type?` method to make it easy to recognize argument nodes. ([@tejasbubane][])
* [#31](https://github.com/rubocop-hq/rubocop-ast/pull/31): Use `param === node` to match params, which allows Regexp, Proc, Set, etc. ([@marcandre][])
* [#41](https://github.com/rubocop-hq/rubocop-ast/pull/41): Add `delimiters` and related predicates for `RegexpNode`. ([@owst][])

## 0.0.3 (2020-05-15)

Expand Down
20 changes: 20 additions & 0 deletions lib/rubocop/ast/node/regexp_node.rb
Expand Up @@ -32,6 +32,26 @@ def content
children.select(&:str_type?).map(&:str_content).join
end

# @return [Bool] if the regexp is a /.../ literal
def slash_literal?
loc.begin.source == '/'
end

# @return [Bool] if the regexp is a %r{...} literal (using any delimiters)
def percent_r_literal?
!slash_literal?
end

# @return [String] the regexp delimiters (without %r)
def delimiters
[loc.begin.source[-1], loc.end.source[0]]
end

# @return [Bool] if char is one of the delimiters
def delimiter?(char)
delimiters.include?(char)
end

# @return [Bool] if regexp contains interpolation
def interpolation?
children.any?(&:begin_type?)
Expand Down
188 changes: 188 additions & 0 deletions spec/rubocop/ast/regexp_node_spec.rb
Expand Up @@ -141,6 +141,194 @@
end
end

describe '#slash_literal?' do
context 'with /-delimiters' do
let(:source) { '/abc/' }

it { expect(regexp_node.slash_literal?).to eq(true) }
end

context 'with %r/-delimiters' do
let(:source) { '%r/abc/' }

it { expect(regexp_node.slash_literal?).to eq(false) }
end

context 'with %r{-delimiters' do
let(:source) { '%r{abc}' }

it { expect(regexp_node.slash_literal?).to eq(false) }
end

context 'with multi-line %r{-delimiters' do
let(:source) do
<<~SRC
%r{
abc
}x
SRC
end

it { expect(regexp_node.slash_literal?).to eq(false) }
end

context 'with %r<-delimiters' do
let(:source) { '%r<abc>x' }

it { expect(regexp_node.slash_literal?).to eq(false) }
end
end

describe '#percent_r_literal?' do
context 'with /-delimiters' do
let(:source) { '/abc/' }

it { expect(regexp_node.percent_r_literal?).to eq(false) }
end

context 'with %r/-delimiters' do
let(:source) { '%r/abc/' }

it { expect(regexp_node.percent_r_literal?).to eq(true) }
end

context 'with %r{-delimiters' do
let(:source) { '%r{abc}' }

it { expect(regexp_node.percent_r_literal?).to eq(true) }
end

context 'with multi-line %r{-delimiters' do
let(:source) do
<<~SRC
%r{
abc
}x
SRC
end

it { expect(regexp_node.percent_r_literal?).to eq(true) }
end

context 'with %r<-delimiters' do
let(:source) { '%r<abc>x' }

it { expect(regexp_node.percent_r_literal?).to eq(true) }
end
end

describe '#delimiters' do
context 'with /-delimiters' do
let(:source) { '/abc/' }

it { expect(regexp_node.delimiters).to eq(['/', '/']) }
end

context 'with %r/-delimiters' do
let(:source) { '%r/abc/' }

it { expect(regexp_node.delimiters).to eq(['/', '/']) }
end

context 'with %r{-delimiters' do
let(:source) { '%r{abc}' }

it { expect(regexp_node.delimiters).to eq(['{', '}']) }
end

context 'with multi-line %r{-delimiters' do
let(:source) do
<<~SRC
%r{
abc
}x
SRC
end

it { expect(regexp_node.delimiters).to eq(['{', '}']) }
end

context 'with %r<-delimiters' do
let(:source) { '%r<abc>x' }

it { expect(regexp_node.delimiters).to eq(['<', '>']) }
end
end

describe '#delimiter?' do
context 'with /-delimiters' do
let(:source) { '/abc/' }

it { expect(regexp_node.delimiter?('/')).to eq(true) }

it { expect(regexp_node.delimiter?('{')).to eq(false) }
end

context 'with %r/-delimiters' do
let(:source) { '%r/abc/' }

it { expect(regexp_node.delimiter?('/')).to eq(true) }

it { expect(regexp_node.delimiter?('{')).to eq(false) }
it { expect(regexp_node.delimiter?('}')).to eq(false) }
it { expect(regexp_node.delimiter?('%')).to eq(false) }
it { expect(regexp_node.delimiter?('r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r/')).to eq(false) }
end

context 'with %r{-delimiters' do
let(:source) { '%r{abc}' }

it { expect(regexp_node.delimiter?('{')).to eq(true) }
it { expect(regexp_node.delimiter?('}')).to eq(true) }

it { expect(regexp_node.delimiter?('/')).to eq(false) }
it { expect(regexp_node.delimiter?('%')).to eq(false) }
it { expect(regexp_node.delimiter?('r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r/')).to eq(false) }
it { expect(regexp_node.delimiter?('%r{')).to eq(false) }
end

context 'with multi-line %r{-delimiters' do
let(:source) do
<<~SRC
%r{
abc
}x
SRC
end

it { expect(regexp_node.delimiter?('{')).to eq(true) }
it { expect(regexp_node.delimiter?('}')).to eq(true) }

it { expect(regexp_node.delimiter?('/')).to eq(false) }
it { expect(regexp_node.delimiter?('%')).to eq(false) }
it { expect(regexp_node.delimiter?('r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r/')).to eq(false) }
it { expect(regexp_node.delimiter?('%r{')).to eq(false) }
end

context 'with %r<-delimiters' do
let(:source) { '%r<abc>x' }

it { expect(regexp_node.delimiter?('<')).to eq(true) }
it { expect(regexp_node.delimiter?('>')).to eq(true) }

it { expect(regexp_node.delimiter?('{')).to eq(false) }
it { expect(regexp_node.delimiter?('}')).to eq(false) }
it { expect(regexp_node.delimiter?('/')).to eq(false) }
it { expect(regexp_node.delimiter?('%')).to eq(false) }
it { expect(regexp_node.delimiter?('r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r')).to eq(false) }
it { expect(regexp_node.delimiter?('%r/')).to eq(false) }
it { expect(regexp_node.delimiter?('%r{')).to eq(false) }
it { expect(regexp_node.delimiter?('%r<')).to eq(false) }
end
end

describe '#interpolation?' do
context 'with direct variable interpoation' do
let(:source) { '/\n\n#{foo}(abc)+/' }
Expand Down

0 comments on commit 41306ed

Please sign in to comment.