fix(c,cpp,objc,rust): index union declarations
A `union` declaration produced no symbol at all in any of the four
languages that have one. The type never entered the graph, and neither
did anything attached to it — in Rust every `impl Trait for MyUnion`
lost its edge, and the impl's methods were left with a qualifiedName
pointing at a type the graph did not contain.
`union_specifier` / `union_item` were absent from the extraction layer
entirely: no `<x>Types` list on the TS side, no dispatch branch in
either kernel walker.
They join `structTypes` (kind `struct` — NodeKind has no `union`), which
is the extension point the table-driven extractors already provide. The
body guard in extractStruct is untouched, so a bodiless `union U;` stays
a forward declaration and is still skipped, exactly like `struct U;`.
`resolveTypeAliasKind` accepts `union_specifier` too, so
`typedef union { … } N;` takes the typedef's name the way
`typedef struct { … } N;` already did. Without it the anonymous union
body would mint a second `<anonymous>` node beside the alias.
Both walkers change together so kernel<->wasm parity holds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d6d17288be
commit
85e9ac6762
@@ -812,7 +812,10 @@ impl<'t> Walker<'t> {
|
||||
} else if self.variant == Variant::Cpp && kind == "class_specifier" {
|
||||
self.extract_class(node);
|
||||
skip_children = true;
|
||||
} else if kind == "struct_specifier" {
|
||||
} else if matches!(kind, "struct_specifier" | "union_specifier") {
|
||||
// `union_specifier` mirrors structTypes on the TS side: a named
|
||||
// `union U { … };` is a definition, extracted with kind "struct"
|
||||
// (NodeKind has no "union"). Bodiless stays a forward declaration.
|
||||
self.extract_struct(node);
|
||||
skip_children = true;
|
||||
} else if kind == "enum_specifier" {
|
||||
@@ -1041,7 +1044,9 @@ impl<'t> Walker<'t> {
|
||||
resolved = Some("enum");
|
||||
break;
|
||||
}
|
||||
if child.kind() == "struct_specifier" && child.child_by_field_name("body").is_some() {
|
||||
if matches!(child.kind(), "struct_specifier" | "union_specifier")
|
||||
&& child.child_by_field_name("body").is_some()
|
||||
{
|
||||
resolved = Some("struct");
|
||||
break;
|
||||
}
|
||||
@@ -1059,7 +1064,8 @@ impl<'t> Walker<'t> {
|
||||
self.stack.push(Scope { row, kind: "struct", name });
|
||||
let type_child = node
|
||||
.child_by_field_name("type")
|
||||
.or_else(|| self.find_child_by_kind(node, "struct_specifier"));
|
||||
.or_else(|| self.find_child_by_kind(node, "struct_specifier"))
|
||||
.or_else(|| self.find_child_by_kind(node, "union_specifier"));
|
||||
if let Some(tc) = type_child {
|
||||
self.extract_inheritance(tc, row);
|
||||
let body = tc.child_by_field_name("body").unwrap_or(tc);
|
||||
@@ -1556,7 +1562,7 @@ impl<'t> Walker<'t> {
|
||||
self.extract_class(node);
|
||||
return;
|
||||
}
|
||||
if kind == "struct_specifier" {
|
||||
if matches!(kind, "struct_specifier" | "union_specifier") {
|
||||
self.extract_struct(node);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -446,7 +446,9 @@ impl<'t> Walker<'t> {
|
||||
} else if kind == "trait_item" {
|
||||
self.extract_interface(node);
|
||||
skip_children = true;
|
||||
} else if kind == "struct_item" {
|
||||
} else if matches!(kind, "struct_item" | "union_item") {
|
||||
// `union_item` mirrors structTypes on the TS side: same `body:`
|
||||
// field, same extractor, kind "struct" (NodeKind has no "union").
|
||||
self.extract_struct(node);
|
||||
skip_children = true;
|
||||
} else if kind == "enum_item" {
|
||||
@@ -1130,7 +1132,7 @@ impl<'t> Walker<'t> {
|
||||
}
|
||||
|
||||
// Structural nodes inside bodies.
|
||||
if kind == "struct_item" {
|
||||
if matches!(kind, "struct_item" | "union_item") {
|
||||
self.extract_struct(node);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user