fix(graph): address Qodo code-review findings on REFERENCES edges - #3
Merged
Conversation
Follow-up to the reference-edges feature. Seven review findings: 1. Case-insensitive store traversals. The seed lookup is case-insensitive (eq_ignore_ascii_case) but symbol_references, related_to_symbol's declaration lookup, and symbol_type_relations matched names case-sensitively, so `--symbol widget` seeded on `Widget` but returned no usages. Ladybug now uses `WHERE lower(name) = $n` with a lowercased param; memory uses eq_ignore_ascii_case. Applies to references AND the pre-existing type relations. 2. Segment-safe same-project check. `file_path.starts_with(project_prefix)` treated `src2/foo` as same-project as `src`. Added same_project_dir() (a strip_prefix + '/'-boundary check) and used it in both resolve_references and resolve_supertypes. 3. Single source of truth for the memory reference traversal: extracted collect_references(); related_to_symbol and symbol_references both call it. 4. Surface extraction failures at warn (was debug) in extract / extract_supertypes / extract_references, so silent undercounts are visible. Goes to stderr, so the stdout=data contract is preserved. 5. remove_file now prunes symbol edges whose *either* endpoint no longer exists (was: only edges originating from the file), so reference_edges isn't inflated by dangling edges into a removed declaration. Applied to inherits/implements too. 6. resolve_references no longer does N+1 store queries: it preloads each file's declarations once (name -> symbols) for the `from` lookup and caches `to` candidates per name across files. 7. Deterministic `from` selection: same-name/same-file declarations are sorted by (start_line, end_line, id) before picking, instead of relying on arbitrary order. Tests: case-insensitive reference lookup, segment-safe same-project resolution (src vs src2), and remove_file pruning incoming reference edges. All existing tests pass; fmt + clippy clean. Verified case-insensitive lookups end-to-end on a real C# repo (lowercase and PascalCase queries return identical reference sites).
Review Summary by QodoFix case-insensitive lookups and same-project resolution in reference edges
WalkthroughsDescription• Fix case-insensitive symbol lookups across all stores (Ladybug/memory) - Seed lookup was case-insensitive but reference/type-relation queries were case-sensitive - Now uses lower(name) in Ladybug and eq_ignore_ascii_case in memory store • Implement segment-safe same-project directory matching - Previous starts_with() check treated src2/foo as same-project as src - New same_project_dir() function enforces /-boundary checks • Fix remove_file to prune incoming reference edges - Previously only removed edges originating from deleted file - Now removes edges whose either endpoint no longer exists • Eliminate N+1 queries in resolve_references - Preload file declarations once per file and cache target candidates by name • Improve determinism and maintainability - Sort same-name declarations by (start_line, end_line, id) for deterministic selection - Extract collect_references() as single source of truth for both stores - Elevate extraction failures from debug to warn level for visibility Diagramflowchart LR
A["Symbol Lookup"] -->|case-insensitive| B["Ladybug Store"]
A -->|case-insensitive| C["Memory Store"]
B -->|lower name| D["Query Results"]
C -->|eq_ignore_ascii_case| D
E["File Removal"] -->|prune both endpoints| F["Reference Edges"]
G["Reference Resolution"] -->|segment-safe check| H["Same-Project Filter"]
G -->|preload & cache| I["Deterministic Selection"]
File Changes1. src/graph/ladybug_store.rs
|
Code Review by Qodo
1. Wrong enclosing symbol pick
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the reference-edges feature (#1), addressing the seven Qodo review findings. Each is verified with a test and/or on a real repo.
Correctness
symbol_references,related_to_symbol's declaration lookup, andsymbol_type_relationsmatched names case-sensitively. So--symbol widgetseeded onWidgetbut returned no usages. Ladybug now usesWHERE lower(name) = $n(lowercased param); memory useseq_ignore_ascii_case. Also fixes the same latent issue in the pre-existing type-relation queries.file_path.starts_with(project_prefix)treatedsrc2/fooas same-project assrc. Addedsame_project_dir()(astrip_prefix+/-boundary check) used in bothresolve_referencesandresolve_supertypes.remove_fileedge cleanup — previously pruned only edges originating from the removed file, leaking edges that point at a symbol the file declared and inflating the user-visiblereferenceEdgesstat. Now retains only edges whose both endpoints still exist (applied to inherits/implements too).Determinism & perf
resolve_referencespreloads each file's declarations once (name -> symbols) for thefromlookup and cachestocandidates per name across files, instead of two store queries per reference.fromselection — same-name/same-file declarations are sorted by(start_line, end_line, id)before picking, rather than relying on arbitrary order.Maintainability & visibility
collect_references(); bothsymbol_referencesandrelated_to_symbolcall it (was duplicated inline).warn(wasdebug) inextract/extract_supertypes/extract_references, so silent undercounts are visible. Goes to stderr, so thestdout=datacontract holds.Tests
New: case-insensitive reference lookup, segment-safe same-project resolution (
srcvssrc2), andremove_filepruning incoming reference edges. All existing tests pass;cargo fmt --check,cargo clippy --all-targets, andcargo test(78 tests) all green. Verified case-insensitive lookups end-to-end on a real C# repo — lowercase and PascalCase queries return identical reference sites.