From 200081cf9b726bab47ba21abe682b7663f612e4e Mon Sep 17 00:00:00 2001 From: ayushcodes10 Date: Wed, 16 Sep 2026 15:16:52 +0530 Subject: [PATCH] Tag a self dot method call with its receiver's syntactic type Detect when a member call's receiver is literally self (a distinct tree sitter node type, not an identifier) and, when the enclosing impl block's bare type name is known, carry it on the raw_call as rust_self_type. Nothing consumes this yet, so the extracted edges are unchanged; it is the signal the next commit's resolver needs. Co-Authored-By: Claude Sonnet 5 --- graphify/extractors/rust.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/graphify/extractors/rust.py b/graphify/extractors/rust.py index c1bc659e3..4936d73ce 100644 --- a/graphify/extractors/rust.py +++ b/graphify/extractors/rust.py @@ -410,7 +410,7 @@ def extract_rust(path: Path) -> dict: seen_call_pairs: set[tuple[str, str]] = set() raw_calls: list[dict] = [] - def walk_calls(node, caller_nid: str) -> None: + def walk_calls(node, caller_nid: str, self_type: str | None = None) -> None: if node.type == "function_item": return if node.type == "call_expression": @@ -418,6 +418,7 @@ def extract_rust(path: Path) -> dict: callee_name: str | None = None is_member_call: bool = False is_scoped_call: bool = False + is_self_call: bool = False if func_node: if func_node.type == "identifier": callee_name = _read_text(func_node, source) @@ -426,6 +427,9 @@ def extract_rust(path: Path) -> dict: field = func_node.child_by_field_name("field") if field: callee_name = _read_text(field, source) + receiver = func_node.child_by_field_name("value") + if receiver is not None and receiver.type == "self": + is_self_call = True elif func_node.type == "scoped_identifier": # Type::method() — still allow in-file EXTRACTED match, but # skip cross-file resolution: bare last-segment lookup ignores @@ -452,18 +456,21 @@ def extract_rust(path: Path) -> dict: "weight": 1.0, }) elif not is_scoped_call and callee_name.lower() not in _RUST_TRAIT_METHOD_BLOCKLIST: - raw_calls.append({ + rc_entry = { "caller_nid": caller_nid, "callee": callee_name, "is_member_call": is_member_call, "source_file": str_path, "source_location": f"L{node.start_point[0] + 1}", - }) + } + if is_self_call and self_type: + rc_entry["rust_self_type"] = self_type + raw_calls.append(rc_entry) for child in node.children: - walk_calls(child, caller_nid) + walk_calls(child, caller_nid, self_type) - for caller_nid, body_node, _impl_type in function_bodies: - walk_calls(body_node, caller_nid) + for caller_nid, body_node, impl_type in function_bodies: + walk_calls(body_node, caller_nid, impl_type) valid_ids = seen_ids clean_edges = []