parser: tag CALLS edges inside dead guards with reachable flag#580
Open
HouMinXi wants to merge 2 commits into
Open
parser: tag CALLS edges inside dead guards with reachable flag#580HouMinXi wants to merge 2 commits into
HouMinXi wants to merge 2 commits into
Conversation
Calls inside `if False:` and `if TYPE_CHECKING:` blocks are statically unreachable but the parser still emits CALLS edges for them, causing false positives in dead-code detection and impact analysis. Add a lightweight ancestor-walk helper that detects these two common Python idioms and sets extra["reachable"] = False on the affected CALLS edges. Live edges omit the key entirely so existing graph.db files remain forward-compatible (absent key means live). The detection covers all Tree-sitter languages routed through _extract_calls. Bespoke handlers (ReScript, Dart, Elixir) and C preprocessor guards (#if 0) are left for follow-up work. Closes tirth8205#576 Signed-off-by: Minxi Hou <houminxi@gmail.com>
|
Nice implementation! I reported #576 and this is exactly what I had in mind. The scope boundary check (stopping at function/class/module) is the right call — a dead guard in an outer scope shouldn't propagate to nested definitions. Tagging with One small thing: might be worth handling |
Extend _is_in_static_dead_guard to recognize the integer literal 0 as a dead condition, alongside False and TYPE_CHECKING. The if 0: pattern appears in C-extension bindings and some legacy codebases. In tree-sitter-python, 0 parses as an "integer" node with text b"0", so the check mirrors the existing "false" node check. Suggested-by: tirth8205 (PR tirth8205#580 review) Signed-off-by: Minxi Hou <houminxi@gmail.com>
Author
|
Good catch -- added |
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.
Linked issue
Closes #576
What & why
Calls inside
if False:andif TYPE_CHECKING:blocks are staticallyunreachable, but the parser emits CALLS edges for them anyway. This
causes false positives in dead-code detection (
refactor_toolmodedead_code) and inflates impact-radius results.This PR adds a lightweight ancestor-walk helper
_is_in_static_dead_guard()that detects these two common Pythonidioms and sets
extra["reachable"] = Falseon the affected CALLSedges. Live edges omit the key entirely, so:
graph.dbfiles remain forward-compatible (absent key =live).
json_extract(extra, '$.reachable') IS NULL OR json_extract(extra, '$.reachable') != 0Scope
_extract_calls(Python, JS/TS, Go, Rust, C, C++, Java, etc.).Elixir), C preprocessor guards (
#if 0). These are left forfollow-up.
Design choice: ancestor walk vs threaded flag
Chose ancestor walk (approach b from #576 discussion) over threading
a flag through
_extract_from_treebecause it requires zero signaturechanges, keeps the diff minimal, and is O(scope-depth) per call node
-- negligible overhead.
How it was tested
Bug-inject verification: neutralized the guard check (
if False and ...) -- test failed ondead_false_calledge missing the flag.Restored -- test passed.
Real-path smoke test: parsed a Python file with
if False:andif TYPE_CHECKING:calls outside the test suite; confirmed live callsshow
reachable=ABSENTand dead calls showreachable=False.Checklist
uv run pytest tests/ --tb=short -quv run ruff check code_review_graph/