From 71076f53d00b76b7b276d2e57bf58d2476cf8b6b Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Wed, 8 Jun 2022 05:56:03 +0900 Subject: [PATCH] [Fix #10693] Add ignore case for `Style/EmptyLinesAroundAttributeAccessor` when there is a comment line on the next line. --- ...r_empty_lines_around_attribute_accessor.md | 1 + .../empty_lines_around_attribute_accessor.rb | 29 +++- ...ty_lines_around_attribute_accessor_spec.rb | 149 +++++++++++++++++- 3 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 changelog/change_add_ignore_case_for_empty_lines_around_attribute_accessor.md diff --git a/changelog/change_add_ignore_case_for_empty_lines_around_attribute_accessor.md b/changelog/change_add_ignore_case_for_empty_lines_around_attribute_accessor.md new file mode 100644 index 00000000000..91567a9ca9e --- /dev/null +++ b/changelog/change_add_ignore_case_for_empty_lines_around_attribute_accessor.md @@ -0,0 +1 @@ +* [#10693](https://github.com/rubocop/rubocop/issues/10693): Add ignore case for `Style/EmptyLinesAroundAttributeAccessor` when there is a comment line on the next line. ([@ydah][]) diff --git a/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb b/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb index 9e4d6fc0e06..9ca43f61a16 100644 --- a/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +++ b/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb @@ -70,18 +70,39 @@ class EmptyLinesAroundAttributeAccessor < Base def on_send(node) return unless node.attribute_accessor? return if next_line_empty?(node.last_line) + return if next_line_empty_or_enable_directive_comment?(node.last_line) next_line_node = next_line_node(node) return unless require_empty_line?(next_line_node) - add_offense(node) do |corrector| - range = range_by_whole_lines(node.source_range) + add_offense(node) { |corrector| autocorrect(corrector, node) } + end + + private - corrector.insert_after(range, "\n") + def autocorrect(corrector, node) + node_range = range_by_whole_lines(node.source_range) + + next_line = node_range.last_line + 1 + if next_line_enable_directive_comment?(next_line) + node_range = processed_source.comment_at_line(next_line) end + + corrector.insert_after(node_range, "\n") end - private + def next_line_empty_or_enable_directive_comment?(line) + return true if next_line_empty?(line) + + next_line = line + 1 + next_line_enable_directive_comment?(next_line) && next_line_empty?(next_line) + end + + def next_line_enable_directive_comment?(line) + return false unless (comment = processed_source.comment_at_line(line)) + + DirectiveComment.new(comment).enabled? + end def next_line_empty?(line) processed_source[line].nil? || processed_source[line].blank? diff --git a/spec/rubocop/cop/layout/empty_lines_around_attribute_accessor_spec.rb b/spec/rubocop/cop/layout/empty_lines_around_attribute_accessor_spec.rb index 7baaf12928a..8151bdb6046 100644 --- a/spec/rubocop/cop/layout/empty_lines_around_attribute_accessor_spec.rb +++ b/spec/rubocop/cop/layout/empty_lines_around_attribute_accessor_spec.rb @@ -33,7 +33,130 @@ def do_something RUBY end - it 'accepts code that separates a attribute accessor from the code with a newline' do + it 'registers an offense and corrects for an attribute accessor and comment line' do + expect_offense(<<~RUBY) + attr_accessor :foo + ^^^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # comment + def do_something + end + RUBY + + expect_correction(<<~RUBY) + attr_accessor :foo + + # comment + def do_something + end + RUBY + end + + it 'registers an offense and corrects for some attribute accessors and comment line' do + expect_offense(<<~RUBY) + attr_accessor :foo + attr_reader :bar + attr_writer :baz + ^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # comment + def do_something + end + RUBY + + expect_correction(<<~RUBY) + attr_accessor :foo + attr_reader :bar + attr_writer :baz + + # comment + def do_something + end + RUBY + end + + it 'registers an offense and corrects for an attribute accessor and some comment line' do + expect_offense(<<~RUBY) + attr_accessor :foo + ^^^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # comment + # comment + def do_something + end + RUBY + + expect_correction(<<~RUBY) + attr_accessor :foo + + # comment + # comment + def do_something + end + RUBY + end + + it 'registers an offense and corrects for an attribute accessor and `rubocop:disable` ' \ + 'comment line' do + expect_offense(<<~RUBY) + attr_accessor :foo + ^^^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # rubocop:disable Department/Cop + def do_something + end + RUBY + + expect_correction(<<~RUBY) + attr_accessor :foo + + # rubocop:disable Department/Cop + def do_something + end + RUBY + end + + it 'registers an offense and corrects for an attribute accessor and `rubocop:enable` ' \ + 'comment line' do + expect_offense(<<~RUBY) + # rubocop:disable Department/Cop + attr_accessor :foo + ^^^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # rubocop:enable Department/Cop + def do_something + end + RUBY + + expect_correction(<<~RUBY) + # rubocop:disable Department/Cop + attr_accessor :foo + # rubocop:enable Department/Cop + + def do_something + end + RUBY + end + + it 'registers an offense and corrects for an attribute accessor and `rubocop:enable` ' \ + 'comment line and other comment' do + expect_offense(<<~RUBY) + # rubocop:disable Department/Cop + attr_accessor :foo + ^^^^^^^^^^^^^^^^^^ Add an empty line after attribute accessor. + # rubocop:enable Department/Cop + # comment + def do_something + end + RUBY + + expect_correction(<<~RUBY) + # rubocop:disable Department/Cop + attr_accessor :foo + # rubocop:enable Department/Cop + + # comment + def do_something + end + RUBY + end + + it 'accepts code that separates an attribute accessor from the code with a newline' do expect_no_offenses(<<~RUBY) attr_accessor :foo @@ -42,6 +165,18 @@ def do_something RUBY end + it 'accepts code that separates an attribute accessor from the code and `rubocop:enable` ' \ + 'comment line with a newline' do + expect_no_offenses(<<~RUBY) + # rubocop:disable Department/Cop + attr_accessor :foo + # rubocop:enable Department/Cop + + def do_something + end + RUBY + end + it 'accepts code that where the attr_accessor is the last line' do expect_no_offenses('attr_accessor :foo') end @@ -57,6 +192,18 @@ def do_something RUBY end + it 'accepts code that separates attribute accessors from the code and comment line with a newline' do + expect_no_offenses(<<~RUBY) + attr_accessor :foo + attr_reader :bar + attr_writer :baz + + # comment + def do_something + end + RUBY + end + it 'accepts code when used in class definition' do expect_no_offenses(<<~RUBY) class Foo