diff --git a/Harmony/Tools/CodeMatcher/CodeMatch.cs b/Harmony/Tools/CodeMatcher/CodeMatch.cs index 831384b9..413a5c22 100644 --- a/Harmony/Tools/CodeMatcher/CodeMatch.cs +++ b/Harmony/Tools/CodeMatcher/CodeMatch.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; +using System.Text; namespace HarmonyLib { @@ -103,24 +104,24 @@ internal bool Matches(List codes, CodeInstruction instruction) /// public override string ToString() { - var result = "["; + var sb = new StringBuilder(); if (name != null) - result += $"{name}: "; + sb.Append($"{name}: "); if (opcodes.Count > 0) - result += $"opcodes={opcodes.Union(new []{ opcode }).Where(o => o.Name != null).Join()} "; + sb.Append($"opcodes={opcodes.Union(new[] {opcode}).Where(o => o.Size != 0).Join()} "); if (operands.Count > 0) - result += $"operands={operands.Union(new []{ operand }).Where(o => o != null).Join()} "; + sb.Append($"operands={operands.Union(new[] {operand}).Where(o => o != null).Join()} "); if (labels.Count > 0) - result += $"labels={labels.Join()} "; + sb.Append($"labels={labels.Join()} "); if (blocks.Count > 0) - result += $"blocks={blocks.Join()} "; + sb.Append($"blocks={blocks.Join()} "); if (jumpsFrom.Count > 0) - result += $"jumpsFrom={jumpsFrom.Join()} "; + sb.Append($"jumpsFrom={jumpsFrom.Join()} "); if (jumpsTo.Count > 0) - result += $"jumpsTo={jumpsTo.Join()} "; + sb.Append($"jumpsTo={jumpsTo.Join()} "); if (predicate != null) - result += "predicate=yes "; - return $"{result.TrimEnd()}]"; + sb.Append("predicate=yes "); + return sb.Length != 0 ? $"[{sb.ToString().Trim()}]" : base.ToString(); } /// Creates a new code match for an opcode diff --git a/HarmonyTests/Tools/TestCodeMatcher.cs b/HarmonyTests/Tools/TestCodeMatcher.cs index 9dae76c3..699c5db3 100644 --- a/HarmonyTests/Tools/TestCodeMatcher.cs +++ b/HarmonyTests/Tools/TestCodeMatcher.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; +using static HarmonyLib.Code; namespace HarmonyLibTests.Tools; @@ -29,23 +30,32 @@ public void TestRepeatReplaceMultiple() err => throw new Exception($"Nothing replaced .{err}")) .Instructions(); + var writeLine = AccessTools.Method(typeof(Console), nameof(Console.WriteLine), new[] {typeof(string)}); AssertSameCode(result, - new[] + new CodeInstruction[] { - "ldarg.0 NULL", "call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()", - "call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"", - "call static void Console::WriteLine(string value)", "ldarg.0 NULL", - "call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()", - "call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"", - "call static void Console::WriteLine(string value)", "ldarg.0 NULL", - "call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()", - "call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"", - "call static void Console::WriteLine(string value)", "ret NULL" - }); + Ldarg_0, // + Call[matchTarget], // + Call[matchReplacement], // + Ldstr["Foo!"], // + Call[writeLine], // + Ldarg_0, // + Call[matchTarget], // + Call[matchReplacement], // + Ldstr["Foo!"], // + Call[writeLine], // + Ldarg_0, // + Call[matchTarget], // + Call[matchReplacement], // + Ldstr["Foo!"], // + Call[writeLine], // + Ret // + } + ); } - private void AssertSameCode(List ins, string[] expected) + private void AssertSameCode(List ins, CodeInstruction[] expected) { - Assert.AreEqual(expected, ins.Select(i => i.ToString()).ToArray()); + Assert.AreEqual(expected.Select(i => i.ToString()), ins.Select(i => i.ToString()).ToArray()); } }