fix(extraction): preserve symbols with colliding same-line IDs (#1349) (#2030)

Same-kind, same-name declarations on one line shared an ID and silently overwrote each other in SQLite.
Use per-extraction collision tracking to append a UTF-16 column only to later distinct declarations.
Apply the same rule across wasm, Rust language walkers, Liquid, and CFML while preserving file IDs and edge endpoints.
Add persistence, call-edge, identity-vector, and Unicode parity regressions.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-09-27 13:35:19 +00:00
committed by GitHub
co-authored by Claude Opus 5.5
parent e27d6da6b2
commit 86708bf519
25 changed files with 329 additions and 31 deletions
+4 -1
View File
@@ -130,6 +130,7 @@ pub struct Walker<'t> {
file_path: &'t str,
line_starts: Vec<usize>,
arena: Arena,
node_id_allocator: ids::NodeIdAllocator,
tables: Tables,
stack: Vec<Scope>,
/// Node id string per row — ids COLLIDE for same-(kind, name, line) nodes
@@ -162,6 +163,7 @@ pub fn extract(file_path: &str, source: &str) -> Result<EmitOut, String> {
file_path,
line_starts: util::line_starts(source),
arena: Arena::default(),
node_id_allocator: ids::NodeIdAllocator::default(),
tables: Tables::default(),
stack: Vec::new(),
node_ids: Vec::new(),
@@ -317,7 +319,8 @@ impl<'t> Walker<'t> {
return None;
}
let start_line = self.line_of(node);
let id = ids::node_id(self.file_path, kind, name, start_line);
let column = self.col_of(node);
let id = self.node_id_allocator.generate(self.file_path, kind, name, start_line, column);
let end_line = node.end_position().row as u32 + 1; // no resolveBody for csharp
let qualified = {