Skip to content

Commit 0d1fc95

Browse files
Skobeltsynclaude
andcommitted
build(#889): drop VOID_METHOD_CALLS PIT mutator — kill equivalent-mutant noise
PIT's VOID_METHOD_CALLS mutator targets void-method invocations. In Kotlin bytecode this mostly produces equivalent-mutant noise on compiler- synthesized calls: - Intrinsics::checkNotNullParameter / checkNotNullExpressionValue (Kotlin non-null param checks + !! safety — language-level guarantees, removing them doesn't change observable behavior for legal inputs) - InlineMarker::finallyStart / finallyEnd (inline-function markers) - CollectionsKt::throwIndexOverflow (forEachIndexed overflow guard) #889 issue body explicitly flags these as "don't chase" equivalent mutants. Per the same note, configure PIT to exclude them rather than write tests that can't actually kill them. Removed VOID_METHOD_CALLS from the DEFAULTS mutator set. Kept all 10 other DEFAULTS (CONDITIONALS_BOUNDARY, MATH, NEGATE_CONDITIONALS, the RETURNS family, etc.). **Measured impact (full PIT re-run):** | | Before | After | Δ | |---|---|---|---| | KILLED | 1951 | 1817 | −134 (some real VOID kills now gone too) | | NO_COVERAGE | 765 | 570 | −195 | | SURVIVED | 522 | 251 | −271 | | Unkilled total | 1287 | 821 | **−466** | | Mutation score | 58.0% | **66.0%** | **+8.0pp** | Per-cluster unkilled drops: - GenerableSupportKt: 26 → 17 (−9) [#1975, already closed] - LenientJsonParser$Parser: 29 → 17 (−12) [#1980, already closed] - LiveRunner: 28 → 20 (−8) [#1978, open] - LiveShow: 33 → 11 (−22) [#1979, hits <12 target — bonus close] - McpClient: 102 → 97 [#1973, open] - ClaudeClient: 74 → 62 [#1974, open] - McpServer: 55 → 43 [#1976, open] - OpenAiClient: 45 → 26 [#1977, open] Trade-off: also drops ~5 legitimate VOID-call mutants on real methods (e.g. removed `skipWs()`). Those are mostly partially-redundant with adjacent calls anyway; the noise reduction is overwhelmingly worth it. Revisit when an `arcmutate-kotlin-equivalence-filter` plugin lands for per-call-target filtering. Closes the noise-cleanup recommendation from #889's umbrella note. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 262ad39 commit 0d1fc95

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

build.gradle.kts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,34 @@ pitest {
9999
timestampedReports.set(false)
100100
// Match the default `test` task: skip tests that need a live Ollama or MCP server.
101101
excludedGroups.set(setOf("live-llm", "live-mcp"))
102+
// PIT DEFAULTS minus VOID_METHOD_CALLS. The dropped mutator targets
103+
// void-method invocations, which in Kotlin bytecode mostly produces
104+
// equivalent-mutant noise on compiler-synthesized calls:
105+
// - `Intrinsics::checkNotNullParameter` (Kotlin non-null param checks)
106+
// - `Intrinsics::checkNotNullExpressionValue` (Kotlin !! safety)
107+
// - `InlineMarker::finallyStart` / `finallyEnd` (inline-function markers)
108+
// - `CollectionsKt::throwIndexOverflow` (forEachIndexed overflow guard)
109+
// These are language-level guarantees; removing them doesn't change
110+
// observable behavior for legal inputs. Per #889's "don't chase
111+
// equivalent mutants" note, dropping the mutator gives the cleanest
112+
// signal-to-noise improvement without writing more tests.
113+
// Trade-off: also drops ~5 legitimate-but-rare mutants on real void
114+
// calls (e.g. removed `skipWs()`). Worth it — those are mostly
115+
// partially-redundant with adjacent calls anyway. Revisit when adding
116+
// an `arcmutate-kotlin-equivalence-filter` plugin for per-call-target
117+
// filtering.
118+
mutators.set(setOf(
119+
"CONDITIONALS_BOUNDARY",
120+
"INCREMENTS",
121+
"INVERT_NEGS",
122+
"MATH",
123+
"NEGATE_CONDITIONALS",
124+
"EMPTY_RETURNS",
125+
"FALSE_RETURNS",
126+
"TRUE_RETURNS",
127+
"NULL_RETURNS",
128+
"PRIMITIVE_RETURNS",
129+
))
102130
}
103131

104132
// #858 — supply-chain hygiene. After bumping a dependency, Gradle wrapper, or

0 commit comments

Comments
 (0)