Repository navigation
Conversation
detect_unreachable_code produced three classes of false positive on C#:
1. `yield_statement` was listed as a control-flow terminator, with a
comment conceding it is "not strictly terminating". Consecutive
`yield return` statements in an iterator are all reachable - each
resumes when the caller pulls the next element - so any iterator with
more than one yield in a block was flagged.
2. C# local functions are hoisted, so `return result; void Check(...) {}`
is idiomatic rather than dead code, but the declaration following the
return was reported.
3. Nodes inside a tree-sitter ERROR region were reported. Where the
parser lost sync the tree no longer describes real control flow, so a
"statement" after a terminator there is a parse artifact.
On a 211k-LOC C# codebase these accounted for every unreachable_code
finding: 7 reported, 7 false.
Real dead code after a return is still reported; a regression test pins
that alongside the three fixes.
|
Reviewed against Hoisted local functions launder genuinely dead code. The new "don't flag hoisted declarations" logic lives inside the Your own (self-closed) #725 handled this correctly: skip hoisted declarations via Two smaller items: #725 also dropped the terminator across |
Problem
detect_unreachable_codereports reachable C# as dead code. On a 211k-LOCC# codebase it produced 7
unreachable_codefindings and all 7 were false:Three distinct causes:
yield_statementwas in_TERMINATOR_TYPES, with a comment conceding itis "not strictly terminating, but often last in generators". Consecutive
yield returnstatements in an iterator are all reachable — each resumes whenthe caller pulls the next element — so any iterator with more than one yield
in a block got flagged.
C# local functions are hoisted.
return result;followed byvoid Check(int code, string op) { ... }is idiomatic C#, but the declarationafter the return was reported as unreachable.
Nodes inside a tree-sitter
ERRORregion were reported. Where the parserloses sync the tree no longer describes real control flow; the
WasapiAudioCapture.cs:907hit above is anERRORnode whose text is just}.Fix
yield_statementfrom_TERMINATOR_TYPES. It is not a terminator in anysupported language (Python yields parse as
expression_statement, JS asyield_expression), so this only removes the C# false positives._HOISTED_DECLARATION_TYPES = {"local_function_statement"}and skip thosewhen scanning past a terminator.
ERRORnodes when reporting.After the fix those same four files report
[].Tests
Four regression tests added to
TestUnreachableCode:test_csharp_local_function_after_return_is_reachabletest_csharp_consecutive_yields_are_reachabletest_error_nodes_are_not_reported_as_unreachabletest_csharp_statement_after_return_is_still_flagged— pins that genuine deadcode after a
returnis still reported, so this does not weaken the detector.python -m pytest desloppify/tests/lang/ -q→ 603 passed. The two failures intest_treesitter_imports_direct.pyand the 34 in the full suite are present onan unmodified checkout of
mainand are unrelated to this change.🤖 Generated with Claude Code