From 140e340a8d75a47d357593e8e1083d9f22e64d53 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 28 Jul 2022 03:05:27 +1000 Subject: [PATCH] Add Analyzer rule to warn of `FirstOrDefault` on list of structs --- Common.ruleset | 3 ++ .../FirstOrDefaultOnStructAnalyzer.cs | 51 ++++++++++++++++++ References/BizHawk.Analyzer.dll | Bin 23040 -> 25600 bytes .../config/HotkeyConfig.cs | 3 +- .../tools/HexEditor/HexEditor.cs | 11 ++-- src/BizHawk.Common/HawkFile/HawkFile.cs | 5 +- .../DiscFormats/CUE/CUE_Compile.cs | 7 +-- 7 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 ExternalProjects/BizHawk.Analyzer/FirstOrDefaultOnStructAnalyzer.cs diff --git a/Common.ruleset b/Common.ruleset index c743a52470..5b8d7aa745 100644 --- a/Common.ruleset +++ b/Common.ruleset @@ -28,6 +28,9 @@ + + + diff --git a/ExternalProjects/BizHawk.Analyzer/FirstOrDefaultOnStructAnalyzer.cs b/ExternalProjects/BizHawk.Analyzer/FirstOrDefaultOnStructAnalyzer.cs new file mode 100644 index 0000000000..e68f46f01e --- /dev/null +++ b/ExternalProjects/BizHawk.Analyzer/FirstOrDefaultOnStructAnalyzer.cs @@ -0,0 +1,51 @@ +namespace BizHawk.Analyzers; + +using System.Collections.Immutable; +using System.Linq; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class FirstOrDefaultOnStructAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor DiagUseFirstOrNull = new( + id: "BHI3100", + title: "Call to FirstOrDefault when elements are of a value type; FirstOrNull may have been intended", + messageFormat: "Call to FirstOrDefault when elements are of a value type; did you mean FirstOrNull?", + category: "Usage", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagUseFirstOrNull); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + context.RegisterCompilationStartAction(initContext => + { + if (initContext.Compilation.GetTypeByMetadataName("BizHawk.Common.CollectionExtensions.CollectionExtensions") is null) return; // project does not have BizHawk.Common dependency + var linqExtClassSym = initContext.Compilation.GetTypeByMetadataName("System.Linq.Enumerable")!; + IMethodSymbol? firstOrDefaultNoPredSym = null; + IMethodSymbol? firstOrDefaultWithPredSym = null; + foreach (var sym in linqExtClassSym.GetMembers("FirstOrDefault").Cast()) + { + if (sym.Parameters.Length is 2) firstOrDefaultWithPredSym = sym; + else firstOrDefaultNoPredSym = sym; + } + initContext.RegisterOperationAction( + oac => + { + var operation = (IInvocationOperation) oac.Operation; + var calledSym = operation.TargetMethod.ConstructedFrom; + if (!(firstOrDefaultWithPredSym!.Matches(calledSym) || firstOrDefaultNoPredSym!.Matches(calledSym))) return; + var receiverExprType = (INamedTypeSymbol) operation.SemanticModel.GetTypeInfo((CSharpSyntaxNode) operation.Arguments[0].Syntax)!.ConvertedType!; + if (receiverExprType.TypeArguments[0].IsValueType) oac.ReportDiagnostic(Diagnostic.Create(DiagUseFirstOrNull, operation.Syntax.GetLocation())); + }, + OperationKind.Invocation); + }); + } +} diff --git a/References/BizHawk.Analyzer.dll b/References/BizHawk.Analyzer.dll index 54b9ce45fa1cda9d5998164a7fb16f80499853fa..aac0933a984b72be7152e8309576cfd1f4751eec 100644 GIT binary patch delta 10454 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 delta 8390 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 Mu^)XbHVqE^4+Pk8E&u=k diff --git a/src/BizHawk.Client.EmuHawk/config/HotkeyConfig.cs b/src/BizHawk.Client.EmuHawk/config/HotkeyConfig.cs index 44a57e5055..18bf6294f3 100644 --- a/src/BizHawk.Client.EmuHawk/config/HotkeyConfig.cs +++ b/src/BizHawk.Client.EmuHawk/config/HotkeyConfig.cs @@ -6,6 +6,7 @@ using System.Windows.Forms; using BizHawk.Client.Common; using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; namespace BizHawk.Client.EmuHawk { @@ -197,7 +198,7 @@ namespace BizHawk.Client.EmuHawk { if (e.IsPressed(Keys.Enter) || e.IsPressed(Keys.Tab)) { - var k = HotkeyInfo.AllHotkeys.FirstOrDefault(kvp => string.Compare(kvp.Value.DisplayName, SearchBox.Text, true) is 0).Key; + var k = HotkeyInfo.AllHotkeys.FirstOrNull(kvp => string.Compare(kvp.Value.DisplayName, SearchBox.Text, true) is 0)?.Key; // Found if (k is not null) diff --git a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 1e79cbc52a..a768bd584b 100644 --- a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -16,6 +16,7 @@ using BizHawk.Emulation.Common; using BizHawk.Client.Common; using BizHawk.Client.EmuHawk.Properties; using BizHawk.Client.EmuHawk.ToolExtensions; +using BizHawk.Common.CollectionExtensions; namespace BizHawk.Client.EmuHawk { @@ -242,13 +243,13 @@ namespace BizHawk.Client.EmuHawk { if (_textTable.Any()) { - var byteArr = new List(); - foreach (var chr in str) + var byteArr = new byte[str.Length]; + for (var i = 0; i < str.Length; i++) { - byteArr.Add((byte)_textTable.FirstOrDefault(kvp => kvp.Value == chr).Key); + var c = str[i]; + byteArr[i] = (byte) (_textTable.FirstOrNull(kvp => kvp.Value == c)?.Key ?? 0); } - - return byteArr.ToArray(); + return byteArr; } return str.Select(Convert.ToByte).ToArray(); diff --git a/src/BizHawk.Common/HawkFile/HawkFile.cs b/src/BizHawk.Common/HawkFile/HawkFile.cs index 33ffdabe4d..3c15b49dfc 100644 --- a/src/BizHawk.Common/HawkFile/HawkFile.cs +++ b/src/BizHawk.Common/HawkFile/HawkFile.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using BizHawk.Common.CollectionExtensions; + namespace BizHawk.Common { /// @@ -257,7 +259,8 @@ namespace BizHawk.Common } /// finds an ArchiveItem with the specified name (path) within the archive; returns null if it doesnt exist - public HawkArchiveFileItem? FindArchiveMember(string? name) => ArchiveItems.FirstOrDefault(ai => ai.Name == name); + public HawkArchiveFileItem? FindArchiveMember(string? name) + => ArchiveItems.FirstOrNull(ai => ai.Name == name); /// a stream for the currently bound file /// no stream bound (haven't called or overload) diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Compile.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Compile.cs index 3f4900eccf..ddace068a9 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Compile.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Compile.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; //this would be a good place for structural validation //after this step, we won't want to have to do stuff like that (it will gunk up already sticky code) @@ -109,10 +110,10 @@ namespace BizHawk.Emulation.DiscSystem.CUE public override string ToString() { - var idx = Indexes.FirstOrDefault(cci => cci.Number == 1); - if (idx.Number != 1) return $"T#{Number:D2} NO INDEX 1"; + var idx = Indexes.FirstOrNull(static cci => cci.Number is 1); + if (idx is null) return $"T#{Number:D2} NO INDEX 1"; var indexlist = string.Join("|", Indexes); - return $"T#{Number:D2} {BlobIndex}:{idx.FileMSF} ({indexlist})"; + return $"T#{Number:D2} {BlobIndex}:{idx.Value.FileMSF} ({indexlist})"; } }