Skip to content

Commit

Permalink
Fix an incorrect auto-correct for Style/SingleLineMethods
Browse files Browse the repository at this point in the history
This PR fixes the following incorrect auto-correct for `Style/SingleLineMethods`
when single line method call without parentheses.

```console
% ruby -v
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-darwin19]

% cat example.rb
def index() head :ok end

% bundle exec rubocop --only Style/SingleLineMethods -a
(snip)

Inspecting 1 file
C

Offenses:

example.rb:1:1: C: [Corrected] Style/SingleLineMethods: Avoid
single-line method definitions.
def index() head :ok end
^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense corrected
```

## Before

Auto-correctd to invalid endless method definition syntax.

```ruby
% cat example.rb
def index() = head :ok

% ruby -c example.rb
example.rb:1: syntax error, unexpected symbol literal, expecting `do' or
'{' or '('
def index() = head :ok
```

## After

Auto-correctd to valid endless method definition syntax.

```ruby
% cat example.rb
def index() = head(:ok)

% ruby -c example.rb
Syntax OK
```
  • Loading branch information
koic authored and bbatsov committed Apr 17, 2021
1 parent 260a5bc commit f504a4e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#9704](https://github.com/rubocop/rubocop/pull/9704): Fix an incorrect auto-correct for `Style/SingleLineMethods` when single line method call without parentheses. ([@koic][])
15 changes: 14 additions & 1 deletion lib/rubocop/cop/style/single_line_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ def correct_to_multiline(corrector, node)
def correct_to_endless(corrector, node)
self_receiver = node.self_receiver? ? 'self.' : ''
arguments = node.arguments.any? ? node.arguments.source : '()'
replacement = "def #{self_receiver}#{node.method_name}#{arguments} = #{node.body.source}"
body_source = method_body_source(node.body)
replacement = "def #{self_receiver}#{node.method_name}#{arguments} = #{body_source}"

corrector.replace(node, replacement)
end

Expand All @@ -111,6 +113,17 @@ def move_comment(node, corrector)
node: node, corrector: corrector
)
end

def method_body_source(method_body)
if method_body.arguments.empty? || method_body.parenthesized?
method_body.source
else
arguments_source = method_body.arguments.map(&:source).join(', ')
body_source = "#{method_body.method_name}(#{arguments_source})"

method_body.receiver ? "#{method_body.receiver.source}.#{body_source}" : body_source
end
end
end
end
end
Expand Down
12 changes: 12 additions & 0 deletions spec/rubocop/cop/style/single_line_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@ def some_method(a, b, c) = body
RUBY
end

it 'corrects to an endless method definition when single line method call with parentheses' do
expect_correction(<<~RUBY.strip, source: 'def index() head(:ok) end')
def index() = head(:ok)
RUBY
end

it 'corrects to an endless method definition when single line method call without parentheses' do
expect_correction(<<~RUBY.strip, source: 'def index() head :ok end')
def index() = head(:ok)
RUBY
end

it 'does not add parens if they are already present' do
expect_correction(<<~RUBY.strip, source: 'def some_method() body end')
def some_method() = body
Expand Down

0 comments on commit f504a4e

Please sign in to comment.