diff --git a/changelog/fix_false_range_for_lint_redundant_cop_disable_directive.md b/changelog/fix_false_range_for_lint_redundant_cop_disable_directive.md new file mode 100644 index 00000000000..95a1a727974 --- /dev/null +++ b/changelog/fix_false_range_for_lint_redundant_cop_disable_directive.md @@ -0,0 +1 @@ +* [#9822](https://github.com/rubocop/rubocop/issues/9822): Fix a false directive comment range for `Lint/RedundantCopDisableDirective`. ([@koic][]) diff --git a/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb b/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb index 8fe1d132b87..574b08a3336 100644 --- a/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +++ b/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb @@ -60,16 +60,19 @@ def previous_line_blank?(range) processed_source.buffer.source_line(range.line - 1).blank? end - def comment_range_with_surrounding_space(range) - if previous_line_blank?(range) && - processed_source.comment_config.comment_only_line?(range.line) + def comment_range_with_surrounding_space(directive_comment_range, line_comment_range) + if previous_line_blank?(directive_comment_range) && + processed_source.comment_config.comment_only_line?(directive_comment_range.line) && + directive_comment_range.begin_pos == line_comment_range.begin_pos # When the previous line is blank, it should be retained - range_with_surrounding_space(range: range, side: :right) + range_with_surrounding_space(range: directive_comment_range, side: :right) else # Eat the entire comment, the preceding space, and the preceding # newline if there is one. - original_begin = range.begin_pos - range = range_with_surrounding_space(range: range, side: :left, newlines: true) + original_begin = directive_comment_range.begin_pos + range = range_with_surrounding_space( + range: directive_comment_range, side: :left, newlines: true + ) range_with_surrounding_space(range: range, side: :right, @@ -179,14 +182,14 @@ def add_offenses(redundant_cops) end def add_offense_for_entire_comment(comment, cops) - location = comment.loc.expression + location = DirectiveComment.new(comment).range cop_list = cops.sort.map { |c| describe(c) } add_offense( location, message: "Unnecessary disabling of #{cop_list.join(', ')}." ) do |corrector| - range = comment_range_with_surrounding_space(location) + range = comment_range_with_surrounding_space(location, comment.loc.expression) corrector.remove(range) end end diff --git a/lib/rubocop/directive_comment.rb b/lib/rubocop/directive_comment.rb index 024dfbf7677..45c28da8fe4 100644 --- a/lib/rubocop/directive_comment.rb +++ b/lib/rubocop/directive_comment.rb @@ -41,7 +41,11 @@ def match?(cop_names) end def range - comment.location.expression + match = comment.text.match(DIRECTIVE_COMMENT_REGEXP) + begin_pos = comment.loc.expression.begin_pos + Parser::Source::Range.new( + comment.loc.expression.source_buffer, begin_pos + match.begin(0), begin_pos + match.end(0) + ) end # Returns match captures to directive comment pattern diff --git a/spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb b/spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb index b2374ba2570..9da3333cc1d 100644 --- a/spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb +++ b/spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb @@ -42,6 +42,19 @@ end end + context 'when using a directive comment after a non-directive comment' do + it 'returns an offense' do + expect_offense(<<~RUBY) + # not very long comment # rubocop:disable Layout/LineLength + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Layout/LineLength`. + RUBY + + expect_correction(<<~RUBY) + # not very long comment + RUBY + end + end + context 'itself and another cop' do context 'disabled on the same range' do it 'returns no offense' do