Skip to content

feat(parser): emit reference edges from function annotations to types#51

Merged
smochan merged 2 commits into
mainfrom
feat/handler-param-references
May 30, 2026
Merged

feat(parser): emit reference edges from function annotations to types#51
smochan merged 2 commits into
mainfrom
feat/handler-param-references

Conversation

@smochan

@smochan smochan commented May 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Functions/methods now emit `CALLS` edges with `dst="unresolved::"` for each capitalized type name in their parameter and return type annotations.
  • Existing resolver rewrites them to real `CLASS` ids when the type is in-repo.
  • Closes the loop for dead-code detection: FastAPI Pydantic request-body models like `def create_defect(body: RetroDefect)` are no longer flagged dead.
  • Framework-agnostic — any function with annotations benefits.
  • Stdlib typing scaffolding and FastAPI dependency markers are blocklisted.

v0.1.2 backlog item #3.

Test plan

  • 6 new unit tests in `tests/test_param_annotation_refs.py` (extractor + fixture FastAPI repo).
  • Full Python suite green (602 passed).
  • Self-graph rebuild: no new dead-code regressions (36 pre-existing findings in `bench/` registry-loaded runners).

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

codegraph PR review

Diff vs main · severity ≤ high

codegraph review (target: main)

Diff: +11 / -0 / ~0 nodes, +54 / -0 edges

Findings (0)

No findings.

Triggered by codegraph CI · last run

smochan added 2 commits May 30, 2026 22:36
The `unresolved_edges` count conflated two very different things:

1. External imports — `fastapi`, `os`, `react`. Static analysis without
   a venv/site-packages parse can't resolve these and isn't supposed to.
   These are expected, not errors.
2. Local-unresolved — target's root module IS in the repo but the
   specific symbol couldn't be matched (rename drift, dynamic import,
   missed binding). These are the actionable ones.

`compute_metrics` now classifies each unresolved edge by checking whether
the target's root module appears as a MODULE node's qualname-root in the
graph. New fields: `external_edges`, `unresolved_local_edges`. The
`unresolved_edges` total is kept as the sum for back-compat.

Surfaced + exposed in the markdown report and the MCP `metrics` tool.

v0.1.2 backlog item #2.
FastAPI Pydantic request-body models were being flagged dead because
the only reference to them came through a handler's parameter type
annotation, which the Python parser didn't trace.

The parser now walks each function's parameter `type` strings and the
return-type string, regex-extracts capitalized identifiers, drops
typing-scaffolding (`Optional`, `Annotated`, `Union`, ...) and FastAPI
dependency markers (`Body`, `Depends`, ...), and emits one
`CALLS` edge with `dst="unresolved::<TypeName>"` and
`metadata.via == "annotation"` per surviving name. The existing
resolver rewrites these to real `CLASS` ids when the type is in-repo,
which closes the loop for dead-code detection.

Framework-agnostic: every function with type annotations benefits, not
just route handlers. The change reuses `EdgeKind.CALLS` (rather than
introducing a new `REFERENCES` kind) because `CALLS` already flows
through the resolver and the reference-kind whitelist used by
dead-code, and Pydantic-body validation IS effectively a runtime call
into the model class.

v0.1.2 backlog item #3.
@smochan smochan force-pushed the feat/handler-param-references branch from 4dff616 to 441d364 Compare May 30, 2026 17:07
@github-actions

Copy link
Copy Markdown

codegraph PR review

Diff vs main · severity ≤ high

codegraph review (target: main)

Diff: +21 / -0 / ~0 nodes, +90 / -0 edges

Findings (0)

No findings.

Triggered by codegraph CI · last run

@smochan smochan merged commit 492672f into main May 30, 2026
5 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators May 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant