mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-11 18:07:31 +00:00
fix(rust): emit field type references for tuple structs
extract_rust() only traversed field_declaration_list (named-struct bodies), so tuple structs -- whose positional fields nest under ordered_field_declaration_list -- had every field type reference silently dropped from the graph. This is the same node shape the enum handler already accounts for (tuple variants nest their types under ordered_field_declaration_list); the struct path was simply left behind. Add an additive branch that, for each type node in a tuple struct's ordered_field_declaration_list, collects type refs via _rust_collect_type_refs and emits references edges with the appropriate field / generic_arg context. The named-struct path is untouched. For `struct Wrapper(Logger, Config);` with Logger/Config defined in-file, no field edges were produced before; both are now emitted. Adds test_rust_tuple_struct_field_references and a tuple struct to the shared Rust fixture covering plain and generic positional field types.
This commit is contained in:
@@ -8180,6 +8180,27 @@ def extract_rust(path: Path) -> dict:
|
||||
if tgt != item_nid:
|
||||
add_edge(item_nid, tgt, "references",
|
||||
field.start_point[0] + 1, context=ctx)
|
||||
# Tuple structs (`struct Wrapper(pub Logger, Config);`) nest their
|
||||
# positional field types directly under ordered_field_declaration_list
|
||||
# with no field_declaration wrapper -- the same shape handled for tuple
|
||||
# enum variants below. Without this branch these field type references
|
||||
# are silently dropped.
|
||||
for c in node.children:
|
||||
if c.type != "ordered_field_declaration_list":
|
||||
continue
|
||||
fline = c.start_point[0] + 1
|
||||
for tc in c.children:
|
||||
if tc.type not in ("type_identifier", "generic_type",
|
||||
"scoped_type_identifier", "reference_type",
|
||||
"primitive_type", "tuple_type", "array_type"):
|
||||
continue
|
||||
refs = []
|
||||
_rust_collect_type_refs(tc, source, False, refs)
|
||||
for ref_name, role in refs:
|
||||
ctx = "generic_arg" if role == "generic_arg" else "field"
|
||||
tgt = ensure_named_node(ref_name, fline)
|
||||
if tgt != item_nid:
|
||||
add_edge(item_nid, tgt, "references", fline, context=ctx)
|
||||
if t == "enum_item":
|
||||
# Variant payload types nest under enum_variant_list ->
|
||||
# enum_variant -> ordered_field_declaration_list (tuple variant,
|
||||
|
||||
Vendored
+2
@@ -56,3 +56,5 @@ enum GraphEvent {
|
||||
NodeAdded(Graph),
|
||||
Processed { proc: DataProcessor },
|
||||
}
|
||||
|
||||
struct GraphPair(Graph, Result<DataProcessor>);
|
||||
|
||||
@@ -365,6 +365,19 @@ def test_rust_struct_field_emits_field_context():
|
||||
assert ("DataProcessor", "DataProcessor") not in _edge_labels(r, "references", "field")
|
||||
|
||||
|
||||
def test_rust_tuple_struct_field_references():
|
||||
"""Tuple struct fields (`struct Wrapper(A, B);`) nest their positional types
|
||||
under ordered_field_declaration_list with no field_declaration wrapper -- the
|
||||
same shape as tuple enum variants. That path was not traversed for structs, so
|
||||
tuple-struct field type references were silently dropped.
|
||||
"""
|
||||
r = extract_rust(FIXTURES / "sample.rs")
|
||||
field_refs = _edge_labels(r, "references", "field")
|
||||
assert ("GraphPair", "Graph") in field_refs, "tuple-struct field reference missing"
|
||||
assert ("GraphPair", "Result") in field_refs, "tuple-struct generic field reference missing"
|
||||
assert ("GraphPair", "DataProcessor") in _edge_labels(r, "references", "generic_arg")
|
||||
|
||||
|
||||
def test_rust_method_parameter_return_and_generic_contexts():
|
||||
r = extract_rust(FIXTURES / "sample.rs")
|
||||
assert ("build", "DataProcessor") in _edge_labels(r, "references", "parameter_type")
|
||||
|
||||
Reference in New Issue
Block a user