Skip to content

Commit

Permalink
Add Node#type? to reduce complexity of checking against multiple no…
Browse files Browse the repository at this point in the history
…de types.
  • Loading branch information
dvandersluis authored and marcandre committed Nov 5, 2024
1 parent 3b9089c commit 510781f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_nodetype_to_reduce_complexity_of.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#329](https://github.com/rubocop/rubocop-ast/pull/329): Add `Node#type?` to reduce complexity of checking against multiple node types. ([@dvandersluis][])
10 changes: 10 additions & 0 deletions lib/rubocop/ast/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ def initialize(type, children = EMPTY_CHILDREN, properties = EMPTY_PROPERTIES)
end
end

# Determine if the node is one of several node types in a single query
# Allows specific single node types, as well as "grouped" types
# (e.g. `:boolean` for `:true` or `:false`)
def type?(*types)
return true if types.include?(type)

group_type = GROUP_FOR_TYPE[type]
!group_type.nil? && types.include?(group_type)
end

(Parser::Meta::NODE_TYPES - [:send]).each do |node_type|
method_name = "#{node_type.to_s.gsub(/\W/, '')}_type?"
class_eval <<~RUBY, __FILE__, __LINE__ + 1
Expand Down
61 changes: 61 additions & 0 deletions spec/rubocop/ast/node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1048,4 +1048,65 @@ class << expr
end
end
end

describe '#type?' do
let(:src) do
<<~RUBY
foo.bar
RUBY
end

context 'when it is one of the given types' do
it 'is true' do
expect(node).to be_type(:send, :const, :lvar)
end
end

context 'when it is not one of the given types' do
it 'is false' do
expect(node).not_to be_type(:if, :while, :until)
end
end

context 'when given :argument with an `arg` node' do
let(:src) { 'foo { |>> var <<| } ' }

it 'is true' do
arg_node = ast.procarg0_type? ? ast.child_nodes.first : node
expect(arg_node).to be_type(:argument)
end
end

context 'when given :boolean with an `true` node' do
let(:src) { 'true' }

it 'is true' do
expect(node).to be_type(:boolean)
end
end

context 'when given :numeric with an `int` node' do
let(:src) { '42' }

it 'is true' do
expect(node).to be_type(:numeric)
end
end

context 'when given :range with an `irange` node' do
let(:src) { '1..3' }

it 'is true' do
expect(node).to be_type(:range)
end
end

context 'when given :call with an `send` node' do
let(:src) { 'foo.bar' }

it 'is true' do
expect(node).to be_type(:call)
end
end
end
end

0 comments on commit 510781f

Please sign in to comment.