From 433b8b56bbc339963e491dad41c24b2750044784 Mon Sep 17 00:00:00 2001 From: Owen Stephens Date: Thu, 4 Jun 2020 09:07:43 +0100 Subject: [PATCH 1/3] Add RegexpNode regopt predicates As suggested by @bbatsov here: https://github.com/rubocop-hq/rubocop/pull/8073#discussion_r433131081 --- lib/rubocop/ast/node/regexp_node.rb | 26 +++++++ spec/rubocop/ast/regexp_node_spec.rb | 104 +++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/lib/rubocop/ast/node/regexp_node.rb b/lib/rubocop/ast/node/regexp_node.rb index dfa04c136..3a723061c 100644 --- a/lib/rubocop/ast/node/regexp_node.rb +++ b/lib/rubocop/ast/node/regexp_node.rb @@ -36,6 +36,32 @@ def content def interpolation? children.any?(&:begin_type?) end + + # @return [Bool] if regexp uses the multiline regopt + def multiline? + regopt_include?(:m) + end + + # @return [Bool] if regexp uses the extended regopt + def extended? + regopt_include?(:x) + end + + # @return [Bool] if regexp uses the ignore-case regopt + def ignore_case? + regopt_include?(:i) + end + + # @return [Bool] if regexp uses the no-encoding regopt + def no_encoding? + regopt_include?(:n) + end + + private + + def regopt_include?(option) + regopt.children.include?(option) + end end end end diff --git a/spec/rubocop/ast/regexp_node_spec.rb b/spec/rubocop/ast/regexp_node_spec.rb index e2d605eb0..6ce5a514f 100644 --- a/spec/rubocop/ast/regexp_node_spec.rb +++ b/spec/rubocop/ast/regexp_node_spec.rb @@ -160,4 +160,108 @@ it { expect(regexp_node.interpolation?).to eq(false) } end end + + describe '#multiline?' do + context 'with no options' do + let(:source) { '/x/' } + + it { expect(regexp_node.multiline?).to be(false) } + end + + context 'with other options' do + let(:source) { '/x/ix' } + + it { expect(regexp_node.multiline?).to be(false) } + end + + context 'with only m option' do + let(:source) { '/x/m' } + + it { expect(regexp_node.multiline?).to be(true) } + end + + context 'with m and other options' do + let(:source) { '/x/imx' } + + it { expect(regexp_node.multiline?).to be(true) } + end + end + + describe '#extended?' do + context 'with no options' do + let(:source) { '/x/' } + + it { expect(regexp_node.extended?).to be(false) } + end + + context 'with other options' do + let(:source) { '/x/im' } + + it { expect(regexp_node.extended?).to be(false) } + end + + context 'with only x option' do + let(:source) { '/x/x' } + + it { expect(regexp_node.extended?).to be(true) } + end + + context 'with x and other options' do + let(:source) { '/x/ixm' } + + it { expect(regexp_node.extended?).to be(true) } + end + end + + describe '#ignore_case?' do + context 'with no options' do + let(:source) { '/x/' } + + it { expect(regexp_node.ignore_case?).to be(false) } + end + + context 'with other options' do + let(:source) { '/x/xm' } + + it { expect(regexp_node.ignore_case?).to be(false) } + end + + context 'with only i option' do + let(:source) { '/x/i' } + + it { expect(regexp_node.ignore_case?).to be(true) } + end + + context 'with i and other options' do + let(:source) { '/x/xim' } + + it { expect(regexp_node.ignore_case?).to be(true) } + end + end + + describe '#no_encoding?' do + context 'with no options' do + let(:source) { '/x/' } + + it { expect(regexp_node.no_encoding?).to be(false) } + end + + context 'with other options' do + let(:source) { '/x/xm' } + + it { expect(regexp_node.no_encoding?).to be(false) } + end + + context 'with only n option' do + let(:source) { '/x/n' } + + it { expect(regexp_node.no_encoding?).to be(true) } + end + + context 'with n and other options' do + let(:source) { '/x/xnm' } + + it { expect(regexp_node.no_encoding?).to be(true) } + end + end end From 33f8a655e32a45485f442dcc8dbdc1dfa28369e1 Mon Sep 17 00:00:00 2001 From: Owen Stephens Date: Thu, 4 Jun 2020 09:14:15 +0100 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3eb678f..3e2a0ac93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### New features * [#4](https://github.com/rubocop-hq/rubocop-ast/issues/4): Add `interpolation?` for `RegexpNode`. ([@tejasbubane][]) +* [#20](https://github.com/rubocop-hq/rubocop-ast/pull/20): Add option predicates for `RegexpNode`. ([@owst][]) ## 0.0.3 (2020-05-15) @@ -28,3 +29,4 @@ * Gem extracted from RuboCop. ([@marcandre][]) [@marcandre]: https://github.com/marcandre +[@owst]: https://github.com/owst From 171955091cec7c57029f932c5f16b3cd874ffd33 Mon Sep 17 00:00:00 2001 From: Owen Stephens Date: Thu, 4 Jun 2020 14:57:06 +0100 Subject: [PATCH 3/3] fixup! Add RegexpNode regopt predicates --- lib/rubocop/ast/node/regexp_node.rb | 5 +++++ spec/rubocop/ast/regexp_node_spec.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/rubocop/ast/node/regexp_node.rb b/lib/rubocop/ast/node/regexp_node.rb index 3a723061c..783c8c698 100644 --- a/lib/rubocop/ast/node/regexp_node.rb +++ b/lib/rubocop/ast/node/regexp_node.rb @@ -52,6 +52,11 @@ def ignore_case? regopt_include?(:i) end + # @return [Bool] if regexp uses the single-interpolation regopt + def single_interpolation? + regopt_include?(:o) + end + # @return [Bool] if regexp uses the no-encoding regopt def no_encoding? regopt_include?(:n) diff --git a/spec/rubocop/ast/regexp_node_spec.rb b/spec/rubocop/ast/regexp_node_spec.rb index 6ce5a514f..f0b319bb8 100644 --- a/spec/rubocop/ast/regexp_node_spec.rb +++ b/spec/rubocop/ast/regexp_node_spec.rb @@ -264,4 +264,30 @@ it { expect(regexp_node.no_encoding?).to be(true) } end end + + describe '#single_interpolation?' do + context 'with no options' do + let(:source) { '/x/' } + + it { expect(regexp_node.single_interpolation?).to be(false) } + end + + context 'with other options' do + let(:source) { '/x/xm' } + + it { expect(regexp_node.single_interpolation?).to be(false) } + end + + context 'with only o option' do + let(:source) { '/x/o' } + + it { expect(regexp_node.single_interpolation?).to be(true) } + end + + context 'with o and other options' do + let(:source) { '/x/xom' } + + it { expect(regexp_node.single_interpolation?).to be(true) } + end + end end