Skip to content

Commit

Permalink
Merge pull request #855 from gsamokovarov/pathname-parens-autocorrect
Browse files Browse the repository at this point in the history
Fix Rails/RootPathnameMethods autocorrection for Pathname calls without parens
  • Loading branch information
koic authored Nov 3, 2022
2 parents 0c27719 + 3df1615 commit 2a96132
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog/fix_railsrootpathnamemethods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#855](https://github.com/rubocop/rubocop-rails/pull/855): Fix Rails/RootPathnameMethods autocorrection for Pathname calls without parens. ([@gsamokovarov][])
25 changes: 18 additions & 7 deletions lib/rubocop/cop/rails/root_pathname_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,11 @@ class RootPathnameMethods < Base
def on_send(node)
evidence(node) do |method, path, args, rails_root|
add_offense(node, message: format(MSG, method: method, rails_root: rails_root.source)) do |corrector|
if dir_glob?(node)
replacement = build_path_glob(path, method)
else
replacement = "#{path.source}.#{method}"
replacement += "(#{args.map(&:source).join(', ')})" unless args.empty?
end
replacement = if dir_glob?(node)
build_path_glob_replacement(path, method)
else
build_path_replacement(path, method, args)
end

corrector.replace(node, replacement)
end
Expand All @@ -184,7 +183,7 @@ def evidence(node)
yield(method, path, args, rails_root)
end

def build_path_glob(path, method)
def build_path_glob_replacement(path, method)
receiver = range_between(path.loc.expression.begin_pos, path.children.first.loc.selector.end_pos).source

argument = if path.arguments.one?
Expand All @@ -196,6 +195,18 @@ def build_path_glob(path, method)
"#{receiver}.#{method}(#{argument})"
end

def build_path_replacement(path, method, args)
path_replacement = path.source
if path.arguments? && !path.parenthesized_call?
path_replacement[' '] = '('
path_replacement << ')'
end

replacement = "#{path_replacement}.#{method}"
replacement += "(#{args.map(&:source).join(', ')})" unless args.empty?
replacement
end

def include_interpolation?(arguments)
arguments.any? do |argument|
argument.children.any? { |child| child.respond_to?(:begin_type?) && child.begin_type? }
Expand Down
11 changes: 11 additions & 0 deletions spec/rubocop/cop/rails/root_pathname_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,15 @@
files.map { |file| Rails.root.join('db', file).open('wb') }
RUBY
end

it 'registers an offense when using `File.open Rails.root.join ...` without parens' do
expect_offense(<<~RUBY)
file = File.open Rails.root.join 'docs', 'invoice.pdf'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#open`.
RUBY

expect_correction(<<~RUBY)
file = Rails.root.join('docs', 'invoice.pdf').open
RUBY
end
end

0 comments on commit 2a96132

Please sign in to comment.