Repository navigation
refactor(analyser): split null guard from out-var check in code fix providers - #848
Merged
Merged
Conversation
…roviders In RegisterCodeFixesAsync of the Count, Length, NullOrEmpty and OutOfRange code fix providers the null check of the if statement was chained with the TryGet... out-var check in a single || condition. Stryker mutants of that guard break definite assignment of the out variable (CS0165), which makes Stryker enter Safe Mode and drop all mutants of the whole method as compile errors. Splitting the guard into two statements keeps the behaviour identical and lets the mutants be compiled and tested.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #848 +/- ##
==========================================
+ Coverage 90.75% 91.31% +0.55%
==========================================
Files 39 39
Lines 2185 2187 +2
Branches 381 385 +4
==========================================
+ Hits 1983 1997 +14
+ Misses 121 113 -8
+ Partials 81 77 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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
The latest mutation run (Stryker 5.0.0, solution mode, MTP runner) logs for four code fix providers:
Same for ThrowIfLengthCodeFixProvider (46:45), ThrowIfNullOrEmptyCodeFixProvider (45:45,
helperName) and ThrowIfOutOfRangeCodeFixProvider (46:55). According to the mutation report these files have 23, 23, 23 and 26 CompileError mutants (95 in total; per-file counts come from the report, not the log) with 0 Killed/Survived. Overall 439 of 1749 mutants (25.1 %) are compile errors.Root cause
In
RegisterCodeFixesAsyncthe guard wasifStatement is null || !TryGet...(..., out var x) || x is null. Some mutants of this combined condition break definite assignment of the out variable (CS0165), Stryker cannot recover the single mutant and removes all mutants of the method. The identified trigger is the out-var combined with the precedingifStatement is null ||operand; the proof is the before/after Stryker run, not the source reading alone.Change
Split the guard into
if (ifStatement is null) { return; }andif (!TryGet...(..., out var x) || x is null) { return; }in the fourRegisterCodeFixesAsyncmethods. Nothing else is touched (ApplyFixAsyncand the other providers are intentionally left alone; the log shows no Safe Mode for them).Before / After
Run: https://github.com/dailydevops/arguments/actions/runs/40806141355 (mutation.yml on this branch) vs. the latest run on main (2026-10-27).
Honest reading: the Safe Mode removals and CS0165 warnings are gone and 60 fewer mutants are compile errors (less than the estimated 95). Those mutants were reclassified, not made testable: they now show up as NoCoverage (+48) and Ignored (+16), the tested set (435) and killed/survived counts are unchanged. Because NoCoverage mutants count against the score, the overall score drops from 27.10 % to 25.82 % even though the report is now more accurate. Killing these mutants requires tests that exercise
RegisterCodeFixesAsyncof the four providers; that is out of scope here.Risk / what this does not change
Pure restructuring of an early-return guard; behaviour is identical. The build passes locally; the local test run could not be executed here (apphost copy error), so CI is the check.