From 397bb83ba8b617dcae6adfcd8038ee118c2301dd Mon Sep 17 00:00:00 2001
From: Octol1ttle <l1ttleofficial@outlook.com>
Date: Mon, 24 Jul 2023 22:35:45 +0500
Subject: [PATCH] Add code analysis to prohibit using bad methods and
 properties (#70)

This PR adds the package `Microsoft.CodeAnalysis.BannedApiAnalyzers` to
scan for banned code (defined by `CodeAnalysis/BannedSymbols.txt`) and
provide warnings if it is used. The list of banned symbols is borrowed
from osu! and other projects

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
---
 Boyfriend.csproj               |  4 ++++
 CodeAnalysis/BannedSymbols.txt | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 CodeAnalysis/BannedSymbols.txt

diff --git a/Boyfriend.csproj b/Boyfriend.csproj
index 8c4cd81..366d1c5 100644
--- a/Boyfriend.csproj
+++ b/Boyfriend.csproj
@@ -22,6 +22,7 @@
         <PackageReference Include="DiffPlex" Version="1.7.1"/>
         <PackageReference Include="Humanizer.Core.ru" Version="2.14.1"/>
         <PackageReference Include="JetBrains.Annotations" Version="2023.2.0"/>
+        <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4"/>
         <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1"/>
         <PackageReference Include="Remora.Discord.Caching" Version="37.0.0"/>
         <PackageReference Include="Remora.Discord.Extensions" Version="5.3.2"/>
@@ -34,4 +35,7 @@
             <LastGenOutput>Messages.Designer.cs</LastGenOutput>
         </EmbeddedResource>
     </ItemGroup>
+    <ItemGroup>
+        <AdditionalFiles Include="CodeAnalysis\BannedSymbols.txt"/>
+    </ItemGroup>
 </Project>
diff --git a/CodeAnalysis/BannedSymbols.txt b/CodeAnalysis/BannedSymbols.txt
new file mode 100644
index 0000000..f664b89
--- /dev/null
+++ b/CodeAnalysis/BannedSymbols.txt
@@ -0,0 +1,19 @@
+M:System.Object.Equals(System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or EqualityComparer<T>.Default instead.
+M:System.ValueType.Equals(System.Object)~System.Boolean;Don't use object.Equals(Fallbacks to ValueType). Use IEquatable<T> or EqualityComparer<T>.Default instead.
+M:System.Nullable`1.Equals(System.Object)~System.Boolean;Use == instead.
+T:System.IComparable;Don't use non-generic IComparable. Use generic version instead.
+M:System.Guid.#ctor;Probably meaning to use Guid.NewGuid() instead. If actually wanting empty, use Guid.Empty.
+M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait.
+P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result.
+M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever.
+M:System.Char.ToLower(System.Char);char.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
+M:System.Char.ToUpper(System.Char);char.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
+M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
+M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
+M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToPascalCase() instead.
+M:Humanizer.InflectorExtensions.Camelize(System.String);Humanizer's .Camelize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToCamelCase() instead.
+M:Humanizer.InflectorExtensions.Underscore(System.String);Humanizer's .Underscore() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToSnakeCase() instead.
+M:Humanizer.InflectorExtensions.Kebaberize(System.String);Humanizer's .Kebaberize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToKebabCase() instead.
+P:System.DateTime.Now;Use System.DateTime.UtcNow instead.
+P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead.
+P:System.DateTimeOffset.DateTime;Use System.DateTimeOffset.UtcDateTime instead.