Skip to content

Commit

Permalink
[Fix #12924] Fix false positives for Style/SendWithLiteralMethodName
Browse files Browse the repository at this point in the history
Fixes #12924.

This PR fixes false positives for `Style/SendWithLiteralMethodName`
when `public_send` argument is a method name that cannot be autocorrected.
  • Loading branch information
koic committed May 23, 2024
1 parent 9e78c46 commit 2e2faf5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#12924](https://github.com/rubocop/rubocop/issues/12924): Fix false positives for `Style/SendWithLiteralMethodName` when `public_send` argument is a method name that cannot be autocorrected. ([@koic][])
11 changes: 9 additions & 2 deletions lib/rubocop/cop/style/send_with_literal_method_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,22 @@ class SendWithLiteralMethodName < Base
MSG = 'Use `%<method_name>s` method call directly instead.'
RESTRICT_ON_SEND = %i[public_send send __send__].freeze
STATIC_METHOD_NAME_NODE_TYPES = %i[sym str].freeze
METHOD_NAME_PATTERN = /\A[a-zA-Z_][a-zA-Z0-9_]*[!?=]?\z/.freeze
RESERVED_WORDS = %i[
BEGIN END alias and begin break case class def defined? do else elsif end ensure
false for if in module next nil not or redo rescue retry return self super then true
undef unless until when while yield
].freeze

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
def on_send(node)
return if allow_send? && !node.method?(:public_send)
return unless (first_argument = node.first_argument)
return unless STATIC_METHOD_NAME_NODE_TYPES.include?(first_argument.type)

offense_range = offense_range(node)
method_name = first_argument.value
return if !METHOD_NAME_PATTERN.match?(method_name) || RESERVED_WORDS.include?(method_name)

add_offense(offense_range, message: format(MSG, method_name: method_name)) do |corrector|
if node.arguments.one?
Expand All @@ -62,7 +69,7 @@ def on_send(node)
end
end
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

private

Expand Down
43 changes: 43 additions & 0 deletions spec/rubocop/cop/style/send_with_literal_method_name_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@
RUBY
end

it 'registers an offense when using `public_send` with method name with underscore' do
expect_offense(<<~RUBY)
obj.public_send("name_with_underscore")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `name_with_underscore` method call directly instead.
RUBY

expect_correction(<<~RUBY)
obj.name_with_underscore
RUBY
end

it 'does not register an offense when using `public_send` with variable argument' do
expect_no_offenses(<<~RUBY)
obj.public_send(variable)
Expand All @@ -68,6 +79,38 @@
RUBY
end

it 'does not register an offense when using `public_send` with method name with space' do
expect_no_offenses(<<~RUBY)
obj.public_send("name with space")
RUBY
end

it 'does not register an offense when using `public_send` with method name with hyphen' do
expect_no_offenses(<<~RUBY)
obj.public_send("name-with-hyphen")
RUBY
end

it 'does not register an offense when using `public_send` with method name with brackets' do
expect_no_offenses(<<~RUBY)
obj.public_send("{brackets}")
RUBY
end

it 'does not register an offense when using `public_send` with method name with square brackets' do
expect_no_offenses(<<~RUBY)
obj.public_send("[square_brackets]")
RUBY
end

it 'does not register an offense when using `public_send` with reserved word argument' do
described_class::RESERVED_WORDS.each do |reserved_word|
expect_no_offenses(<<~RUBY)
obj.public_send(:#{reserved_word})
RUBY
end
end

it 'does not register an offense when using `public_send` with integer literal argument' do
expect_no_offenses(<<~RUBY)
obj.public_send(42)
Expand Down

0 comments on commit 2e2faf5

Please sign in to comment.