diff --git a/Directory.Build.targets b/Directory.Build.targets
index bb4eb0ccf..f56227b38 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -138,6 +138,10 @@
+
+
+
+
$(MSBuildThisFileDirectory)
$(CodeAnalysisSettingsLocation)LeanCode.CodeAnalysis.ruleset
diff --git a/src/Tools/LeanCode.CodeAnalysis/Analyzers/EnsureCommandValidatorsFollowNamingConvention.cs b/src/Tools/LeanCode.CodeAnalysis/Analyzers/EnsureCommandValidatorsFollowNamingConvention.cs
index a7936bc24..fa6c361fc 100644
--- a/src/Tools/LeanCode.CodeAnalysis/Analyzers/EnsureCommandValidatorsFollowNamingConvention.cs
+++ b/src/Tools/LeanCode.CodeAnalysis/Analyzers/EnsureCommandValidatorsFollowNamingConvention.cs
@@ -39,7 +39,7 @@ private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
if (TryGetCommandValidator(type, out var commandValidator))
{
- var expectedName = GetCommandValidatorExpectedName(commandValidator);
+ var expectedName = GetCommandValidatorExpectedName(commandValidator!);
if (type.Name != expectedName)
{
@@ -61,10 +61,7 @@ internal static string GetCommandValidatorExpectedName(INamedTypeSymbol commandV
);
}
- private static bool TryGetCommandValidator(
- INamedTypeSymbol type,
- [NotNullWhen(true)] out INamedTypeSymbol? commandValidator
- )
+ private static bool TryGetCommandValidator(INamedTypeSymbol type, out INamedTypeSymbol? commandValidator)
{
var validator = GetImplementedValidator(type);
diff --git a/src/Tools/LeanCode.CodeAnalysis/Analyzers/SuggestCommandsHaveValidators.cs b/src/Tools/LeanCode.CodeAnalysis/Analyzers/SuggestCommandsHaveValidators.cs
index 6c05bc279..b146ce6dc 100644
--- a/src/Tools/LeanCode.CodeAnalysis/Analyzers/SuggestCommandsHaveValidators.cs
+++ b/src/Tools/LeanCode.CodeAnalysis/Analyzers/SuggestCommandsHaveValidators.cs
@@ -45,14 +45,14 @@ private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
var tree = type.DeclaringSyntaxReferences.First().SyntaxTree;
- if (!CommandIsValidated(commandType, tree, context.SemanticModel))
+ if (!CommandIsValidated(commandType!, tree, context.SemanticModel))
{
- var diagnostic = Diagnostic.Create(Rule, type.Locations[0], commandType.Name);
+ var diagnostic = Diagnostic.Create(Rule, type.Locations[0], commandType!.Name);
context.ReportDiagnostic(diagnostic);
}
}
- private static bool IsCommandHandler(INamedTypeSymbol type, [NotNullWhen(true)] out INamedTypeSymbol? commandType)
+ private static bool IsCommandHandler(INamedTypeSymbol type, out INamedTypeSymbol? commandType)
{
var handler = type.AllInterfaces.FirstOrDefault(i => i.GetFullNamespaceName() == HandlerTypeName);
diff --git a/src/Tools/LeanCode.CodeAnalysis/LeanCode.CodeAnalysis.csproj b/src/Tools/LeanCode.CodeAnalysis/LeanCode.CodeAnalysis.csproj
index 24535772a..96af15322 100644
--- a/src/Tools/LeanCode.CodeAnalysis/LeanCode.CodeAnalysis.csproj
+++ b/src/Tools/LeanCode.CodeAnalysis/LeanCode.CodeAnalysis.csproj
@@ -6,11 +6,13 @@
true
- netstandard2.1
+
+ netstandard2.0
+
diff --git a/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingFileMethods.cs b/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingFileMethods.cs
new file mode 100644
index 000000000..d3e62aa30
--- /dev/null
+++ b/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingFileMethods.cs
@@ -0,0 +1,47 @@
+// Based on https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/IO/File.cs
+// as linked by docs on 02.09.2024
+
+global using File = LeanCode.CodeAnalysis.NetStandard21Compatibility.MissingFileMethods;
+using System.Text;
+
+namespace LeanCode.CodeAnalysis.NetStandard21Compatibility;
+
+public static class MissingFileMethods
+{
+ private static readonly Encoding UTF8NoBOM = new UTF8Encoding(
+ encoderShouldEmitUTF8Identifier: false,
+ throwOnInvalidBytes: true
+ );
+
+ public static void Delete(string path) => System.IO.File.Delete(path);
+
+ public static Task WriteAllTextAsync(
+ string path,
+ string? contents,
+ CancellationToken cancellationToken = default
+ ) => WriteAllTextAsync(path, contents, UTF8NoBOM, cancellationToken);
+
+ public static async Task WriteAllTextAsync(
+ string path,
+ string? contents,
+ Encoding encoding,
+ CancellationToken cancellationToken = default
+ )
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentException("Path is invalid");
+ }
+
+ using var stream = System.IO.File.OpenWrite(path);
+
+ var preamble = encoding.GetPreamble();
+ await stream.WriteAsync(preamble, 0, preamble.Length, cancellationToken);
+
+ if (contents is not null)
+ {
+ var encoded = encoding.GetBytes(contents);
+ await stream.WriteAsync(encoded, 0, encoded.Length, cancellationToken);
+ }
+ }
+}
diff --git a/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingStringMethods.cs b/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingStringMethods.cs
new file mode 100644
index 000000000..dc12dbf22
--- /dev/null
+++ b/src/Tools/LeanCode.CodeAnalysis/NetStandard21Compatibility/MissingStringMethods.cs
@@ -0,0 +1,10 @@
+// Based on https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/String.Searching.cs#L26C13-L26C56
+// as linked by docs on 02.09.2024
+
+namespace System;
+
+public static class MissingStringMethods
+{
+ public static bool Contains(this string s, string value, StringComparison comparisonType) =>
+ s.IndexOf(value, comparisonType) >= 0;
+}