diff --git a/Common.ruleset b/Common.ruleset index 57248b3d98..cc498e204c 100644 --- a/Common.ruleset +++ b/Common.ruleset @@ -31,6 +31,9 @@ + + + diff --git a/ExternalProjects/AnalyzersCommon/RoslynUtils.cs b/ExternalProjects/AnalyzersCommon/RoslynUtils.cs index 7c7dea0b7b..cc8b60d094 100644 --- a/ExternalProjects/AnalyzersCommon/RoslynUtils.cs +++ b/ExternalProjects/AnalyzersCommon/RoslynUtils.cs @@ -26,4 +26,16 @@ public static class RoslynUtils public static bool Matches(this ISymbol expected, ISymbol? actual) => SymbolEqualityComparer.Default.Equals(expected, actual); + +#if false // easier to just `.OriginalDefinition` always + public static bool Matches(this INamedTypeSymbol expected, INamedTypeSymbol? actual, bool degenericise) + { + if (degenericise) + { + if (expected.IsGenericType && !expected.IsUnboundGenericType) return expected.OriginalDefinition.Matches(actual, degenericise: true); + if (actual is not null && actual.IsGenericType && !actual.IsUnboundGenericType) return expected.Matches(actual.OriginalDefinition, degenericise: true); + } + return expected.Matches(actual as ISymbol); + } +#endif } diff --git a/ExternalProjects/BizHawk.Analyzer/TryGetValueImplicitDiscardAnalyzer.cs b/ExternalProjects/BizHawk.Analyzer/TryGetValueImplicitDiscardAnalyzer.cs new file mode 100644 index 0000000000..8f1ab1dc64 --- /dev/null +++ b/ExternalProjects/BizHawk.Analyzer/TryGetValueImplicitDiscardAnalyzer.cs @@ -0,0 +1,56 @@ +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 TryGetValueImplicitDiscardAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor DiagUncheckedTryGetValue = new( + id: "BHI1200", + title: "Check result of IDictionary.TryGetValue, or discard it if default(T) is desired", + messageFormat: "Assign the result of this TryGetValue call to a variable or discard", + category: "Usage", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagUncheckedTryGetValue); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + context.RegisterCompilationStartAction(static initContext => + { + const string STR_TGV = "TryGetValue"; + var rwDictSym = initContext.Compilation.GetTypeByMetadataName("System.Collections.Generic.IDictionary`2")!; + var roDictSym = initContext.Compilation.GetTypeByMetadataName("System.Collections.Generic.IReadOnlyDictionary`2")!; + bool IsBCLTryGetValue(IMethodSymbol calledSym) + => calledSym.ContainingType.AllInterfaces.Any(intfSym => + { + var degenericisedSym = intfSym.OriginalDefinition; + return rwDictSym.Matches(degenericisedSym) || roDictSym.Matches(degenericisedSym); + }); + initContext.RegisterOperationAction( + oac => + { + var operation = (IInvocationOperation) oac.Operation; + if (operation.Parent?.Kind is not OperationKind.ExpressionStatement) return; + var calledSym = operation.TargetMethod.ConstructedFrom; + if (calledSym.Name is STR_TGV) oac.ReportDiagnostic(Diagnostic.Create( + DiagUncheckedTryGetValue, + operation.Syntax.GetLocation(), + IsBCLTryGetValue(calledSym) ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning, + additionalLocations: null, + properties: null, + messageArgs: null)); + }, + OperationKind.Invocation); + }); + } +} diff --git a/References/BizHawk.Analyzer.dll b/References/BizHawk.Analyzer.dll index 08bbf5e521..62e21f6ee4 100644 Binary files a/References/BizHawk.Analyzer.dll and b/References/BizHawk.Analyzer.dll differ diff --git a/src/BizHawk.Bizware.BizwareGL/Pipeline.cs b/src/BizHawk.Bizware.BizwareGL/Pipeline.cs index 709ec7bae4..ce51253a65 100644 --- a/src/BizHawk.Bizware.BizwareGL/Pipeline.cs +++ b/src/BizHawk.Bizware.BizwareGL/Pipeline.cs @@ -66,7 +66,7 @@ namespace BizHawk.Bizware.BizwareGL public PipelineUniform TryGetUniform(string name) { - Uniforms.TryGetValue(name, out var ret); + _ = Uniforms.TryGetValue(name, out var ret); return ret; } diff --git a/src/BizHawk.Bizware.DirectX/DirectInputAdapter.cs b/src/BizHawk.Bizware.DirectX/DirectInputAdapter.cs index 7921d8e164..b99a02c6b8 100644 --- a/src/BizHawk.Bizware.DirectX/DirectInputAdapter.cs +++ b/src/BizHawk.Bizware.DirectX/DirectInputAdapter.cs @@ -54,8 +54,8 @@ namespace BizHawk.Bizware.DirectX continue; for (int b = 0, n = pad.NumButtons; b < n; b++) handleButton(pad.InputNamePrefix + pad.ButtonName(b), pad.Pressed(b), ClientInputFocus.Pad); foreach (var (axisName, f) in pad.GetAxes()) handleAxis(pad.InputNamePrefix + axisName, (int) f); - _lastHapticsSnapshot.TryGetValue(pad.InputNamePrefix + "Left", out var leftStrength); - _lastHapticsSnapshot.TryGetValue(pad.InputNamePrefix + "Right", out var rightStrength); + _ = _lastHapticsSnapshot.TryGetValue(pad.InputNamePrefix + "Left", out var leftStrength); + _ = _lastHapticsSnapshot.TryGetValue(pad.InputNamePrefix + "Right", out var rightStrength); pad.SetVibration(leftStrength, rightStrength); // values will be 0 if not found } foreach (var pad in GamePad.EnumerateDevices()) diff --git a/src/BizHawk.Client.Common/DisplayManager/FilterManager.cs b/src/BizHawk.Client.Common/DisplayManager/FilterManager.cs index 7d1c5694b6..10a6a635aa 100644 --- a/src/BizHawk.Client.Common/DisplayManager/FilterManager.cs +++ b/src/BizHawk.Client.Common/DisplayManager/FilterManager.cs @@ -47,7 +47,7 @@ namespace BizHawk.Client.Common.FilterManager { get { - _filterNameIndex.TryGetValue(name, out var ret); + _ = _filterNameIndex.TryGetValue(name, out var ret); return ret; } } diff --git a/src/BizHawk.Client.Common/RomLoader.cs b/src/BizHawk.Client.Common/RomLoader.cs index f9216cb95c..e2270f3d87 100644 --- a/src/BizHawk.Client.Common/RomLoader.cs +++ b/src/BizHawk.Client.Common/RomLoader.cs @@ -379,7 +379,7 @@ namespace BizHawk.Client.Common } else { - _config.PreferredCores.TryGetValue(cip.Game.System, out var preferredCore); + _ = _config.PreferredCores.TryGetValue(cip.Game.System, out var preferredCore); var dbForcedCoreName = cip.Game.ForcedCore; cores = CoreInventory.Instance.GetCores(cip.Game.System) .OrderBy(c => diff --git a/src/BizHawk.Client.Common/cheats/GbGgGameGenieDecoder.cs b/src/BizHawk.Client.Common/cheats/GbGgGameGenieDecoder.cs index 3207d2c44f..96573dd702 100644 --- a/src/BizHawk.Client.Common/cheats/GbGgGameGenieDecoder.cs +++ b/src/BizHawk.Client.Common/cheats/GbGgGameGenieDecoder.cs @@ -52,20 +52,20 @@ namespace BizHawk.Client.Common.cheats // Getting Value if (_code.Length > 0) { - _gbGgGameGenieTable.TryGetValue(_code[0], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[0], out x); result.Value = x << 4; } if (_code.Length > 1) { - _gbGgGameGenieTable.TryGetValue(_code[1], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[1], out x); result.Value |= x; } // Address if (_code.Length > 2) { - _gbGgGameGenieTable.TryGetValue(_code[2], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[2], out x); result.Value = x << 8; } else @@ -75,30 +75,30 @@ namespace BizHawk.Client.Common.cheats if (_code.Length > 3) { - _gbGgGameGenieTable.TryGetValue(_code[3], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[3], out x); result.Address |= x << 4; } if (_code.Length > 4) { - _gbGgGameGenieTable.TryGetValue(_code[4], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[4], out x); result.Address |= x; } if (_code.Length > 5) { - _gbGgGameGenieTable.TryGetValue(_code[5], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[5], out x); result.Address |= (x ^ 0xF) << 12; } // compare need to be full if (_code.Length > 8) { - _gbGgGameGenieTable.TryGetValue(_code[6], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[6], out x); var comp = x << 2; // 8th character ignored - _gbGgGameGenieTable.TryGetValue(_code[8], out x); + _ = _gbGgGameGenieTable.TryGetValue(_code[8], out x); comp |= (x & 0xC) >> 2; comp |= (x & 0x3) << 6; result.Compare = comp ^ 0xBA; diff --git a/src/BizHawk.Client.Common/cheats/GenesisGameGenieDecoder.cs b/src/BizHawk.Client.Common/cheats/GenesisGameGenieDecoder.cs index 3968b7f03a..a198330f63 100644 --- a/src/BizHawk.Client.Common/cheats/GenesisGameGenieDecoder.cs +++ b/src/BizHawk.Client.Common/cheats/GenesisGameGenieDecoder.cs @@ -65,7 +65,7 @@ namespace BizHawk.Client.Common.cheats foreach (var t in code) { hexCode <<= 5; - GameGenieTable.TryGetValue(t, out var y); + _ = GameGenieTable.TryGetValue(t, out var y); hexCode |= y; } diff --git a/src/BizHawk.Client.Common/cheats/NesGameGenieDecoder.cs b/src/BizHawk.Client.Common/cheats/NesGameGenieDecoder.cs index 04cddfa884..1f5a25bb4b 100644 --- a/src/BizHawk.Client.Common/cheats/NesGameGenieDecoder.cs +++ b/src/BizHawk.Client.Common/cheats/NesGameGenieDecoder.cs @@ -47,26 +47,26 @@ namespace BizHawk.Client.Common.cheats result.Value = 0; result.Address = 0x8000; - GameGenieTable.TryGetValue(code[0], out var x); + _ = GameGenieTable.TryGetValue(code[0], out var x); result.Value |= x & 0x07; result.Value |= (x & 0x08) << 4; - GameGenieTable.TryGetValue(code[1], out x); + _ = GameGenieTable.TryGetValue(code[1], out x); result.Value |= (x & 0x07) << 4; result.Address |= (x & 0x08) << 4; - GameGenieTable.TryGetValue(code[2], out x); + _ = GameGenieTable.TryGetValue(code[2], out x); result.Address |= (x & 0x07) << 4; - GameGenieTable.TryGetValue(code[3], out x); + _ = GameGenieTable.TryGetValue(code[3], out x); result.Address |= (x & 0x07) << 12; result.Address |= x & 0x08; - GameGenieTable.TryGetValue(code[4], out x); + _ = GameGenieTable.TryGetValue(code[4], out x); result.Address |= x & 0x07; result.Address |= (x & 0x08) << 8; - GameGenieTable.TryGetValue(code[5], out x); + _ = GameGenieTable.TryGetValue(code[5], out x); result.Address |= (x & 0x07) << 8; result.Value |= x & 0x08; } @@ -79,34 +79,34 @@ namespace BizHawk.Client.Common.cheats result.Address = 0x8000; result.Compare = 0; - GameGenieTable.TryGetValue(code[0], out var x); + _ = GameGenieTable.TryGetValue(code[0], out var x); result.Value |= x & 0x07; result.Value |= (x & 0x08) << 4; - GameGenieTable.TryGetValue(code[1], out x); + _ = GameGenieTable.TryGetValue(code[1], out x); result.Value |= (x & 0x07) << 4; result.Address |= (x & 0x08) << 4; - GameGenieTable.TryGetValue(code[2], out x); + _ = GameGenieTable.TryGetValue(code[2], out x); result.Address |= (x & 0x07) << 4; - GameGenieTable.TryGetValue(code[3], out x); + _ = GameGenieTable.TryGetValue(code[3], out x); result.Address |= (x & 0x07) << 12; result.Address |= x & 0x08; - GameGenieTable.TryGetValue(code[4], out x); + _ = GameGenieTable.TryGetValue(code[4], out x); result.Address |= x & 0x07; result.Address |= (x & 0x08) << 8; - GameGenieTable.TryGetValue(code[5], out x); + _ = GameGenieTable.TryGetValue(code[5], out x); result.Address |= (x & 0x07) << 8; result.Compare |= x & 0x08; - GameGenieTable.TryGetValue(code[6], out x); + _ = GameGenieTable.TryGetValue(code[6], out x); result.Compare |= x & 0x07; result.Compare |= (x & 0x08) << 4; - GameGenieTable.TryGetValue(code[7], out x); + _ = GameGenieTable.TryGetValue(code[7], out x); result.Compare |= (x & 0x07) << 4; result.Value |= x & 0x08; } diff --git a/src/BizHawk.Client.Common/cheats/SnesGameGenieDecoder.cs b/src/BizHawk.Client.Common/cheats/SnesGameGenieDecoder.cs index e3829eb69f..24e12e8e80 100644 --- a/src/BizHawk.Client.Common/cheats/SnesGameGenieDecoder.cs +++ b/src/BizHawk.Client.Common/cheats/SnesGameGenieDecoder.cs @@ -55,53 +55,53 @@ namespace BizHawk.Client.Common.cheats // Value if (code.Length > 0) { - SNESGameGenieTable.TryGetValue(code[0], out x); + _ = SNESGameGenieTable.TryGetValue(code[0], out x); result.Value = x << 4; } if (code.Length > 1) { - SNESGameGenieTable.TryGetValue(code[1], out x); + _ = SNESGameGenieTable.TryGetValue(code[1], out x); result.Value |= x; } // Address if (code.Length > 2) { - SNESGameGenieTable.TryGetValue(code[2], out x); + _ = SNESGameGenieTable.TryGetValue(code[2], out x); result.Address = x << 12; } if (code.Length > 3) { - SNESGameGenieTable.TryGetValue(code[3], out x); + _ = SNESGameGenieTable.TryGetValue(code[3], out x); result.Address |= x << 4; } if (code.Length > 4) { - SNESGameGenieTable.TryGetValue(code[4], out x); + _ = SNESGameGenieTable.TryGetValue(code[4], out x); result.Address |= (x & 0xC) << 6; result.Address |= (x & 0x3) << 22; } if (code.Length > 5) { - SNESGameGenieTable.TryGetValue(code[5], out x); + _ = SNESGameGenieTable.TryGetValue(code[5], out x); result.Address |= (x & 0xC) << 18; result.Address |= (x & 0x3) << 2; } if (code.Length > 6) { - SNESGameGenieTable.TryGetValue(code[6], out x); + _ = SNESGameGenieTable.TryGetValue(code[6], out x); result.Address |= (x & 0xC) >> 2; result.Address |= (x & 0x3) << 18; } if (code.Length > 7) { - SNESGameGenieTable.TryGetValue(code[7], out x); + _ = SNESGameGenieTable.TryGetValue(code[7], out x); result.Address |= (x & 0xC) << 14; result.Address |= (x & 0x3) << 10; } diff --git a/src/BizHawk.Client.Common/config/ConfigExtensions.cs b/src/BizHawk.Client.Common/config/ConfigExtensions.cs index 796b7a295c..db982d0d3a 100644 --- a/src/BizHawk.Client.Common/config/ConfigExtensions.cs +++ b/src/BizHawk.Client.Common/config/ConfigExtensions.cs @@ -45,7 +45,7 @@ namespace BizHawk.Client.Common /// null if no settings were saved, or there was an error deserializing public static object GetCoreSettings(this Config config, Type coreType, Type settingsType) { - config.CoreSettings.TryGetValue(coreType.ToString(), out var j); + _ = config.CoreSettings.TryGetValue(coreType.ToString(), out var j); return Deserialize(j, settingsType); } @@ -85,7 +85,7 @@ namespace BizHawk.Client.Common /// null if no settings were saved, or there was an error deserializing public static object GetCoreSyncSettings(this Config config, Type coreType, Type syncSettingsType) { - config.CoreSyncSettings.TryGetValue(coreType.ToString(), out var j); + _ = config.CoreSyncSettings.TryGetValue(coreType.ToString(), out var j); return Deserialize(j, syncSettingsType); } diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 6ea67c3e4c..0f9fb07a11 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -81,9 +81,9 @@ namespace BizHawk.Client.EmuHawk entry.Click += ClickHandler; return (ToolStripItem) entry; }).ToArray()); - submenu.DropDownOpened += (openedSender, _) => + submenu.DropDownOpened += (openedSender, _1) => { - Config.PreferredCores.TryGetValue(groupLabel, out var preferred); + _ = Config.PreferredCores.TryGetValue(groupLabel, out var preferred); foreach (ToolStripMenuItem entry in ((ToolStripMenuItem) openedSender).DropDownItems) entry.Checked = entry.Text == preferred; }; CoresSubMenu.DropDownItems.Add(submenu); diff --git a/src/BizHawk.Client.EmuHawk/config/ControllerConfig.cs b/src/BizHawk.Client.EmuHawk/config/ControllerConfig.cs index 03df2722c1..3f64cda681 100644 --- a/src/BizHawk.Client.EmuHawk/config/ControllerConfig.cs +++ b/src/BizHawk.Client.EmuHawk/config/ControllerConfig.cs @@ -267,7 +267,7 @@ namespace BizHawk.Client.EmuHawk private void SetControllerPicture(string controlName) { - ControllerImages.TryGetValue(controlName, out var lazyBmp); + _ = ControllerImages.TryGetValue(controlName, out var lazyBmp); if (lazyBmp != null) { var bmp = lazyBmp.Value; diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index bf670ee524..5dbe97029c 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -194,7 +194,7 @@ namespace BizHawk.Emulation.Common _acquire.WaitOne(); var hashFormatted = FormatHash(hash); - DB.TryGetValue(hashFormatted, out var cgi); + _ = DB.TryGetValue(hashFormatted, out var cgi); if (cgi == null) { Console.WriteLine($"DB: hash {hash} not in game database."); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs index fc4c242c6f..9bc56c84b3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs @@ -29,7 +29,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public byte* QUERY_get_memory_data(SNES_MEMORY id) { string name = QUERY_MemoryNameForId(id); - _sharedMemoryBlocks.TryGetValue(name, out var ret); + _ = _sharedMemoryBlocks.TryGetValue(name, out var ret); return (byte*)ret; } diff --git a/src/BizHawk.Emulation.Cores/CoreInventory.cs b/src/BizHawk.Emulation.Cores/CoreInventory.cs index 5edcde5fd8..6573150a4d 100644 --- a/src/BizHawk.Emulation.Cores/CoreInventory.cs +++ b/src/BizHawk.Emulation.Cores/CoreInventory.cs @@ -151,7 +151,7 @@ namespace BizHawk.Emulation.Cores public IEnumerable GetCores(string system) { - _systems.TryGetValue(system, out var cores); + _ = _systems.TryGetValue(system, out var cores); return cores ?? Enumerable.Empty(); } diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs index 05663da7bb..44297aa50e 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs @@ -113,8 +113,8 @@ namespace BizHawk.Emulation.Cores.Waterbox var possible = info.AllOverrides.Where(kvp => kvp.Value.NonSync && kvp.Value.NoRestart).Select(kvp => kvp.Key); return possible.Where(key => { - x.MednafenValues.TryGetValue(key, out var xx); - y.MednafenValues.TryGetValue(key, out var yy); + _ = x.MednafenValues.TryGetValue(key, out var xx); + _ = y.MednafenValues.TryGetValue(key, out var yy); return xx != yy; }); } @@ -124,8 +124,8 @@ namespace BizHawk.Emulation.Cores.Waterbox var restarters = info.AllOverrides.Where(kvp => kvp.Value.NonSync && !kvp.Value.NoRestart).Select(kvp => kvp.Key); foreach (var key in restarters) { - x.MednafenValues.TryGetValue(key, out var xx); - y.MednafenValues.TryGetValue(key, out var yy); + _ = x.MednafenValues.TryGetValue(key, out var xx); + _ = y.MednafenValues.TryGetValue(key, out var yy); if (xx != yy) return PutSettingsDirtyBits.RebootCore; } @@ -186,8 +186,8 @@ namespace BizHawk.Emulation.Cores.Waterbox var restarters = info.AllOverrides.Where(kvp => !kvp.Value.NonSync && !kvp.Value.NoRestart).Select(kvp => kvp.Key); foreach (var key in restarters) { - x.MednafenValues.TryGetValue(key, out var xx); - y.MednafenValues.TryGetValue(key, out var yy); + _ = x.MednafenValues.TryGetValue(key, out var xx); + _ = y.MednafenValues.TryGetValue(key, out var yy); if (xx != yy) return PutSettingsDirtyBits.RebootCore; } @@ -206,7 +206,7 @@ namespace BizHawk.Emulation.Cores.Waterbox { // try to get actual value from settings var dict = ovr.NonSync ? _settings.MednafenValues : _syncSettingsActual.MednafenValues; - dict.TryGetValue(name, out val); + _ = dict.TryGetValue(name, out val); } if (val == null) {