diff --git a/CHANGELOG.md b/CHANGELOG.md index cc31bcda5..cd78232aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### New features + +* [#XXXX](https://github.com/rubocop-hq/rubocop-ast/pull/XXXX): Add `RegexpNode#options`. ([@owst][]) + ## 0.5.1 (2020-09-25) ### Bug fixes diff --git a/lib/rubocop/ast/node/regexp_node.rb b/lib/rubocop/ast/node/regexp_node.rb index 2b621ad90..15eaca964 100644 --- a/lib/rubocop/ast/node/regexp_node.rb +++ b/lib/rubocop/ast/node/regexp_node.rb @@ -14,12 +14,9 @@ class RegexpNode < Node o: 0 }.freeze - # Note: The 'o' option is ignored. - # # @return [Regexp] a regexp of this node def to_regexp - option = regopt.children.map { |opt| OPTIONS.fetch(opt) }.inject(:|) - Regexp.new(content, option) + Regexp.new(content, options) end # @return [RuboCop::AST::Node] a regopt node @@ -27,6 +24,13 @@ def regopt children.last end + # Note: The 'o' option is ignored. + # + # @return [Integer] the Regexp option bits as returned by Regexp#options + def options + regopt.children.map { |opt| OPTIONS.fetch(opt) }.inject(0, :|) + end + # @return [String] a string of regexp content def content children.select(&:str_type?).map(&:str_content).join diff --git a/spec/rubocop/ast/regexp_node_spec.rb b/spec/rubocop/ast/regexp_node_spec.rb index 8a9a0bbb3..d995a72c5 100644 --- a/spec/rubocop/ast/regexp_node_spec.rb +++ b/spec/rubocop/ast/regexp_node_spec.rb @@ -101,6 +101,43 @@ end end + describe '#options' do + let(:actual_options) { regexp_node.options } + # rubocop:disable Security/Eval + let(:expected_options) { eval(source).options } + # rubocop:enable Security/Eval + + context 'with an empty regexp' do + let(:source) { '//' } + + it { expect(actual_options).to eq(expected_options) } + end + + context 'with a regexp without option' do + let(:source) { '/.+/' } + + it { expect(actual_options).to eq(expected_options) } + end + + context 'with a regexp with single option' do + let(:source) { '/.+/i' } + + it { expect(actual_options).to eq(expected_options) } + end + + context 'with a regexp with multiple options' do + let(:source) { '/.+/ix' } + + it { expect(actual_options).to eq(expected_options) } + end + + context 'with a regexp with "o" option' do + let(:source) { '/.+/o' } + + it { expect(actual_options).to eq(expected_options) } + end + end + describe '#content' do let(:content) { regexp_node.content }