Skip to content

Commit 78193fa

Browse files
committed
ToCSharpCode: add comments to invalid block expressions
1 parent 3369c2b commit 78193fa

File tree

2 files changed

+66
-16
lines changed

2 files changed

+66
-16
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

+11-8
Original file line numberDiff line numberDiff line change
@@ -6978,7 +6978,6 @@ internal static StringBuilder ToCSharpString(this Expression e, StringBuilder sb
69786978
var x = (ConditionalExpression)e;
69796979
if (e.Type == typeof(void)) // otherwise output as ternary expression
69806980
{
6981-
sb.NewLine(lineIdent, identSpaces);
69826981
sb.Append("if (");
69836982
x.Test.ToCSharpString(sb, EnclosedIn.IfTest, lineIdent, stripNamespace, printType, identSpaces, notRecognizedToCode);
69846983
sb.Append(')');
@@ -7016,9 +7015,15 @@ internal static StringBuilder ToCSharpString(this Expression e, StringBuilder sb
70167015
return BlockToCSharpString((BlockExpression)e, sb, lineIdent, stripNamespace, printType, identSpaces, notRecognizedToCode: notRecognizedToCode);
70177016
else
70187017
{
7019-
sb.Append('{');
7018+
var isExpressionBlock = e.Type != typeof(void) && sb.Length > 0;
7019+
sb.Append("{");
7020+
if (isExpressionBlock)
7021+
sb.Append(" /* BlockExpression cannot be written in C#. Please rewrite the code inside these braces as a C# expression, or reorganize the parent expression as a block. */");
70207022
BlockToCSharpString((BlockExpression)e, sb, lineIdent + identSpaces, stripNamespace, printType, identSpaces, notRecognizedToCode: notRecognizedToCode);
7021-
return sb.AddSemicolonIfFits().NewLineIdent(lineIdent).Append('}');
7023+
7024+
if (isExpressionBlock)
7025+
sb.Append("/* <- block result */");
7026+
return sb.NewLineIdent(lineIdent).Append('}');
70227027
}
70237028
}
70247029
case ExpressionType.Loop:
@@ -7170,12 +7175,11 @@ void PrintPart(Expression part)
71707175
}
71717176
case ExpressionType.Default:
71727177
{
7173-
return e.Type == typeof(void) ? sb : // `default(void)` does not make sense in the C#
7174-
!e.Type.IsValueType && !e.Type.IsGenericParameter ? sb.Append("null") :
7175-
sb.Append("default(").Append(e.Type.ToCode(stripNamespace, printType)).Append(')');
7178+
return e.Type == typeof(void) ? sb // `default(void)` does not make sense in the C#
7179+
: sb.Append("default(").Append(e.Type.ToCode(stripNamespace, printType)).Append(')');
71767180
}
71777181
case ExpressionType.TypeIs:
7178-
case ExpressionType.TypeEqual: // TODO: type equal
7182+
case ExpressionType.TypeEqual:
71797183
{
71807184
var x = (TypeBinaryExpression)e;
71817185
sb.Append('(');
@@ -8127,4 +8131,3 @@ public RequiresUnreferencedCodeAttribute(string message)
81278131
}
81288132
}
81298133
#endif
8130-
}

test/FastExpressionCompiler.UnitTests/ToCSharpStringTests.cs

+55-8
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,62 @@ public void Outputs_closed_generic_type_constant_correctly()
3232
}
3333

3434
[Test]
35-
public void Outputs_default_reference_type_is_just_null()
35+
public void Lambda_with_block_body()
3636
{
37-
var cs = Default(typeof(string)).ToCSharpString();
38-
Assert.AreEqual("null;", cs);
37+
var variable = Parameter(typeof(int), "variable");
38+
var e = Lambda<Func<int>>(Block(new [] { variable }, Assign(variable, Constant(1)), Add(variable, Constant(2))));
39+
40+
var cs = e.ToCSharpString();
3941

40-
cs = Default(typeof(System.Collections.Generic.List<string>)).ToCSharpString();
41-
Assert.AreEqual("null;", cs);
42+
Assert.AreEqual("""
43+
(Func<int>)(() =>
44+
{
45+
int variable = default;
46+
variable = 1;
47+
return (variable + 2);
48+
});
49+
""", cs);
4250
}
4351

52+
[Test]
53+
public void Nested_blocks()
54+
{
55+
var v1 = Parameter(typeof(int), "v1");
56+
var v2 = Parameter(typeof(int), "v2");
57+
var cs = Block(new [] { v1 },
58+
Assign(v1, Constant(2)),
59+
Block(new [] { v2 },
60+
Assign(v2, Constant(3)),
61+
AddAssign(v1, v2),
62+
IfThen(
63+
Equal(v1, Constant(5)),
64+
Block(
65+
Assign(v2, Constant(7)),
66+
AddAssign(v1, v2)
67+
)
68+
)
69+
),
70+
v1
71+
).ToCSharpString();
72+
Console.WriteLine(cs);
73+
Assert.AreEqual("""
74+
{
75+
int v1 = default;
76+
v1 = 2;
77+
int v2 = default;
78+
v2 = 3;
79+
v1 += v2;
80+
if (v1 == 5)
81+
{
82+
v2 = 7;
83+
v1 += v2;
84+
}
85+
v1;
86+
};
87+
""", cs);
88+
}
89+
90+
4491
[Test]
4592
public void Somehow_handles_block_in_expression()
4693
{
@@ -51,10 +98,10 @@ public void Somehow_handles_block_in_expression()
5198
variable
5299
)).ToCSharpString();
53100
Assert.AreEqual("""
54-
(1 + {
55-
int variable;
101+
(1 + { /* BlockExpression cannot be written in C#. Please rewrite the code inside these braces as a C# expression, or reorganize the parent expression as a block. */
102+
int variable = default;
56103
variable = 2;
57-
variable;
104+
variable;/* <- block result */
58105
});
59106
""", cs);
60107
}

0 commit comments

Comments
 (0)