fix(elixir): populate first_string_arg for Elixir calls - #1721
Conversation
tree-sitter-elixir attaches no field name to a call's arguments node. Its whole field set is key, left, operand, operator, quoted_start, quoted_end, right, target and value, so ts_node_child_by_field_name(node, "arguments") is always null for Elixir and call.first_string_arg was never populated for any Elixir call. Every downstream signal that keys off a call's string argument was therefore dead for Elixir: Phoenix route paths, HTTP/async service URLs, and config keys. Nothing reported an error — the field was simply always NULL. The definition side already knows this: extract_defs.c carries elixir_call_args() with a positional second-child fallback for exactly this reason. This adds the same fallback on the call side, gated to `call` nodes, since Elixir's other call kinds (`dot`, the `|>` binary_operator) carry no arguments node in that position. The new test pins the field directly rather than a downstream effect. Signed-off-by: Henry Hazan <henry@teramine.io>
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
|
The build step succeeded; the guard script failed:
Five independent subprocess/daemon startups failing in one Windows job reads like a sick runner rather than a code defect. Why it should not be reachable from this diff:
Everything else on the PR is green: DCO, I do not have rerun rights on this repo — could a maintainer re-run that single job? Happy to push an empty commit to re-trigger instead if you would rather not spend the click, and equally happy to dig further if you have seen this guard fail for a real reason before. |
The bug
tree-sitter-elixirattaches no field name to a call's arguments node. Its entire field set is:There is no
argumentsfield. Buthandle_calls()ininternal/cbm/extract_calls.creads exactly that:For Elixir this is always null, so
call.first_string_argwas never populated for any Elixir call — not once, in any file. Nothing errored; the field was simply alwaysNULL.Why it matters
Everything downstream that keys off a call's string argument was silently dead for Elixir:
get "/wallets", WalletController, :indexnever yielded a pathCBM_SVC_HTTP/CBM_SVC_ASYNCclassification needs the URL or topic literalApplication.get_env("...")is matched asCBM_SVC_CONFIG, which reads the same fieldThe fix
The definition side has always known about this.
extract_defs.ccarrieselixir_call_args()with a positional second-child fallback for precisely this reason:This adds the same fallback on the call side. It is gated to
callnodes, because Elixir's other call kinds —dot, and the|>binary_operator— carry no arguments node in that position and would otherwise pick up the operator token.Test
elixir_call_string_argumentpinsfirst_string_argdirectly rather than asserting a downstream effect, so it stays meaningful independently of route or service classification.Verification
make -f Makefile.cbm test-focused TEST_SUITES="extraction registry lang_contract grammar_regression grammar_labels repro_language_registry repro_call_node_manifest"→ 388 passed, 0 failedCBM_LANG_ELIXIRclang-format --dry-run --Werrorclean on the changed source.tests/was deliberately left unformatted, per the note that it is not inLINT_SRCSelixir-plug/plugand an 829-file Phoenix applicationScope
Submitted as a bug fix under the CONTRIBUTING exception for focused bug fixes and test additions, so there is no prior issue. Additions only — 54 lines, no deletions, no reformatting.
This is the first of four independent Elixir fixes found while auditing Elixir extraction against a real Phoenix codebase. The other three are prepared and gated separately, and I will open them one at a time rather than as a bundle:
first_string_argnever populatedargumentsfield again, plus a dispatch on adefnode type the grammar does not have)Routenodes (everyroute_reg_suffixesentry is prefixed.or::, but the macros are bare) — depends on this PR for the path argumentHappy to reorder, split further, or drop any of them if you would rather discuss the approach in an issue first.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DpDDX9sFC16mQ9U9wQ3WNd