From 1646be74822ad7cbc1e49ac12f6b29ebfd37bb57 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 26 May 2018 18:35:34 +0200 Subject: [PATCH] #1145: Make type arguments optional in mcs auto event pattern. --- .../ICSharpCode.Decompiler.Tests.csproj | 1 + .../ILPrettyTestRunner.cs | 6 ++ .../TestCases/ILPretty/Issue1145.cs | 7 ++ .../TestCases/ILPretty/Issue1145.il | 78 +++++++++++++++++++ .../Syntax/PatternMatching/Backreference.cs | 2 +- .../Transforms/PatternStatementTransform.cs | 4 +- 6 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index f180b3e3f..62a2d66b3 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -84,6 +84,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 30defe919..73b843890 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -106,6 +106,12 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test] + public void Issue1145() + { + Run(); + } + [Test, Ignore("?")] public void FSharpLoops_Debug() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.cs new file mode 100644 index 000000000..d54281695 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.cs @@ -0,0 +1,7 @@ +using System; + +[Serializable] +public class OwningClass +{ + public event Action EvName; +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.il new file mode 100644 index 000000000..be084dda4 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.il @@ -0,0 +1,78 @@ +.class public auto ansi serializable beforefieldinit OwningClass +{ + +.field class [System.Core]System.Action EvName + +.event [System.Core]System.Action EvName +{ + .addon instance void OwningClass::add_EvName(class [System.Core]System.Action) + .removeon instance void OwningClass::remove_EvName(class [System.Core]System.Action) +} + +.method public hidebysig specialname + instance void add_EvName ( + class [System.Core]System.Action 'value' + ) cil managed +{ + .maxstack 3 + .locals init ( + [0] class [System.Core]System.Action, + [1] class [System.Core]System.Action + ) + + IL_0000: ldarg.0 + IL_0001: ldfld class [System.Core]System.Action OwningClass::EvName + IL_0006: stloc.0 + // loop start (head: IL_0007) + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldarg.0 + IL_000a: ldflda class [System.Core]System.Action OwningClass::EvName + IL_000f: ldloc.1 + IL_0010: ldarg.1 + IL_0011: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) + IL_0016: castclass [System.Core]System.Action + IL_001b: ldloc.0 + IL_001c: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un IL_0007 + // end loop + IL_0029: ret +} // end of method OwningClass::add_EvName + +.method public hidebysig specialname + instance void remove_EvName ( + class [System.Core]System.Action 'value' + ) cil managed +{ + .maxstack 3 + .locals init ( + [0] class [System.Core]System.Action, + [1] class [System.Core]System.Action + ) + + IL_0000: ldarg.0 + IL_0001: ldfld class [System.Core]System.Action OwningClass::EvName + IL_0006: stloc.0 + // loop start (head: IL_0007) + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldarg.0 + IL_000a: ldflda class [System.Core]System.Action OwningClass::EvName + IL_000f: ldloc.1 + IL_0010: ldarg.1 + IL_0011: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) + IL_0016: castclass [System.Core]System.Action + IL_001b: ldloc.0 + IL_001c: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un IL_0007 + // end loop + IL_0029: ret +} // end of method OwningClass::remove_EvName + +} // end of class OwningClass \ No newline at end of file diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Backreference.cs b/ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Backreference.cs index 845dd6123..d3d8c3e93 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Backreference.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Backreference.cs @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching public override bool DoMatch(INode other, Match match) { - var last = match.Get (referencedGroupName).Last (); + var last = match.Get (referencedGroupName).LastOrDefault(); if (last == null && other == null) return true; return last.IsMatch(other); diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs index 2be9ed9da..f4c0c61d9 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs @@ -682,10 +682,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms Left = new IdentifierExpressionBackreference("var1"), Right = new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(System.Threading.Interlocked)).ToType()), "CompareExchange", - new AstType[] { new AnyNode("type") }), // type argument+ + new AstType[] { new Repeat(new AnyNode()) }), // optional type arguments new Expression[] { // arguments new DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new Backreference("field") }, - new CastExpression(new Backreference("type"), new InvocationExpression(new AnyNode("delegateCombine").ToExpression(), new IdentifierExpressionBackreference("var2"), new IdentifierExpression("value"))), + new CastExpression(new AnyNode("type"), new InvocationExpression(new AnyNode("delegateCombine").ToExpression(), new IdentifierExpressionBackreference("var2"), new IdentifierExpression("value"))), new IdentifierExpressionBackreference("var1") } )