mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-17 05:07:37 +08:00
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:
@@ -33,11 +33,6 @@
|
||||
//! (loses uninit scalars by design); cpp declarations instead take the TS
|
||||
//! GENERIC fallback (direct identifier children only → `int x;` extracts,
|
||||
//! `int x = 5;` does not — bug-for-bug).
|
||||
//! - inheritance quirk: extractInheritance recurses into
|
||||
//! field_declaration_list, where a field_declaration with no DIRECT
|
||||
//! field_identifier child (pointer/array/method members) but a direct
|
||||
//! type_identifier emits an `extends` ref to that type (the Go-embedding
|
||||
//! branch matching c/cpp shapes). Kept: the parity gate pins today's graph.
|
||||
//! - static-member/value-read pass (cpp only): `field_expression` is in
|
||||
//! MEMBER_ACCESS_TYPES (listed for Scala, same node kind in cpp), so
|
||||
//! `Capitalized.member` / `Capitalized->member` VALUE reads emit
|
||||
@@ -1866,8 +1861,10 @@ impl<'t> Walker<'t> {
|
||||
// --- inheritance ---------------------------------------------------------
|
||||
|
||||
/// extractInheritance — the branches whose node kinds occur in the c/cpp
|
||||
/// grammars: base_class_clause (#1043), the field_declaration Go-embedding
|
||||
/// shape, and the field_declaration_list recursion that reaches it.
|
||||
/// grammars: base_class_clause (#1043) and the field_declaration_list
|
||||
/// recursion. A member `field_declaration` is never a supertype: the TS
|
||||
/// Go-embedding check is gated to Go, since c/cpp members nest their
|
||||
/// field_identifier inside a pointer/array/function declarator.
|
||||
fn extract_inheritance(&mut self, node: Node<'t>, class_row: u32) {
|
||||
stack_guard!();
|
||||
let extends_kind = edge_kind_index("extends").unwrap();
|
||||
@@ -1886,20 +1883,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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user