From 05029d96a475c5d2b2e28431cbe8c55c02093118 Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Tue, 1 Nov 2022 18:38:46 +0900 Subject: [PATCH] Fix a false positive for `Style/Alias`cop when alias in a method def The following cases will result in a NoMethodError if replaced with alias_method. Therefore, it is correct to regard it as a violation and not to replace it. ```ruby def foo alias :ala :bala end ``` --- ...ix_fix_a_false_positive_for_style_alias.md | 1 + lib/rubocop/cop/style/alias.rb | 10 ++++- spec/rubocop/cop/style/alias_spec.rb | 42 ++++++++++++++++--- 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 changelog/fix_fix_a_false_positive_for_style_alias.md diff --git a/changelog/fix_fix_a_false_positive_for_style_alias.md b/changelog/fix_fix_a_false_positive_for_style_alias.md new file mode 100644 index 00000000000..ed29efa0aba --- /dev/null +++ b/changelog/fix_fix_a_false_positive_for_style_alias.md @@ -0,0 +1 @@ +* [#11014](https://github.com/rubocop/rubocop/pull/11014): Fix a false positive for `Style/Alias`cop when alias in a method def. ([@ydah][]) diff --git a/lib/rubocop/cop/style/alias.rb b/lib/rubocop/cop/style/alias.rb index 7a25c626369..fe70ff01dd2 100644 --- a/lib/rubocop/cop/style/alias.rb +++ b/lib/rubocop/cop/style/alias.rb @@ -7,6 +7,11 @@ module Style # depending on configuration. # It also flags uses of `alias :symbol` rather than `alias bareword`. # + # However, it will always enforce `method_alias` when used `alias` + # in an instance method definition and in a singleton method definition. + # If used in a block, always enforce `alias_method` + # unless it is an `instance_eval` block. + # # @example EnforcedStyle: prefer_alias (default) # # bad # alias_method :bar, :foo @@ -22,6 +27,7 @@ module Style # # # good # alias_method :bar, :foo + # class Alias < Base include ConfigurableEnforcedStyle extend AutoCorrector @@ -71,7 +77,9 @@ def alias_keyword_possible?(node) end def alias_method_possible?(node) - scope_type(node) != :instance_eval && node.children.none?(&:gvar_type?) + scope_type(node) != :instance_eval && + node.children.none?(&:gvar_type?) && + node&.parent&.type != :def end def add_offense_for_args(node, &block) diff --git a/spec/rubocop/cop/style/alias_spec.rb b/spec/rubocop/cop/style/alias_spec.rb index fdcb1b3cfd7..e7e527604df 100644 --- a/spec/rubocop/cop/style/alias_spec.rb +++ b/spec/rubocop/cop/style/alias_spec.rb @@ -106,22 +106,52 @@ module M RUBY end - it 'does not register an offense for alias_method with explicit receiver' do + it 'does not register registers an offense for alias in a def' do expect_no_offenses(<<~RUBY) - class C - receiver.alias_method :ala, :bala + def foo + alias :ala :bala end RUBY end - it 'does not register an offense for alias_method in a method def' do - expect_no_offenses(<<~RUBY) - def method + it 'registers an offense for alias in a defs' do + expect_offense(<<~RUBY) + def some_obj.foo + alias :ala :bala + ^^^^^ Use `alias_method` instead of `alias`. + end + RUBY + + expect_correction(<<~RUBY) + def some_obj.foo alias_method :ala, :bala end RUBY end + it 'registers an offense for alias in a block' do + expect_offense(<<~RUBY) + included do + alias :ala :bala + ^^^^^ Use `alias_method` instead of `alias`. + end + RUBY + + expect_correction(<<~RUBY) + included do + alias_method :ala, :bala + end + RUBY + end + + it 'does not register an offense for alias_method with explicit receiver' do + expect_no_offenses(<<~RUBY) + class C + receiver.alias_method :ala, :bala + end + RUBY + end + it 'does not register an offense for alias_method in self.method def' do expect_no_offenses(<<~RUBY) def self.method