Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Leave parentheses in place on method calls
Note that this explicitly leaves parentheses in place even if they are
empty. There are two reasons we would need to do this. The first is if
we're calling something that looks like a constant, as in:

    Foo()

In this case if we remove the parentheses then this becomes a constant
reference and not a method call. The second is if we're calling a
method that is the same name as a local variable that is in scope, as
in:

    foo = foo()

In this case we have to keep the parentheses or else it treats this
like assigning nil to the local variable. Note that we could attempt
to be smarter about this by tracking the local variables that are in
scope, but for now it's simpler and more efficient to just leave the
parentheses in place.
  • Loading branch information
kddnewton committed Jan 4, 2023
commit 11ead3e61ae3570f20abf70c63c35e2f6693b696
29 changes: 19 additions & 10 deletions lib/syntax_tree/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3001,16 +3001,25 @@ def format(q)
else
q.format(message)

if arguments.is_a?(ArgParen) && arguments.arguments.nil? &&
!message.is_a?(Const)
# If you're using an explicit set of parentheses on something that
# looks like a constant, then we need to match that in order to
# maintain valid Ruby. For example, you could do something like Foo(),
# on which we would need to keep the parentheses to make it look like
# a method call.
else
q.format(arguments)
end
# Note that this explicitly leaves parentheses in place even if they are
# empty. There are two reasons we would need to do this. The first is if
# we're calling something that looks like a constant, as in:
#
# Foo()
#
# In this case if we remove the parentheses then this becomes a constant
# reference and not a method call. The second is if we're calling a
# method that is the same name as a local variable that is in scope, as
# in:
#
# foo = foo()
#
# In this case we have to keep the parentheses or else it treats this
# like assigning nil to the local variable. Note that we could attempt
# to be smarter about this by tracking the local variables that are in
# scope, but for now it's simpler and more efficient to just leave the
# parentheses in place.
q.format(arguments) if arguments
end
end

Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/arg_paren.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
foo(bar)
%
foo()
-
foo
%
foo(barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)
-
Expand Down