Skip to content

Commit f826bb5

Browse files
authored
Merge pull request #120 from PhenX/feature/support-switch-expressions
Add partial support for switch expression, by converting them to nested ternary expressions
2 parents 2075d4c + b2bdef7 commit f826bb5

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

src/EntityFrameworkCore.Projectables.Generator/ExpressionSyntaxRewriter.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,57 @@ public ExpressionSyntaxRewriter(INamedTypeSymbol targetTypeSymbol, NullCondition
145145

146146
}
147147

148+
public override SyntaxNode? VisitSwitchExpression(SwitchExpressionSyntax node)
149+
{
150+
// Reverse arms order to start from the default value
151+
var arms = node.Arms.Reverse();
152+
153+
ExpressionSyntax? currentExpression = null;
154+
155+
foreach (var arm in arms)
156+
{
157+
var armExpression = (ExpressionSyntax)Visit(arm.Expression);
158+
159+
// Handle fallback value
160+
if (currentExpression == null)
161+
{
162+
currentExpression = arm.Pattern is DiscardPatternSyntax
163+
? armExpression
164+
: SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression);
165+
166+
continue;
167+
}
168+
169+
// Handle each arm, only if it's a constant expression
170+
if (arm.Pattern is ConstantPatternSyntax constant)
171+
{
172+
ExpressionSyntax expression = SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, (ExpressionSyntax)Visit(node.GoverningExpression), constant.Expression);
173+
174+
// Add the when clause as a AND expression
175+
if (arm.WhenClause != null)
176+
{
177+
expression = SyntaxFactory.BinaryExpression(
178+
SyntaxKind.LogicalAndExpression,
179+
expression,
180+
(ExpressionSyntax)Visit(arm.WhenClause.Condition)
181+
);
182+
}
183+
184+
currentExpression = SyntaxFactory.ConditionalExpression(
185+
expression,
186+
armExpression,
187+
currentExpression
188+
);
189+
190+
continue;
191+
}
192+
193+
throw new InvalidOperationException("Switch expressions rewriting is only supported with constant values");
194+
}
195+
196+
return currentExpression;
197+
}
198+
148199
public override SyntaxNode? VisitMemberBindingExpression(MemberBindingExpressionSyntax node)
149200
{
150201
if (_conditionalAccessExpressionsStack.Count > 0)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// <auto-generated/>
2+
#nullable disable
3+
using EntityFrameworkCore.Projectables;
4+
5+
namespace EntityFrameworkCore.Projectables.Generated
6+
{
7+
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
8+
static class _Foo_SomeNumber
9+
{
10+
static global::System.Linq.Expressions.Expression<global::System.Func<global::Foo, int, int>> Expression()
11+
{
12+
return (global::Foo @this, int input) => input == 1 ? 2 : input == 3 ? 4 : input == 4 && @this.FancyNumber == 12 ? 48 : 1000;
13+
}
14+
}
15+
}

tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,33 @@ class Foo {
17841784
return Verifier.Verify(result.GeneratedTrees[0].ToString());
17851785
}
17861786

1787+
[Fact]
1788+
public Task SwitchExpression()
1789+
{
1790+
var compilation = CreateCompilation(@"
1791+
using EntityFrameworkCore.Projectables;
1792+
1793+
class Foo {
1794+
public int? FancyNumber { get; set; }
1795+
1796+
[Projectable(NullConditionalRewriteSupport = NullConditionalRewriteSupport.Rewrite)]
1797+
public int SomeNumber(int input) => input switch {
1798+
1 => 2,
1799+
3 => 4,
1800+
4 when FancyNumber == 12 => 48,
1801+
_ => 1000,
1802+
};
1803+
}
1804+
");
1805+
1806+
var result = RunGenerator(compilation);
1807+
1808+
Assert.Empty(result.Diagnostics);
1809+
Assert.Single(result.GeneratedTrees);
1810+
1811+
return Verifier.Verify(result.GeneratedTrees[0].ToString());
1812+
}
1813+
17871814
[Fact]
17881815
public Task GenericTypes()
17891816
{

0 commit comments

Comments
 (0)