From 40e456f031065a63e418c0673c046a4b1a851c1f Mon Sep 17 00:00:00 2001 From: fatkodima Date: Sun, 14 Jun 2020 15:36:50 +0300 Subject: [PATCH] Add `post_condition_loop?` and `loop?` for `Node` --- CHANGELOG.md | 2 ++ lib/rubocop/ast/node.rb | 10 ++++++++++ spec/rubocop/ast/for_node_spec.rb | 12 ++++++++++++ spec/rubocop/ast/until_node_spec.rb | 28 ++++++++++++++++++++++++++++ spec/rubocop/ast/while_node_spec.rb | 28 ++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66822baa3..90844a784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### New features +* [#36](https://github.com/rubocop-hq/rubocop-ast/pull/36): Add `post_condition_loop?` and `loop?` for `Node`. ([@fatkodima][]) * [#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][]) * [#11](https://github.com/rubocop-hq/rubocop-ast/issues/11): Add `argument_type?` method to make it easy to recognize argument nodes. ([@tejasbubane][]) @@ -32,3 +33,4 @@ [@marcandre]: https://github.com/marcandre [@owst]: https://github.com/owst +[@fatkodima]: https://github.com/fatkodima diff --git a/lib/rubocop/ast/node.rb b/lib/rubocop/ast/node.rb index 483ffc13f..bd1853bd9 100644 --- a/lib/rubocop/ast/node.rb +++ b/lib/rubocop/ast/node.rb @@ -44,6 +44,8 @@ class Node < Parser::AST::Node # rubocop:disable Metrics/ClassLength BASIC_CONDITIONALS = %i[if while until].freeze CONDITIONALS = [*BASIC_CONDITIONALS, :case].freeze + POST_CONDITION_LOOP_TYPES = %i[while_post until_post].freeze + LOOP_TYPES = (POST_CONDITION_LOOP_TYPES + %i[while until for]).freeze VARIABLES = %i[ivar gvar cvar lvar].freeze REFERENCES = %i[nth_ref back_ref].freeze KEYWORDS = %i[alias and break case class def defs defined? @@ -426,6 +428,14 @@ def conditional? CONDITIONALS.include?(type) end + def post_condition_loop? + POST_CONDITION_LOOP_TYPES.include?(type) + end + + def loop? + LOOP_TYPES.include?(type) + end + def keyword? return true if special_keyword? || send_type? && prefix_not? return false unless KEYWORDS.include?(type) diff --git a/spec/rubocop/ast/for_node_spec.rb b/spec/rubocop/ast/for_node_spec.rb index 94b84bb75..f41f794a8 100644 --- a/spec/rubocop/ast/for_node_spec.rb +++ b/spec/rubocop/ast/for_node_spec.rb @@ -60,4 +60,16 @@ it { expect(for_node.body.sym_type?).to be(true) } end + + describe '#post_condition_loop?' do + let(:source) { 'for foo in bar; baz; end' } + + it { expect(for_node.post_condition_loop?).to be_falsey } + end + + describe '#loop?' do + let(:source) { 'for foo in bar; baz; end' } + + it { expect(for_node.loop?).to be_truthy } + end end diff --git a/spec/rubocop/ast/until_node_spec.rb b/spec/rubocop/ast/until_node_spec.rb index e2d4679ad..a02881faf 100644 --- a/spec/rubocop/ast/until_node_spec.rb +++ b/spec/rubocop/ast/until_node_spec.rb @@ -42,4 +42,32 @@ it { expect(until_node.do?).to be_falsey } end end + + describe '#post_condition_loop?' do + context 'with a statement until' do + let(:source) { 'until foo; bar; end' } + + it { expect(until_node.post_condition_loop?).to be_falsey } + end + + context 'with a modifier until' do + let(:source) { 'begin foo; end until bar' } + + it { expect(until_node.post_condition_loop?).to be_truthy } + end + end + + describe '#loop?' do + context 'with a statement until' do + let(:source) { 'until foo; bar; end' } + + it { expect(until_node.loop?).to be_truthy } + end + + context 'with a modifier until' do + let(:source) { 'begin foo; end until bar' } + + it { expect(until_node.loop?).to be_truthy } + end + end end diff --git a/spec/rubocop/ast/while_node_spec.rb b/spec/rubocop/ast/while_node_spec.rb index 4933203b8..06449d166 100644 --- a/spec/rubocop/ast/while_node_spec.rb +++ b/spec/rubocop/ast/while_node_spec.rb @@ -42,4 +42,32 @@ it { expect(while_node.do?).to be_falsey } end end + + describe '#post_condition_loop?' do + context 'with a statement while' do + let(:source) { 'while foo; bar; end' } + + it { expect(while_node.post_condition_loop?).to be_falsey } + end + + context 'with a modifier while' do + let(:source) { 'begin foo; end while bar' } + + it { expect(while_node.post_condition_loop?).to be_truthy } + end + end + + describe '#loop?' do + context 'with a statement while' do + let(:source) { 'while foo; bar; end' } + + it { expect(while_node.loop?).to be_truthy } + end + + context 'with a modifier while' do + let(:source) { 'begin foo; end while bar' } + + it { expect(while_node.loop?).to be_truthy } + end + end end