Skip to content

feat(dead-code): report unreachable classes via INSTANTIATES and INHERITS reachability#544

Merged
vitali87 merged 2 commits into
mainfrom
feat/dead-code-classes
Jun 28, 2026
Merged

feat(dead-code): report unreachable classes via INSTANTIATES and INHERITS reachability#544
vitali87 merged 2 commits into
mainfrom
feat/dead-code-classes

Conversation

@vitali87

Copy link
Copy Markdown
Owner

Summary

Adds class-level dead-code detection to cgr dead-code via a new --classes flag, backed by a new INSTANTIATES relationship. This preserves the existing invariant that CALLS only ever targets functions and methods (never a class node).

What changed

  • New INSTANTIATES relationship ((Module|Function|Method) -[INSTANTIATES]-> (Class)): class construction now emits INSTANTIATES -> class for every construction, plus CALLS -> __init__ only when the class defines one. Classless constructions (dataclass / NamedTuple / pydantic) are represented by INSTANTIATES alone, so CALLS stays function/method-only.
  • --classes/--no-classes flag (off by default). When on, reachability walks [:CALLS|INSTANTIATES|INHERITS*0..] and module-load roots are reached via [:CALLS|INSTANTIATES], so a class is reported only when nothing instantiates or subclasses it.
  • L2 module-call eval now credits module-scope INSTANTIATES edges so classless construction keeps recall at 1.0.

Caveats (documented in --classes help)

Classes referenced only via type annotations, isinstance, or dynamic lookups are not modelled as edges, so class candidates are review hints, not a guaranteed delete list.

Verification

  • 81 dead-code / cypher / constructor / class tests pass, including Memgraph integration (confirms the multi-rel variable-length traversal runs on Memgraph).
  • 1511 broad parser/call regression tests pass.
  • RED -> GREEN demonstrated for the new eval test.
  • ruff, ty (no new diagnostics vs main), and check_no_docs.py all clean locally.
  • End-to-end against real Memgraph: a fixture with a dataclass, a class with __init__, an inheritance pair, and an orphan class reports only the orphan under --classes; all instantiated/subclassed classes are correctly live.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for identifying unreachable classes in the dead-code analysis tool. It adds a new --classes CLI option, introduces an INSTANTIATES relationship type to track class construction (especially for classes without an explicit __init__ method), and updates the Cypher query generation to traverse INSTANTIATES and INHERITS relationships when the classes flag is enabled. Comprehensive unit and integration tests have been added to verify these changes. I have no further feedback to provide as there are no review comments.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@greptile-apps

greptile-apps Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds class-aware dead-code reporting. The main changes are:

  • New INSTANTIATES edges for class construction.
  • Optional --classes dead-code query mode.
  • Reachability traversal across calls, instantiations, and inheritance.
  • Updated eval logic for module-scope class construction.
  • Tests for class candidates and constructor edge behavior.

Confidence Score: 5/5

The changes appear merge-safe with no code issues identified.

The implementation is well-scoped, covered by targeted tests, and no blocking correctness concerns were found in the changed code.

T-Rex T-Rex Logs

What T-Rex did

  • Observed the base construction-edges run labeled Before, which showed no INSTANTIATES edges and only calls to Widget.__init__.
  • Observed the head construction-edges run labeled After, which showed INSTANTIATES edges use_config -> Class Config and use_widget -> Class Widget, plus a CALL from use_widget to Widget.__init__, with CALLS never targeting Class: True.
  • Executed the dead-code-classes query fixture baseline; base signature was (include_tests: bool) and attempting to pass include_classes raised a TypeError, with the fixture run blocked by an interpreter mismatch; no bug report was filed.
  • Compared before/after module-call graph for the Config class; after state shows Config included in cgr_module_calls and oracle_module_calls, Config credited by cgr, and a NameEdge emitted from app.py to Config.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "docs(dead-code): clarify base classes ar..." | Re-trigger Greptile

Comment thread codebase_rag/cypher_queries.py
@vitali87

Copy link
Copy Markdown
Owner Author

@greptile review

@vitali87 vitali87 merged commit ef69b18 into main Jun 28, 2026
2 of 15 checks passed
@vitali87 vitali87 deleted the feat/dead-code-classes branch June 28, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant