From 7737098a54eb2ec87971db4dffbcbf903d7737df Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Tue, 3 Mar 2026 12:42:42 -0800 Subject: [PATCH] fix: suppress MA0077 on ref struct types and fix variable shadowing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref struct types (BatchOutputs, BatchInputs, ScalarState, WorkBuffers) cannot implement IEquatable — C# prohibits interface implementation on ref structs. Added #pragma warning disable/restore MA0077 at type declaration level in AccBands.cs, Aberr.cs, Apz.cs (9 ref structs). Renamed local 'output' to 'result' in Wma.Coverage.Tests.cs to avoid shadowing the primary constructor ITestOutputHelper parameter (S1117/MA0084). --- lib/channels/aberr/Aberr.cs | 6 ++++++ lib/channels/accbands/AccBands.cs | 8 ++++++++ lib/channels/apz/Apz.cs | 4 ++++ lib/trends_FIR/wma/Wma.Coverage.Tests.cs | 12 ++++++------ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/channels/aberr/Aberr.cs b/lib/channels/aberr/Aberr.cs index cfcd7af3..9bde5ec7 100644 --- a/lib/channels/aberr/Aberr.cs +++ b/lib/channels/aberr/Aberr.cs @@ -412,6 +412,7 @@ public sealed class Aberr : ITValuePublisher, IDisposable /// /// Output buffers for batch Aberr calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] #pragma warning disable S1104 // Fields should not have public accessibility public readonly ref struct BatchOutputs @@ -447,10 +448,12 @@ public sealed class Aberr : ITValuePublisher, IDisposable public static bool operator ==(BatchOutputs left, BatchOutputs right) => left.Equals(right); public static bool operator !=(BatchOutputs left, BatchOutputs right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Internal state for scalar calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] [SuppressMessage("NDepend", "ND1903:StructuresShouldBeImmutable", Justification = "Mutable calculation state accumulator by design")] private ref struct ScalarState @@ -471,10 +474,12 @@ public sealed class Aberr : ITValuePublisher, IDisposable public static bool operator ==(ScalarState left, ScalarState right) => left.Equals(right); public static bool operator !=(ScalarState left, ScalarState right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Working buffers for batch calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] private readonly ref struct WorkBuffers(Span source, Span deviation) { @@ -492,6 +497,7 @@ public sealed class Aberr : ITValuePublisher, IDisposable public static bool operator ==(WorkBuffers left, WorkBuffers right) => left.Equals(right); public static bool operator !=(WorkBuffers left, WorkBuffers right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Calculates Aberr for the entire TSeries using a new instance. diff --git a/lib/channels/accbands/AccBands.cs b/lib/channels/accbands/AccBands.cs index 88438164..1d0576d6 100644 --- a/lib/channels/accbands/AccBands.cs +++ b/lib/channels/accbands/AccBands.cs @@ -474,6 +474,7 @@ public sealed class AccBands : ITValuePublisher, IDisposable /// Public Span fields are intentional: ref structs cannot use auto-properties with Span<T> /// and direct field access provides optimal performance for this high-throughput API. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] #pragma warning disable S1104 // Fields should not have public accessibility public readonly ref struct BatchOutputs @@ -509,10 +510,12 @@ public sealed class AccBands : ITValuePublisher, IDisposable public static bool operator ==(BatchOutputs left, BatchOutputs right) => left.Equals(right); public static bool operator !=(BatchOutputs left, BatchOutputs right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Input buffers for batch AccBands calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] #pragma warning disable S1104 // Fields should not have public accessibility public readonly ref struct BatchInputs @@ -548,10 +551,12 @@ public sealed class AccBands : ITValuePublisher, IDisposable public static bool operator ==(BatchInputs left, BatchInputs right) => left.Equals(right); public static bool operator !=(BatchInputs left, BatchInputs right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Internal state for scalar calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] [SuppressMessage("NDepend", "ND1903:StructuresShouldBeImmutable", Justification = "Mutable calculation state accumulator by design")] private ref struct ScalarState @@ -576,10 +581,12 @@ public sealed class AccBands : ITValuePublisher, IDisposable public static bool operator ==(ScalarState left, ScalarState right) => left.Equals(right); public static bool operator !=(ScalarState left, ScalarState right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Working buffers for batch calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] private readonly ref struct WorkBuffers(Span adjHigh, Span adjLow, Span close) { @@ -600,6 +607,7 @@ public sealed class AccBands : ITValuePublisher, IDisposable public static bool operator ==(WorkBuffers left, WorkBuffers right) => left.Equals(right); public static bool operator !=(WorkBuffers left, WorkBuffers right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Calculates AccBands for the entire TBarSeries using a new instance. diff --git a/lib/channels/apz/Apz.cs b/lib/channels/apz/Apz.cs index 6c779cfd..a0afa865 100644 --- a/lib/channels/apz/Apz.cs +++ b/lib/channels/apz/Apz.cs @@ -411,6 +411,7 @@ public sealed class Apz : ITValuePublisher /// /// Output buffers for batch APZ calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] #pragma warning disable S1104 // Fields should not have public accessibility public readonly ref struct BatchOutputs @@ -446,10 +447,12 @@ public sealed class Apz : ITValuePublisher public static bool operator ==(BatchOutputs left, BatchOutputs right) => left.Equals(right); public static bool operator !=(BatchOutputs left, BatchOutputs right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Internal state for scalar calculation. /// +#pragma warning disable MA0077 // ref struct cannot implement interfaces [StructLayout(LayoutKind.Auto)] [SuppressMessage("NDepend", "ND1903:StructuresShouldBeImmutable", Justification = "Mutable calculation state accumulator by design")] private ref struct ScalarState @@ -476,6 +479,7 @@ public sealed class Apz : ITValuePublisher public static bool operator ==(ScalarState left, ScalarState right) => left.Equals(right); public static bool operator !=(ScalarState left, ScalarState right) => !left.Equals(right); } +#pragma warning restore MA0077 /// /// Calculates APZ for the entire TBarSeries using a new instance. diff --git a/lib/trends_FIR/wma/Wma.Coverage.Tests.cs b/lib/trends_FIR/wma/Wma.Coverage.Tests.cs index 3bdcab93..09b9ae2d 100644 --- a/lib/trends_FIR/wma/Wma.Coverage.Tests.cs +++ b/lib/trends_FIR/wma/Wma.Coverage.Tests.cs @@ -18,12 +18,12 @@ public class WmaCoverageTests(ITestOutputHelper output) source[i] = i; } - double[] output = new double[len]; + double[] result = new double[len]; // This should trigger CalculateScalarCore internally - Wma.Batch(source.AsSpan(), output.AsSpan(), period); + Wma.Batch(source.AsSpan(), result.AsSpan(), period); - Assert.NotEqual(0, output[period]); + Assert.NotEqual(0, result[period]); } [Fact] @@ -94,11 +94,11 @@ public class WmaCoverageTests(ITestOutputHelper output) source[i] = i; } - double[] output = new double[len]; + double[] result = new double[len]; - InvokePrivateStaticMethod_WithSpans("CalculateScalarCore", source, output, period); + InvokePrivateStaticMethod_WithSpans("CalculateScalarCore", source, result, period); - Assert.NotEqual(0, output[period]); + Assert.NotEqual(0, result[period]); } private delegate void CoreDelegate(ReadOnlySpan source, Span output, int period);