mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
The fixture is the desired output for the C# 9 pattern forms the decompiler does not reconstruct yet: relational subpatterns printed with conventional spacing (currently emitted as 'I: >5', which the repo's own formatter rejects), 'and'/'or' combinators (type + value tests, constant alternatives, range checks in subpatterns), top-level 'is not' with designator, negated recursive patterns, 'null or ""', and switch statements/expressions with relational or combined arms (currently leaked as balanced-comparison if trees). It also pins two real bugs: a 'not' subpattern with a string constant decompiles to 'Text: 0' (uncompilable, CS0029 on recompile) and with a decimal constant to 'Dec: 0' (compiles but silently inverts and changes the matched value); the negation and the operand of the logic.not(call op_Equality) form are both dropped in ExpressionBuilder.TranslatePattern. The test is Assert.Ignore'd (#829); all six Roslyn 3.11/4.14/latest debug/opt configs compile the fixture and fail only at the output comparison. Assisted-by: Claude:claude-fable-5:Claude Code
184 lines
3.0 KiB
C#
184 lines
3.0 KiB
C#
using System;
|
|
|
|
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
|
|
{
|
|
public class PatternMatchingImprovements
|
|
{
|
|
public enum Color
|
|
{
|
|
Red,
|
|
Green,
|
|
Blue
|
|
}
|
|
|
|
public class X
|
|
{
|
|
public int I { get; set; }
|
|
public char Ch { get; set; }
|
|
public double D { get; set; }
|
|
public decimal Dec { get; set; }
|
|
public Color Col { get; set; }
|
|
public string Text { get; set; }
|
|
public object Obj { get; set; }
|
|
public X Next { get; set; }
|
|
}
|
|
|
|
public void RelationalSubpatternInt(object x)
|
|
{
|
|
if (x is X { I: > 5 } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void RelationalSubpatternChar(object x)
|
|
{
|
|
if (x is X { Ch: >= 'a' } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void RelationalSubpatternDouble(object x)
|
|
{
|
|
if (x is X { D: <= 2.5 } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void RelationalSubpatternEnum(object x)
|
|
{
|
|
if (x is X { Col: > Color.Red } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void RelationalSubpatternNested(object x)
|
|
{
|
|
if (x is X { Next: { I: < 10 } } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void RelationalSubpatternTwoProperties(object x)
|
|
{
|
|
if (x is X { I: > 5, Ch: < 'x' } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public void NotStringConstant(object x)
|
|
{
|
|
if (x is X { Text: not "abc" } x2)
|
|
{
|
|
Console.WriteLine(x2.I);
|
|
}
|
|
}
|
|
|
|
public void NotDecimalConstant(object x)
|
|
{
|
|
if (x is X { Dec: not 3.5m } x2)
|
|
{
|
|
Console.WriteLine(x2.Text);
|
|
}
|
|
}
|
|
|
|
public bool TypeAndRelational(object x)
|
|
{
|
|
return x is int and > 5;
|
|
}
|
|
|
|
public bool TypeAndRelationalRange(object x)
|
|
{
|
|
return x is int and > 0 and < 10;
|
|
}
|
|
|
|
public bool SubpatternOrConstants(object x)
|
|
{
|
|
return x is X { I: 1 or 2 };
|
|
}
|
|
|
|
public bool SubpatternRelationalRange(object x)
|
|
{
|
|
return x is X { I: > 0 and < 10 };
|
|
}
|
|
|
|
public bool TypeOrType(object x)
|
|
{
|
|
return x is int or double;
|
|
}
|
|
|
|
public bool NullOrEmptyString(string s)
|
|
{
|
|
return s is null or "";
|
|
}
|
|
|
|
public string NegatedTypePatternWithDesignator(object x)
|
|
{
|
|
if (x is not string text)
|
|
{
|
|
return "no";
|
|
}
|
|
return text;
|
|
}
|
|
|
|
public bool NegatedRecursivePattern(object x)
|
|
{
|
|
return x is not X { I: 5 };
|
|
}
|
|
|
|
public string SwitchStatementRelational(int i)
|
|
{
|
|
switch (i)
|
|
{
|
|
case < 0:
|
|
return "negative";
|
|
case 0:
|
|
return "zero";
|
|
case > 100:
|
|
return "big";
|
|
default:
|
|
return "small";
|
|
}
|
|
}
|
|
|
|
public string SwitchStatementTypeAndRelational(object o)
|
|
{
|
|
switch (o)
|
|
{
|
|
case int and > 5:
|
|
return "big int";
|
|
case int:
|
|
return "int";
|
|
case string { Length: > 3 } text:
|
|
return text;
|
|
default:
|
|
return "other";
|
|
}
|
|
}
|
|
|
|
public string SwitchExpressionRelational(int i)
|
|
{
|
|
return i switch {
|
|
< 0 => "negative",
|
|
0 => "zero",
|
|
> 100 => "big",
|
|
_ => "small"
|
|
};
|
|
}
|
|
|
|
public string SwitchExpressionCharRange(char c)
|
|
{
|
|
return c switch {
|
|
>= 'a' and <= 'z' => "lower",
|
|
>= 'A' and <= 'Z' => "upper",
|
|
_ => "other"
|
|
};
|
|
}
|
|
}
|
|
}
|