Skip to content

Commit ccafc60

Browse files
authored
fix(native): align edge builder kind filters with JS parity (#541)
* fix(native): align edge builder kind filters with JS parity The Rust edge builder only matched `kind == "class"` when looking up source nodes and targets for extends/implements edges. This caused all `impl Trait for Struct` relationships (and any non-class hierarchy) to be silently dropped — producing 0 implements edges for Rust sources while WASM correctly found 9. Align the three kind filter sets with the JS-side constants: - Source: class, struct, record, enum (was: class only) - Extends targets: class, struct, trait, record (was: class only) - Implements targets: interface, class, trait (was: interface, class) Fixes #530 (partial — implements parity gap) Impact: 1 functions changed, 0 affected * refactor: extract kind-filter constants for readability (#541) Extract inline kind-filter closures into named constants (HIERARCHY_SOURCE_KINDS, EXTENDS_TARGET_KINDS, IMPLEMENTS_TARGET_KINDS) at module level, mirroring the JS-side convention in build-edges.js. This prevents future native/WASM drift by giving each set a single source of truth.
1 parent c433e6e commit ccafc60

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

crates/codegraph-core/src/edge_builder.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ use napi_derive::napi;
44

55
use crate::import_resolution;
66

7+
/// Kind sets for hierarchy edge resolution -- mirrors the JS constants in
8+
/// `build-edges.js` (`HIERARCHY_SOURCE_KINDS`, `EXTENDS_TARGET_KINDS`,
9+
/// `IMPLEMENTS_TARGET_KINDS`). Keeping them in one place prevents the
10+
/// native/WASM drift that caused the original parity bug.
11+
const HIERARCHY_SOURCE_KINDS: &[&str] = &["class", "struct", "record", "enum"];
12+
const EXTENDS_TARGET_KINDS: &[&str] = &["class", "struct", "trait", "record"];
13+
const IMPLEMENTS_TARGET_KINDS: &[&str] = &["interface", "trait", "class"];
14+
715
#[napi(object)]
816
pub struct NodeInfo {
917
pub id: u32,
@@ -339,16 +347,14 @@ pub fn build_call_edges(
339347
for cls in &file_input.classes {
340348
let source_row = nodes_by_name_and_file
341349
.get(&(cls.name.as_str(), rel_path.as_str()))
342-
.and_then(|v| v.iter().find(|n| {
343-
n.kind == "class" || n.kind == "struct" || n.kind == "record" || n.kind == "enum"
344-
}));
350+
.and_then(|v| v.iter().find(|n| HIERARCHY_SOURCE_KINDS.contains(&n.kind.as_str())));
345351

346352
if let Some(source) = source_row {
347353
if let Some(ref extends_name) = cls.extends {
348354
let targets = nodes_by_name
349355
.get(extends_name.as_str())
350356
.map(|v| v.iter().filter(|n| {
351-
n.kind == "class" || n.kind == "struct" || n.kind == "trait" || n.kind == "record"
357+
EXTENDS_TARGET_KINDS.contains(&n.kind.as_str())
352358
}).collect::<Vec<_>>())
353359
.unwrap_or_default();
354360
for t in targets {
@@ -366,7 +372,7 @@ pub fn build_call_edges(
366372
.get(implements_name.as_str())
367373
.map(|v| {
368374
v.iter()
369-
.filter(|n| n.kind == "interface" || n.kind == "class" || n.kind == "trait")
375+
.filter(|n| IMPLEMENTS_TARGET_KINDS.contains(&n.kind.as_str()))
370376
.collect::<Vec<_>>()
371377
})
372378
.unwrap_or_default();

0 commit comments

Comments
 (0)