fix(julia): name parametric functors by their type, not the variable

`(b::Box{T})(x)` puts the type in a `parametrized_type_expression`, so taking
the last identifier in the typed expression picked the variable `b` and
emitted a bogus `b#call` node, split from `Box#call`. Read the last operand
through `_type_name_of`, which already unwraps parametric heads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ayarodionovandClaude Opus 5.5 authored and safishamsi committed 2026-10-12 13:01:09 +01:00
1 parent d611afbee9
commit fac1491665
2 files changed
+21 -3

No files matched your search

+7 -3
View File
@@ -194,9 +194,13 @@ def extract_julia(path: Path) -> dict:
typed = next((c for c in callee.children
if c.type in ("typed_expression", "unary_typed_expression")), None)
if typed is not None:
ids = [c for c in typed.children if c.type == "identifier"]
if ids:
tname = _read_text(ids[-1], source)
# The type is the last operand; it may be parametric (`(b::Box{T})`),
# so read it through `_type_name_of` rather than the last identifier,
# which would be the variable `b`.
operands = [c for c in typed.children
if c.type in ("identifier", "parametrized_type_expression")]
tname = _type_name_of(operands[-1]) if operands else None
if tname:
return tname + "#call", f"({tname})"
return None
+14
View File
@@ -5728,3 +5728,17 @@ def test_julia_broadcast_and_pipe_calls(tmp_path):
assert ("bcast()", "helper()") in calls
assert ("param()", "helper()") in calls
assert ("rettype()", "param()") in calls
def test_julia_parametric_functor_uses_type_not_variable(tmp_path):
f = tmp_path / "functor.jl"
f.write_text(
"struct Box{T}\n v::T\nend\n"
"(b::Box{T})(x) where T = x\n"
"(b::Box)(x, y) = x\n"
"(::Box{T})(x, y, z) where T = x\n"
)
r = extract_julia(f)
call_nodes = [n for n in r["nodes"] if n["id"].endswith("_call")]
# All three methods of the Box functor share one node labelled by the type.
assert [n["label"] for n in call_nodes] == ["(Box)()"]