diff --git a/CHANGELOG.md b/CHANGELOG.md index a5de8c081..b3ea4888d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ ### New features * [#50](https://github.com/rubocop-hq/rubocop-ast/pull/50): Support find pattern matching for Ruby 2.8 (3.0) parser. ([@koic][]) +* [#55](https://github.com/rubocop-hq/rubocop-ast/pull/55): Add `ProcessedSource#line_with_comment?`. ([@marcandre][]) + +### Bug fixes + +* [#55](https://github.com/rubocop-hq/rubocop-ast/pull/55): Fix `ProcessedSource#commented?` for multi-line ranges. Renamed `contains_comment?` ([@marcandre][]) ## 0.1.0 (2020-06-26) diff --git a/lib/rubocop/ast/processed_source.rb b/lib/rubocop/ast/processed_source.rb index 212ccd1c5..21cc7dccf 100644 --- a/lib/rubocop/ast/processed_source.rb +++ b/lib/rubocop/ast/processed_source.rb @@ -95,10 +95,20 @@ def blank? ast.nil? end - def commented?(source_range) - comment_lines.include?(source_range.line) + # @return [Boolean] if the given line number has a comment. + def line_with_comment?(line) + comment_lines.include?(line) end + # @return [Boolean] if any of the lines in the given `source_range` has a comment. + def contains_comment?(source_range) + (source_range.line..source_range.last_line).any? do |line| + line_with_comment?(line) + end + end + # @deprecated use contains_comment? + alias commented? contains_comment? + def comments_before_line(line) comments.select { |c| c.location.line <= line } end diff --git a/spec/rubocop/ast/processed_source_spec.rb b/spec/rubocop/ast/processed_source_spec.rb index 4fba7e818..dbc7a4cae 100644 --- a/spec/rubocop/ast/processed_source_spec.rb +++ b/spec/rubocop/ast/processed_source_spec.rb @@ -251,25 +251,64 @@ def foo # comment one end end - describe '#commented?' do - subject(:commented) { processed_source.commented?(range) } + describe '#line_with_comment?' do + let(:source) { <<~RUBY } + # comment + [ + 1, # comment + 2 + ] + RUBY + + it 'returns true for lines with comments' do + expect(processed_source.line_with_comment?(1)).to be true + expect(processed_source.line_with_comment?(3)).to be true + end + + it 'returns false for lines without comments' do + expect(processed_source.line_with_comment?(2)).to be false + expect(processed_source.line_with_comment?(4)).to be false + end + end + + describe '#contains_comment?' do + subject(:commented) { processed_source.contains_comment?(range) } let(:source) { <<~RUBY } # comment - [ 1, 2 ] + [ 1, + { a: 2, + b: 3 # comment + } + ] RUBY + let(:ast) { processed_source.ast } + let(:array) { ast } + let(:hash) { array.children[1] } context 'provided source_range on line without comment' do - let(:range) { processed_source.find_token(&:left_bracket?).pos } + let(:range) { hash.pairs.first.loc.expression } it { is_expected.to be false } end - context 'provided source_range on line with comment' do + context 'provided source_range on comment line' do let(:range) { processed_source.find_token(&:comment?).pos } it { is_expected.to be true } end + + context 'provided source_range on line with comment' do + let(:range) { hash.pairs.last.loc.expression } + + it { is_expected.to be true } + end + + context 'provided a multiline source_range with at least one line with comment' do + let(:range) { array.loc.expression } + + it { is_expected.to be true } + end end describe '#comments_before_line' do