build: adopt SecuritySharp and PerformanceSharp analyzers and refresh…
… dependencies (#1651)
* build: adopt SecuritySharp and PerformanceSharp analyzers and refresh dependencies
- Add SecuritySharp.Analyzers and PerformanceSharp.Analyzers; bump
StyleSharp.Analyzers to 3.38.1 (the three share one suite release)
- Adapt the shared .editorconfig to the suite, keeping Splat's file header
and the Platforms RS0041 exemption
- Update NuGet packages to their latest compatible stable versions, obeying
the per-TFM constraints in the packages file; hold Microsoft.ApplicationInsights
at 2.23.0 (3.x removes PageViewTelemetry from Splat.ApplicationInsights' public API)
- Fix every resulting analyzer finding across product and test code rather than
suppressing it; add real assertions to no-assertion tests; save sources as UTF-8
without a BOM
* build: fix analyzer findings on the Apple and Windows target frameworks
The Apple (Cocoa) platform files and the Windows-target test build were not
reachable from the Linux multi-TFM build, so these only surfaced on CI:
- Cocoa CocoaBitmap/PlatformBitmapLoader/SplatColorExtensions: Volatile.Read on
the interlocked field (snapshotting for the closure), delete redundant
suppressions, RunContinuationsAsynchronously on the TaskCompletionSource,
observe-then-throw null fallbacks, interpolated strings, uppercase float
suffix, extension-block ordering, and drop the unused UIApplication alias
- BitmapLoaderCoverageTests: add the explicit System.IO using so Stream resolves
on the Windows target frameworks (their implicit usings omit it)
* test: cover the new analyzer-fix code paths
Add behavioral tests exercising the lines introduced when fixing the analyzer
findings: the exception-observing catch blocks (throwing-disposable disposal and
throwing resolver-changed callbacks), the extra registration overloads that use
GetValueRefOrAddDefault, the IFormatProvider single-value logger overloads, the
service-collection unwrap loops, and the achromatic SplatColor paths. Each test
asserts real behavior.
The few remaining uncovered lines are genuinely-unreachable defensive/off-platform
code (nested catches whose inner guard always fires, BCL-guard catches with no
injection seam, and the WPF/Silverlight design-mode reflection that resolves only
on a real XAML host).
* refactor(drawing): merge the identical net4/net6 WPF platform files
The net4 (.NET Framework) and net6 (net*-windows) platform folders both target
WPF (UseWPF is set for both TFM sets) and had byte-identical copies of the colour,
geometry and bitmap extension files. Move the seven shared files into a single
Platforms/Wpf/ folder compiled on both TFM sets, removing the duplication the
Sonar new-code gate flagged. BitmapSourceBitmap keeps its two versions (their
Save implementations genuinely differ).
* fix(drawing): restore RegisterPlatformBitmapLoader registration and doc crefs
- RegisterPlatformBitmapLoader had been collapsed to an expression body (an
SST2275 auto-fix on the modern targets, where the conditional body is empty),
which dropped the actual IBitmapLoader registration on the WPF / .NET Framework
targets. Restore the conditional registration and scope-suppress SST2275.
- Correct two XML doc crefs surfaced in review: the Rect FromNative summary said
Point, and the Color FromNative summary said SolidColorBrush.
* test: bring the touched product files to 100% line and branch coverage
Add ~500 behavioral tests across the adapter, logger, resolver, drawing and
core projects so every reachable line and branch in the files this PR touched is
exercised (logger overload families, registration/resolution edge cases,
disposal and callback-failure paths, colour conversions, mode detection).
Where code is genuinely unreachable, extract the smallest wrapping method and
mark it [ExcludeFromCodeCoverage] (off-platform design-mode reflection, defensive
catches whose guarded call cannot throw, non-null field disposal). A few provably
dead branches are removed outright (a redundant null-conditional, a dead
already-immutable guard, an unreachable batch-eviction path).
* fix(prism): correct inverted condition in named parameterized Resolve
Resolve(Type, string name, params) had an inverted TryGetValue check, so a
registered named type always returned null (and threw) and the CreateInstance
arm was dead. Match the sibling unnamed overload; add a success test and drop
the test that had pinned the buggy throw-when-registered behavior.
* refactor(core): extract shared resolver exception and dictionary helpers
Replace the 12 duplicated exception-swallowing disposal/callback blocks across
ModernDependencyResolver, GlobalGenericFirstDependencyResolver and
InstanceGenericFirstDependencyResolver with a single
ResolverExceptionHelpers.RunSwallowingExceptions(Action) helper, and share the
GetValueRefOrAddDefault get-or-add via ResolverDictionaryHelpers.GetOrAddValue.
Removes the Sonar new-code duplication in the resolver family.
* refactor(core): close residual coverage gaps in resolvers and mode detection
- Splat mode detection/TFM: extract pure matcher (NameContainsAnyMarker),
add net11.0 target-framework moniker mapping, remove provably-dead
AssemblyQualifiedName null guard, minimal ExcludeFromCodeCoverage on
OS/permission-sensitive probe scaffolding, add tests.
- Splat.Core resolver family: remove dead ThrowIf-follow returns and
null guards, scope copy-on-write / double-checked-lock race guards
into minimal ExcludeFromCodeCoverage helpers.