Browse Source

Support decimal constants in pattern matching

pull/3049/head
Siegfried Pammer 2 years ago
parent
commit
bf96482d56
  1. 58
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/PatternMatching.cs
  2. 4
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 9
      ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs

58
ICSharpCode.Decompiler.Tests/TestCases/Pretty/PatternMatching.cs

@ -21,6 +21,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -21,6 +21,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public int I;
public string Text { get; set; }
public object Obj { get; set; }
public S2 S2 { get; set; }
}
public struct S2
{
public int I;
public float F;
public decimal D;
public string Text { get; set; }
public object Obj { get; set; }
}
public void SimpleTypePattern(object x)
@ -682,6 +692,54 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -682,6 +692,54 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine("not Test");
}
}
public void RecursivePattern_CustomStructNested_Null(object obj)
{
if (obj is S { S2: { Obj: null } })
{
Console.WriteLine("Test " + obj);
}
else
{
Console.WriteLine("not Test");
}
}
public void RecursivePattern_CustomStructNested_TextLengthZero(object obj)
{
if (obj is S { S2: { Text: { Length: 0 } } })
{
Console.WriteLine("Test " + obj);
}
else
{
Console.WriteLine("not Test");
}
}
public void RecursivePattern_CustomStructNested_Float(object obj)
{
if (obj is S { S2: { F: 3.141f, Obj: null } })
{
Console.WriteLine("Test " + obj);
}
else
{
Console.WriteLine("not Test");
}
}
public void RecursivePattern_CustomStructNested_Decimal(object obj)
{
if (obj is S { S2: { D: 3.141m, Obj: null } })
{
Console.WriteLine("Test " + obj);
}
else
{
Console.WriteLine("not Test");
}
}
#endif
private bool F()
{

4
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -4657,7 +4657,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -4657,7 +4657,9 @@ namespace ICSharpCode.Decompiler.CSharp
default:
throw new InvalidOperationException("Unexpected comparison kind: " + comp.Kind);
}
case Call call when MatchInstruction.IsCallToString_op_Equality(call):
case Call call when MatchInstruction.IsCallToOpEquality(call, KnownTypeCode.String):
return Translate(call.Arguments[1]);
case Call call when MatchInstruction.IsCallToOpEquality(call, KnownTypeCode.Decimal):
return Translate(call.Arguments[1]);
default:
throw new NotImplementedException();

9
ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs

@ -146,19 +146,22 @@ namespace ICSharpCode.Decompiler.IL @@ -146,19 +146,22 @@ namespace ICSharpCode.Decompiler.IL
}
return IsConstant(comp.Right);
}
case Call call when IsCallToString_op_Equality(call):
case Call call when IsCallToOpEquality(call, KnownTypeCode.String):
testedOperand = call.Arguments[0];
return call.Arguments[1].OpCode == OpCode.LdStr;
case Call call when IsCallToOpEquality(call, KnownTypeCode.Decimal):
testedOperand = call.Arguments[0];
return call.Arguments[1].OpCode == OpCode.LdcDecimal;
default:
testedOperand = null;
return false;
}
}
internal static bool IsCallToString_op_Equality(Call call)
internal static bool IsCallToOpEquality(Call call, KnownTypeCode knownType)
{
return call.Method.IsOperator && call.Method.Name == "op_Equality"
&& call.Method.DeclaringType.IsKnownType(KnownTypeCode.String)
&& call.Method.DeclaringType.IsKnownType(knownType)
&& call.Arguments.Count == 2;
}

Loading…
Cancel
Save