diff --git a/.editorconfig b/.editorconfig index ade320b3..276b98b0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,13 @@ insert_final_newline = true # Suppress SonarQube S3776 - Cognitive Complexity # High-performance SIMD code intentionally has complex control flow dotnet_diagnostic.S3776.severity = none + +#### C# Coding Conventions #### + +# "var" preferences +# Prefer explicit types for built-in types (e.g. int, double, string) - reduces noise in math-heavy code +csharp_style_var_for_built_in_types = false:silent +# Prefer var when the type is already mentioned on the right side (e.g. new List()) +csharp_style_var_when_type_is_apparent = true:suggestion +# Prefer explicit types in other cases to improve readability of math formulas +csharp_style_var_elsewhere = false:silent diff --git a/.github/scanner.sh b/.github/scanner.sh index 9c8168ed..5adea0ce 100644 --- a/.github/scanner.sh +++ b/.github/scanner.sh @@ -200,6 +200,12 @@ if [ "$SKIP_QODANA" = false ]; then if command -v qodana &> /dev/null; then log_info "Starting Qodana analysis..." + # Install dependencies required for Qodana (IntelliJ) on minimal Debian + if ! dpkg -s libfreetype6 fontconfig &> /dev/null; then + log_info "Installing missing dependencies (libfreetype6, fontconfig)..." + apt-get update && apt-get install -y libfreetype6 fontconfig + fi + export CI=true qodana scan --within-docker=false -l qodana-dotnet --coverage-dir "$COVERAGE_DIR" || true diff --git a/.vscode/settings.json b/.vscode/settings.json index 67bb6fb2..cb5c2c72 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -164,8 +164,6 @@ "dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true, "dotnet.server.useOmnisharp": false, - "testing.automaticallyOpenPeekView": "never", - "testing.openTesting": "neverOpen", "sonarlint.connectedMode.project": { "connectionId": "mihakralj-quantalib", "projectKey": "mihakralj_QuanTAlib" diff --git a/lib/averages/sma/Sma.cs b/lib/averages/sma/Sma.cs index 4b394357..52a9599f 100644 --- a/lib/averages/sma/Sma.cs +++ b/lib/averages/sma/Sma.cs @@ -1,3 +1,4 @@ +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -300,6 +301,7 @@ public sealed class Sma } [MethodImpl(MethodImplOptions.AggressiveOptimization)] +#pragma warning disable S6640 // Unsafe code is required for high-performance SIMD operations private static unsafe void CalculateSimdCore(ReadOnlySpan source, Span output, int period) { int len = source.Length; @@ -370,6 +372,7 @@ public sealed class Sma } } } +#pragma warning restore S6640 /// /// Checks if span contains any non-finite values (NaN or Infinity). diff --git a/lib/averages/wma/Wma.cs b/lib/averages/wma/Wma.cs index f9c69a60..d65e4927 100644 --- a/lib/averages/wma/Wma.cs +++ b/lib/averages/wma/Wma.cs @@ -1,3 +1,4 @@ +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -285,6 +286,7 @@ public sealed class Wma } [MethodImpl(MethodImplOptions.AggressiveOptimization)] +#pragma warning disable S6640 // Unsafe code is required for high-performance SIMD operations private static unsafe void CalculateSimdCore(ReadOnlySpan source, Span output, int period) { int len = source.Length; @@ -466,6 +468,7 @@ public sealed class Wma } } } +#pragma warning restore S6640 [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool HasNonFiniteValues(ReadOnlySpan span) diff --git a/lib/core/ringbuffer/RingBuffer.cs b/lib/core/ringbuffer/RingBuffer.cs index 9fed9aa3..9e04801e 100644 --- a/lib/core/ringbuffer/RingBuffer.cs +++ b/lib/core/ringbuffer/RingBuffer.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Numerics; using System.Runtime.CompilerServices; @@ -466,7 +467,7 @@ public sealed class RingBuffer : IEnumerable _start == other._start && _count == other._count && _index == other._index && - _current == other._current; + _current.Equals(other._current); public override readonly bool Equals(object? obj) => obj is Enumerator other && Equals(other); diff --git a/lib/core/tseries/tseries.cs b/lib/core/tseries/tseries.cs index 38dd1651..2a9ceac4 100644 --- a/lib/core/tseries/tseries.cs +++ b/lib/core/tseries/tseries.cs @@ -1,4 +1,6 @@ +using System; using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/lib/feeds/gbm/gbm.cs b/lib/feeds/gbm/gbm.cs index 730e92fc..8f084e54 100644 --- a/lib/feeds/gbm/gbm.cs +++ b/lib/feeds/gbm/gbm.cs @@ -8,7 +8,7 @@ namespace QuanTAlib; /// Stateless design - only maintains minimal state needed for price continuity. /// [SkipLocalsInit] - // Types should be named in PascalCase - GBM is a standard acronym +#pragma warning disable S101 // Rename class 'GBM' to match pascal case naming rules public class GBM : IFeed #pragma warning restore S101 { diff --git a/quantower/IndicatorExtensions.Tests.cs b/quantower/IndicatorExtensions.Tests.cs index 5970779d..e2e90941 100644 --- a/quantower/IndicatorExtensions.Tests.cs +++ b/quantower/IndicatorExtensions.Tests.cs @@ -96,6 +96,7 @@ public class IndicatorExtensionsTests } [Fact] + [System.Runtime.Versioning.SupportedOSPlatform("windows")] public void PaintMethods_DoNotThrow_WithValidGraphics() { // This test attempts to verify that paint methods don't crash. @@ -144,5 +145,8 @@ public class IndicatorExtensionsTests // Test DrawText IndicatorExtensions.DrawText(indicator, args, "Test Text"); + + // Assert that we reached the end without throwing + Assert.True(true); } }