fix(c,cpp): a pointer, array or function member is not a supertype (#2394)

extractInheritance carried Go's struct-embedding check (a field_declaration
with no direct field_identifier names an embedded type) into every grammar
with a field_declaration_list. tree-sitter-c/cpp, and Objective-C's C
structs, nest a member's field_identifier inside its pointer/array/
function/reference declarator, so `SharedState* shared;`, `jv elements[];`
and `virtual Status Put(...) = 0;` all became `extends` edges to the
member's type: false supertypes in the type hierarchy, blast radius and
codegraph_explore, and false cpp-override call edges built on them
(google/leveldb: 246 of 302 extends edges).

Gate the branch to Go in the TS extractor, drop the mirrored arm from the
C/C++ kernel port (and the "kept for parity" quirk note), and drop the
inert copy from the Rust-language port. C++ base_class_clause, Objective-C
superclasses and Go embedding are unchanged.

Validated on leveldb, jq, llm.c and redis: every removed extends edge is a
member site, no base-clause edge is lost; gin, SDWebImage and ripgrep
dumps are byte-identical; kernel/wasm parity sweeps show 0 diffs.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-10-06 23:27:58 +00:00
committed by GitHub
parent 0a670dc8cc
commit ac1f430d3e
7 changed files with 292 additions and 45 deletions
+3 -17
View File
@@ -1061,9 +1061,9 @@ impl<'t> Walker<'t> {
/// extractInheritance — the rust-reachable cases: trait_bounds
/// (supertraits; a scoped `fmt::Debug` bound matches NO case and is
/// dropped), the Go embedding check on field_declaration (inert in rust —
/// every field has a field_identifier), and the field_declaration_list
/// recursion that reaches it.
/// dropped) and the field_declaration_list recursion. The TS Go-embedding
/// check on field_declaration is gated to Go (and was inert here anyway —
/// every rust field has a field_identifier).
fn extract_inheritance(&mut self, node: Node<'t>, class_row: u32) {
stack_guard!();
let extends_kind = edge_kind_index("extends").unwrap();
@@ -1102,20 +1102,6 @@ impl<'t> Walker<'t> {
}
}
}
"field_declaration" => {
let has_field_identifier = (0..child.named_child_count())
.filter_map(|j| child.named_child(j))
.any(|c| c.kind() == "field_identifier");
if !has_field_identifier {
let type_id = (0..child.named_child_count())
.filter_map(|j| child.named_child(j))
.find(|c| c.kind() == "type_identifier");
if let Some(type_id) = type_id {
let name = self.text(type_id).to_string();
self.push_ref_at(class_row, &name, extends_kind, type_id);
}
}
}
"field_declaration_list" | "class_heritage" => {
self.extract_inheritance(child, class_row);
}