Skip to content

fix(query): include unresolved bare-name targets in references_to - #969

Open
nhuphuoc-bic wants to merge 1 commit into
tirth8205:mainfrom
nhuphuoc-bic:fix/references-to-unresolved-targets
Open

fix(query): include unresolved bare-name targets in references_to#969
nhuphuoc-bic wants to merge 1 commit into
tirth8205:mainfrom
nhuphuoc-bic:fix/references-to-unresolved-targets

Conversation

@nhuphuoc-bic

Copy link
Copy Markdown

Linked issue

No existing issue matched — I searched open and closed issues for references_to, unresolved targets, and workspace aliases and found none. Happy to file one via the issue form if you'd prefer that first.

What & why

references_to returns only the dependents whose REFERENCES edge carries a fully-qualified target (<file>::<Symbol>).

When a module imports a symbol through a specifier the parser cannot resolve — an npm/pnpm workspace alias such as @core/ports, or a tsconfig path mapping — the edge is still recorded, but its target is stored as a bare name. references_to never looks at those, so it drops the dependents silently. There is no confidence note on a non-empty result, so the short answer reads as a complete one.

That failure mode is worse than an empty result: the caller gets a small, plausible number and concludes nothing else depends on the symbol.

Measured on a pnpm workspace monorepo (TypeScript, apps/* + packages/* behind @core/* aliases):

symbol references_to actual dependents
an exported interface 6 12
another exported type 2 10

In both cases every missing dependent lived outside the defining package and imported through the alias. The edges were present in graph.db the whole time, under the bare target name.

callers_of already has exactly this fallback (the iter_edges_by_target_name pass that marks results target_resolution: "unresolved"). This PR mirrors it for references_to, with one added guard: bare-name edges are merged only when count_nodes_by_name(name) == 1, so a name shared by two symbols is never attributed to both. Edges carrying ambiguous_targets are skipped, as in the existing path.

After the change the two queries above return 11 and 9 — the remainder in each case is the barrel index.ts, which re-exports rather than references, so it legitimately produces no REFERENCES edge.

How it was tested

uv run pytest tests/ -q
# 2986 passed, 9 skipped, 2 xpassed in 58.47s

uv run ruff check code_review_graph/
# All checks passed!

uv run mypy code_review_graph/ --ignore-missing-imports --no-strict-optional
# Success: no issues found in 72 source files

The new test test_references_to_includes_alias_imported_dependents builds a fixture whose consumer imports through @core/ports, which the parser cannot resolve. Verified it is a real regression test: with the query.py change reverted it fails with assert 'usePort' in {}, and passes with the change applied.

Checklist

  • Tests added for new functionality
  • All tests pass: uv run pytest tests/ --tb=short -q
  • ruff check clean
  • mypy clean

A module that imports a symbol through a specifier the parser cannot
resolve (npm workspace alias, tsconfig path mapping) gets a REFERENCES
edge whose target is a bare name rather than "<file>::<Symbol>".
references_to matched only fully-qualified targets, so those dependents
were dropped without any signal — the caller reads the short result as
proof that nothing else depends on the symbol.

callers_of already carries the same fallback. Mirror it here, and merge
bare-name edges only when the name identifies exactly one node so a name
shared by two symbols is never attributed to both.

Measured on a pnpm workspace monorepo: references_to for an interface
returned 6 of 12 dependents, and 2 of 10 for another; the missing ones
were all consumers importing across a package boundary.
@tirth8205

Copy link
Copy Markdown
Owner

Integrated on integration/token-efficiency-hardening as 48fc808. Unresolved unique-name references now remain visible, with a correction preserving target_resolution='unresolved' in minimal as well as standard output. Parser and query regressions cover both detail levels and ambiguous names; same-name ambiguity remains unassigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants