From 2d7ec2d02defc1c2ddce7d53f0de7f9ddef67474 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 21 Jul 2020 12:29:43 -0400 Subject: [PATCH] Add `ProcessedSource#each_comment_in_lines` Deprecate `ProcessedSource#comments_before_line` --- CHANGELOG.md | 1 + lib/rubocop/ast/processed_source.rb | 22 +++++++++++++++++----- spec/rubocop/ast/processed_source_spec.rb | 9 +++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4504f34fb..04e1aaf94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [#70](https://github.com/rubocop-hq/rubocop-ast/pull/70): Add `NextNode` ([@marcandre][]) * [#83](https://github.com/rubocop-hq/rubocop-ast/pull/83): Add `ProcessedSource#comment_at_line` ([@marcandre][]) +* [#83](https://github.com/rubocop-hq/rubocop-ast/pull/83): Add `ProcessedSource#each_comment_in_lines` ([@marcandre][]) ### Bug fixes diff --git a/lib/rubocop/ast/processed_source.rb b/lib/rubocop/ast/processed_source.rb index e2d2232c8..9c329a8c9 100644 --- a/lib/rubocop/ast/processed_source.rb +++ b/lib/rubocop/ast/processed_source.rb @@ -76,7 +76,7 @@ def each_comment comments.each { |comment| yield comment } end - # @deprecated Use `comments.find` or `comment_at_line` + # @deprecated Use `comment_at_line`, `each_comment_in_lines`, or `comments.find` def find_comment comments.find { |comment| yield comment } end @@ -109,17 +109,29 @@ def line_with_comment?(line) comment_index.include?(line) end + # Enumerates on the comments contained with the given `line_range` + def each_comment_in_lines(line_range) + return to_enum(:each_comment_in_lines, line_range) unless block_given? + + line_range.each do |line| + if (comment = comment_index[line]) + yield comment + end + end + end + # @return [Boolean] if any of the lines in the given `source_range` has a comment. + # Consider using `each_comment_in_lines` instead def contains_comment?(source_range) - (source_range.line..source_range.last_line).any? do |line| - line_with_comment?(line) - end + each_comment_in_lines(source_range.line..source_range.last_line).any? end # @deprecated use contains_comment? alias commented? contains_comment? + # @deprecated Use `each_comment_in_lines` + # Should have been called `comments_before_or_at_line`. Doubtful it has of any valid use. def comments_before_line(line) - comments.select { |c| c.location.line <= line } + each_comment_in_lines(0..line).to_a end def start_with?(string) diff --git a/spec/rubocop/ast/processed_source_spec.rb b/spec/rubocop/ast/processed_source_spec.rb index cefb77961..9d9bf57d9 100644 --- a/spec/rubocop/ast/processed_source_spec.rb +++ b/spec/rubocop/ast/processed_source_spec.rb @@ -268,6 +268,15 @@ def some_method end end + describe '#each_comment_in_lines' do + it 'yields the comments' do + enum = processed_source.each_comment_in_lines(1..4) + expect(enum.is_a?(Enumerable)).to be(true) + expect(enum.to_a).to eq processed_source.comments + expect(processed_source.each_comment_in_lines(2..5).map(&:text)).to eq ['# comment two'] + end + end + describe '#line_with_comment?' do it 'returns true for lines with comments' do expect(processed_source.line_with_comment?(1)).to be true