mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-20 02:41:13 +00:00
fix(rust): emit a node per enum variant with a case_of edge
The enum_item handler walked each variant only to collect its payload type
references (`Click(Logger)` -> Logger), but never emitted a node for the
variant itself. So an `enum Shape { Circle, Square, Empty }` produced a node
for Shape with no members at all — the enum was a leaf and its variants were
absent from the graph.
Emit a node plus a `case_of` edge per enum_variant, keyed on the variant's
`identifier` child, alongside the existing payload-type walk. This brings
Rust to parity with every other language that has enums: Java's enum_constant
(#1719), Kotlin's enum_entry (#1738), Swift, and Scala.
This commit is contained in:
1 parent
1cd9a36c0c
commit
13903a8ac3
2 files changed
+36
No files matched your search
@@ -366,6 +366,24 @@ def extract_rust(path: Path) -> dict:
|
||||
if variant.type != "enum_variant":
|
||||
continue
|
||||
vline = variant.start_point[0] + 1
|
||||
# Emit a node per variant with a case_of edge back to
|
||||
# the enum. Only the variants' payload types were
|
||||
# walked before, so the variants themselves (`Circle`,
|
||||
# `Square`, `Empty`) never became nodes and the enum
|
||||
# was left a memberless leaf. This is the Rust parity
|
||||
# of Java #1719 / Kotlin #1738 / Swift / Scala enums.
|
||||
# The variant name is the enum_variant's `identifier`.
|
||||
vname_node = next(
|
||||
(vc for vc in variant.children
|
||||
if vc.type == "identifier"),
|
||||
None,
|
||||
)
|
||||
if vname_node is not None:
|
||||
vname = _read_text(vname_node, source)
|
||||
if vname:
|
||||
variant_nid = _make_id(item_nid, vname)
|
||||
add_node(variant_nid, vname, vline)
|
||||
add_edge(item_nid, variant_nid, "case_of", vline)
|
||||
for vc in variant.children:
|
||||
if vc.type == "ordered_field_declaration_list":
|
||||
for tc in vc.children:
|
||||
|
||||
@@ -410,6 +410,24 @@ def test_rust_enum_variant_references():
|
||||
assert ("GraphEvent", "DataProcessor") in refs, "struct-variant reference missing"
|
||||
|
||||
|
||||
def test_rust_enum_variants_emit_case_of_nodes():
|
||||
"""Each enum variant must become a node with a `case_of` edge to its enum.
|
||||
|
||||
The enum handler only walked variants to collect their payload type
|
||||
references; the variants themselves (`NodeAdded`, `Processed`) never became
|
||||
nodes, so the enum was left a memberless leaf. Every other language with
|
||||
enums (Java #1719, Kotlin #1738, Swift, Scala) emits a node per member with
|
||||
a `case_of` edge; this brings Rust to parity.
|
||||
"""
|
||||
r = extract_rust(FIXTURES / "sample.rs")
|
||||
labels = {n["label"] for n in r["nodes"]}
|
||||
assert "NodeAdded" in labels
|
||||
assert "Processed" in labels
|
||||
case_of = _edge_labels(r, "case_of")
|
||||
assert ("GraphEvent", "NodeAdded") in case_of
|
||||
assert ("GraphEvent", "Processed") in case_of
|
||||
|
||||
|
||||
def test_rust_struct_field_emits_field_context():
|
||||
r = extract_rust(FIXTURES / "sample.rs")
|
||||
assert ("DataProcessor", "Result") in _edge_labels(r, "references", "field")
|
||||
|
||||
Reference in new issue
Block a user