fix: stop reporting reachable C# code as unreachable - #735
Open
SirCrest wants to merge 1 commit into
Open
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.
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.
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