diff --git a/changelog/fix_false_negative_when_nested_classes_has_private_or_protected_methods.md b/changelog/fix_false_negative_when_nested_classes_has_private_or_protected_methods.md new file mode 100644 index 0000000000..86e5d5ed8a --- /dev/null +++ b/changelog/fix_false_negative_when_nested_classes_has_private_or_protected_methods.md @@ -0,0 +1 @@ +* [#712](https://github.com/rubocop/rubocop-rails/issues/712): Fix false negative in `Rails/Delegate` when preceding nested class declares private or protected methods. ([@Darhazer][]) diff --git a/lib/rubocop/cop/rails/delegate.rb b/lib/rubocop/cop/rails/delegate.rb index df86aeb5d3..7bc8f27c08 100644 --- a/lib/rubocop/cop/rails/delegate.rb +++ b/lib/rubocop/cop/rails/delegate.rb @@ -54,6 +54,7 @@ module Rails # delegate :bar, to: :foo, prefix: true class Delegate < Base extend AutoCorrector + include VisibilityHelp MSG = 'Use `delegate` to define delegations.' @@ -112,17 +113,11 @@ def prefixed_method_name(body) end def private_or_protected_delegation(node) - line = node.first_line - private_or_protected_before(line) || - private_or_protected_inline(line) + private_or_protected_inline(node) || node_visibility(node) != :public end - def private_or_protected_before(line) - (processed_source[0..line].map(&:strip) & %w[private protected]).any? - end - - def private_or_protected_inline(line) - processed_source[line - 1].strip.match?(/\A(private )|(protected )/) + def private_or_protected_inline(node) + processed_source[node.first_line - 1].strip.match?(/\A(private )|(protected )/) end end end diff --git a/spec/rubocop/cop/rails/delegate_spec.rb b/spec/rubocop/cop/rails/delegate_spec.rb index 268804b6d0..5d7728aade 100644 --- a/spec/rubocop/cop/rails/delegate_spec.rb +++ b/spec/rubocop/cop/rails/delegate_spec.rb @@ -125,7 +125,7 @@ def fox bar.fox end - private + private def fox bar.fox @@ -147,6 +147,41 @@ def fox RUBY end + it 'works with private methods declared in inner classes' do + expect_offense(<<~RUBY) + class A + class B + + private + + def foo + bar.foo + end + end + + def baz + ^^^ Use `delegate` to define delegations. + foo.baz + end + end + RUBY + + expect_correction(<<~RUBY) + class A + class B + + private + + def foo + bar.foo + end + end + + delegate :baz, to: :foo + end + RUBY + end + it 'ignores delegation with assignment' do expect_no_offenses(<<~RUBY) def new