From a5652ee3bc3484b271703996c1aa43cbdc223683 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 13 Aug 2022 02:15:54 +1000 Subject: [PATCH] Backport `IEnumerable.Order`/`OrderDescending` shorthand at time of writing, in .NET 7 preview https://github.com/dotnet/runtime/pull/70525 --- Common.ruleset | 3 + .../BizHawk.Analyzer/OrderBySelfAnalyzer.cs | 70 ++++++++++++++++++ References/BizHawk.Analyzer.dll | Bin 25600 -> 28160 bytes src/BizHawk.Client.Common/ArgParser.cs | 4 +- .../FilesystemFilterSet.cs | 4 +- .../movie/tasproj/TasMovie.Editing.cs | 4 +- .../movie/tasproj/ZwinderStateManager.cs | 3 +- .../tools/Lua/Libraries/ConsoleLuaLibrary.cs | 4 +- .../tools/Watch/RamWatch.cs | 2 +- .../Extensions/CollectionExtensions.cs | 15 ++++ src/BizHawk.Emulation.Common/VSystemID.cs | 5 +- 11 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 ExternalProjects/BizHawk.Analyzer/OrderBySelfAnalyzer.cs diff --git a/Common.ruleset b/Common.ruleset index 5b8d7aa745..96a02ae30f 100644 --- a/Common.ruleset +++ b/Common.ruleset @@ -31,6 +31,9 @@ + + + diff --git a/ExternalProjects/BizHawk.Analyzer/OrderBySelfAnalyzer.cs b/ExternalProjects/BizHawk.Analyzer/OrderBySelfAnalyzer.cs new file mode 100644 index 0000000000..8fc6539fa4 --- /dev/null +++ b/ExternalProjects/BizHawk.Analyzer/OrderBySelfAnalyzer.cs @@ -0,0 +1,70 @@ +namespace BizHawk.Analyzers; + +using System.Collections.Immutable; +using System.Linq; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public class OrderBySelfAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor DiagUseOrderBySelfExt = new( + id: "BHI3101", + title: "Use .Order()/.OrderDescending() shorthand", + messageFormat: "Replace .OrderBy{0}(e => e) with .Order{0}()", + category: "Usage", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagUseOrderBySelfExt); + + 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")!; + var orderByAscSym = linqExtClassSym.GetMembers("OrderBy").Cast().First(sym => sym.Parameters.Length is 2); + var orderByDescSym = linqExtClassSym.GetMembers("OrderByDescending").Cast().First(sym => sym.Parameters.Length is 2); + initContext.RegisterOperationAction( + oac => + { + static bool IsSelfReturnLambda(AnonymousFunctionExpressionSyntax afes) + { + ParameterSyntax paramSyn; + switch (afes) + { + case AnonymousMethodExpressionSyntax ames: // banned in BizHawk but included for completeness + if ((ames.ParameterList?.Parameters)?.Count is not 1) return false; + paramSyn = ames.ParameterList.Parameters[0]; + break; + case ParenthesizedLambdaExpressionSyntax ples: + if (ples.ParameterList.Parameters.Count is not 1) return false; + paramSyn = ples.ParameterList.Parameters[0]; + break; + case SimpleLambdaExpressionSyntax sles: + paramSyn = sles.Parameter; + break; + default: + return false; + } + bool Matches(IdentifierNameSyntax ins) + => ins.Identifier.ValueText == paramSyn.Identifier.ValueText; + if (afes.ExpressionBody is not null) return afes.ExpressionBody is IdentifierNameSyntax ins && Matches(ins); + return afes.Block!.Statements.Count is 1 && afes.Block.Statements[0] is ReturnStatementSyntax { Expression: IdentifierNameSyntax ins1 } && Matches(ins1); + } + var operation = (IInvocationOperation) oac.Operation; + var calledSym = operation.TargetMethod.ConstructedFrom; + if (!(orderByAscSym!.Matches(calledSym) || orderByDescSym!.Matches(calledSym))) return; + if (((ArgumentSyntax) operation.Arguments[1].Syntax).Expression is not AnonymousFunctionExpressionSyntax afes) return; + if (IsSelfReturnLambda(afes)) oac.ReportDiagnostic(Diagnostic.Create(DiagUseOrderBySelfExt, afes.GetLocation(), orderByDescSym.Matches(calledSym) ? "Descending" : string.Empty)); + }, + OperationKind.Invocation); + }); + } +} diff --git a/References/BizHawk.Analyzer.dll b/References/BizHawk.Analyzer.dll index aac0933a984b72be7152e8309576cfd1f4751eec..b3a7549b299391e9505abb85d5f5537ac882c906 100644 GIT binary patch literal 28160 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%0AHfd5p#9Oyy?{+}IEw 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 @@ -86,7 +88,7 @@ namespace BizHawk.Client.Common } // automatically set dump length to maximum frame - autoDumpLength = currAviWriterFrameList.OrderBy(x => x).Last(); + autoDumpLength = currAviWriterFrameList.Order().Last(); } else if (argDowncased.StartsWith("--version")) { diff --git a/src/BizHawk.Client.Common/FilesystemFilterSet.cs b/src/BizHawk.Client.Common/FilesystemFilterSet.cs index 9437d40f13..dfa1cb730c 100644 --- a/src/BizHawk.Client.Common/FilesystemFilterSet.cs +++ b/src/BizHawk.Client.Common/FilesystemFilterSet.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; +using BizHawk.Common.CollectionExtensions; + namespace BizHawk.Client.Common { public sealed class FilesystemFilterSet @@ -27,7 +29,7 @@ namespace BizHawk.Client.Common /// call other overload (omit ) to not prepend combined entry, return value is a valid Filter for Save-/OpenFileDialog public string ToString(string combinedEntryDesc, bool addAllFilesEntry = true) { - _allSer ??= FilesystemFilter.SerializeEntry(combinedEntryDesc, Filters.SelectMany(static filter => filter.Extensions).Distinct().OrderBy(static s => s).ToList()); + _allSer ??= FilesystemFilter.SerializeEntry(combinedEntryDesc, Filters.SelectMany(static filter => filter.Extensions).Distinct().Order().ToList()); return $"{_allSer}|{ToString(addAllFilesEntry)}"; } diff --git a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs index 2e0de988ec..a4e6d8ef13 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; +using BizHawk.Common.CollectionExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -117,8 +118,7 @@ namespace BizHawk.Client.Common // and process each block independently List framesToDelete = frames .Where(fr => fr >= 0 && fr < InputLogLength) - .OrderBy(fr => fr) - .ToList(); + .Order().ToList(); // f is the current index for framesToDelete int f = 0; int numDeleted = 0; diff --git a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs index 844af118d0..264e96678c 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -244,7 +245,7 @@ namespace BizHawk.Client.Common // Enumerate all reserved states in reverse order private IEnumerable ReservedStates() { - foreach (var key in _reserved.Keys.OrderByDescending(k => k)) + foreach (var key in _reserved.Keys.OrderDescending()) { yield return new StateInfo(key, _reserved[key]); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/ConsoleLuaLibrary.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/ConsoleLuaLibrary.cs index 2d6a04fc56..853acce6b4 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/ConsoleLuaLibrary.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/ConsoleLuaLibrary.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Text; using BizHawk.Client.Common; +using BizHawk.Common.CollectionExtensions; + using NLua; namespace BizHawk.Client.EmuHawk @@ -82,7 +84,7 @@ namespace BizHawk.Client.EmuHawk return string.Concat(keyObjs.Cast() .Select((kObj, i) => $"\"{(kObj is string s ? FixString(s) : kObj.ToString())}\": \"{(values[i] is string s1 ? FixString(s1) : values[i].ToString())}\"\n") - .OrderBy(static s => s)); + .Order()); } if (!Tools.Has()) diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs index 57addaaa41..9dac2dddcf 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs @@ -759,7 +759,7 @@ namespace BizHawk.Client.EmuHawk private void RemoveWatchMenuItem_Click(object sender, EventArgs e) { if (!WatchListView.AnyRowsSelected) return; - foreach (var index in SelectedIndices.OrderByDescending(static i => i).ToList()) _watches.RemoveAt(index); + foreach (var index in SelectedIndices.OrderDescending().ToList()) _watches.RemoveAt(index); WatchListView.RowCount = _watches.Count; GeneralUpdate(); UpdateWatchCount(); diff --git a/src/BizHawk.Common/Extensions/CollectionExtensions.cs b/src/BizHawk.Common/Extensions/CollectionExtensions.cs index 3c0813bfd3..f2d6915239 100644 --- a/src/BizHawk.Common/Extensions/CollectionExtensions.cs +++ b/src/BizHawk.Common/Extensions/CollectionExtensions.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; namespace BizHawk.Common.CollectionExtensions { @@ -153,6 +154,16 @@ namespace BizHawk.Common.CollectionExtensions return null; } + /// shorthand for this.OrderBy(static e => e), backported from .NET 7 + public static IOrderedEnumerable Order(this IEnumerable source) + where T : IComparable + => source.OrderBy(ReturnSelf); + + /// shorthand for this.OrderByDescending(static e => e), backported from .NET 7 + public static IOrderedEnumerable OrderDescending(this IEnumerable source) + where T : IComparable + => source.OrderByDescending(ReturnSelf); + /// /// /// (This is an extension method which reimplements for other collections. @@ -180,6 +191,10 @@ namespace BizHawk.Common.CollectionExtensions return c - list.Count; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static T ReturnSelf(this T self) + => self; + public static bool IsSortedAsc(this IReadOnlyList list) where T : IComparable { diff --git a/src/BizHawk.Emulation.Common/VSystemID.cs b/src/BizHawk.Emulation.Common/VSystemID.cs index 7614078862..7ae233eeac 100644 --- a/src/BizHawk.Emulation.Common/VSystemID.cs +++ b/src/BizHawk.Emulation.Common/VSystemID.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using BizHawk.Common.CollectionExtensions; + namespace BizHawk.Emulation.Common { /// @@ -74,8 +76,7 @@ namespace BizHawk.Emulation.Common private static List AllSysIDs => _allSysIDs ??= typeof(Raw).GetFields(BindingFlags.Public | BindingFlags.Static) .Select(x => (string) x.GetRawConstantValue()) - .OrderBy(s => s) - .ToList(); + .Order().ToList(); /// iff it's in the valid list, else public static string? Validate(string sysID)