Support wildcard callees in call patterns - #11
Merged
Conversation
dannote
reviewed
Jul 20, 2026
| # function calls, so `_(...)` does not treat them as calls. Symbolic heads | ||
| # (`%{}`, `{}`, `.`, operators, `@`, ...) are already excluded by | ||
| # `regular_identifier?/1`, so only identifier-shaped forms need listing. | ||
| @non_call_heads ExAST.Symbols.definition_forms() ++ |
Collaborator
There was a problem hiding this comment.
and, or, not, and in all pass regular_identifier?/1, so _(...) matches them as calls:
Patcher.find_all("left and right", "_(...)")
# one matchThat contradicts the operator exclusion described above. Could you filter word operators too and add coverage for them?
`_(...)` matches any local call and `_._(...)` any remote call, filling the one gap where `_` couldn't be used — the name of the function being called. `_` already matched arguments, remote-call modules, and definition names. Special forms, operators, and definitions are excluded so `_(...)` means a function call, not any node. The exclusion list reuses `ExAST.Symbols.definition_forms/0` and omits symbolic heads already handled by identifier checking.
`and`, `or`, `not`, and `in` parse to identifier-shaped heads that pass `regular_identifier?/1`, so `_(...)` was matching them as local calls — contradicting the operator exclusion the surrounding comment describes. Collect the identifier-shaped operators (`and`, `or`, `not`, `in`, `when`) into `@word_operators` and prepend them to `@non_call_heads` so `real_call_name?/1` rejects them. Symbolic operators (`&&`, `++`, `^^^`, …) are still excluded by `regular_identifier?/1`.
dannote
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With this PR
_can stand in for the name of the function being called — the one spot where it didn't already work._already matched arguments, remote-call modules, and definition names; this fills the gap:_(...)_._(...)_.section(...)sectionon any moduleFoo._(...)Foo_(...)means "a function call," not "any node": special forms, operators, and definitions (def,case,%{},fn,with, …) are excluded, so it won't match map literals, definition heads, or control-flow forms. Remote calls are excluded too — use_._(...)for those.Before
_in callee position matched nothing:After
Pin the function name and leave the module open with _.name(...):