Elixir: Not all functions are properly identified
Describe the bug In addition to #245, there are two other function declarations that are currently not correctly identified by @function.inner/@function.outer queries. The following are not matched:
def foo(), do: 12
def foo() do
12
end
def guarded_fn(a, b) when a == b, do: a + b
def guarded_fn(a, b) when a != b do
a * b
end
To Reproduce Steps to reproduce the behavior:
- Add above code to editor
- Try to move to next/prev function.
Expected behavior Functions with guards and functions without parameters are correctly identified.
Additional context
Having to deep dive treesitter to learn all that's needed to fix this. Posting my findings here so that maybe someone can speed me up on fixing this. The problem is in this match.
The match assumes the functions argument list will not be empty
(arguments (call [
(arguments (_) @parameter.inner . "," @_delimiter)
(arguments ((_) @parameter.inner) @_delimiter .)
] (#make-range! "parameter.outer" @parameter.inner @_delimiter))
So the following code doesn't get registered
def foo(), do: 12
What I am struggling with is getting the #make-range to work properly when adding an empty argument clause. If I drop the whole make range logic and just do something like this the function selection works.
(call
target: ((identifier) @_identifier (#any-of? @_identifier
"def"
"defmacro"
"defmacrop"
"defn"
"defnp"
"defp"
))
(arguments (call [
(arguments (_) @parameter.inner . "," @_delimiter)
(arguments ((_) @parameter.inner) @_delimiter .)
(arguments)
]))
(keywords
(pair
value: (_) @function.inner))
)
) @function.outer
I don't know if the proper approach is to define several somewhat duplicated matches that do or do not use the make-range helper or if there is a way to only call that predicate on a part of the match logic.
Going to keep playing with this. I think the solution is to stop trying to define a lot of the text objects in one query and instead make separate queries for exact text objects. By pulling the parameters query away from the functions query I think I can get everything lined up