Skip to content

Commit 6f824cf

Browse files
Fix conversion of single-statement multiline lambda to block syntax
Fixes #1012 by ensuring that when a VB.NET MultiLineLambdaExpressionSyntax contains a single statement that is not an ExpressionStatementSyntax or ReturnStatementSyntax (such as a local declaration statement with a multiline LINQ query), it is converted to a block-bodied lambda in C# rather than an arrow expression clause. Also adds a corresponding characterization test. Co-authored-by: GrahamTheCoder <2490482+GrahamTheCoder@users.noreply.github.com>
1 parent 2c2b64e commit 6f824cf

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

CodeConverter/CSharp/LambdaConverter.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,17 @@ public async Task<CSharpSyntaxNode> ConvertAsync(VBSyntax.LambdaExpressionSyntax
7979
convertedStatements = convertedStatements.Select(l => l.WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed)).ToList();
8080
block = SyntaxFactory.Block(convertedStatements);
8181
} else if (singleStatement.TryUnpackSingleExpressionFromStatement(out expressionBody)) {
82-
arrow = SyntaxFactory.ArrowExpressionClause(expressionBody);
82+
if (vbNode is VBasic.Syntax.MultiLineLambdaExpressionSyntax && singleStatement is not ExpressionStatementSyntax && singleStatement is not ReturnStatementSyntax) {
83+
singleStatement = singleStatement.WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed);
84+
block = SyntaxFactory.Block(singleStatement);
85+
expressionBody = null;
86+
} else {
87+
arrow = SyntaxFactory.ArrowExpressionClause(expressionBody);
88+
}
8389
} else {
90+
if (vbNode is VBasic.Syntax.MultiLineLambdaExpressionSyntax) {
91+
singleStatement = singleStatement.WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed);
92+
}
8493
block = SyntaxFactory.Block(singleStatement);
8594
}
8695

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Threading.Tasks;
2+
using ICSharpCode.CodeConverter.Tests.TestRunners;
3+
using Xunit;
4+
5+
namespace ICSharpCode.CodeConverter.Tests.CSharp.ExpressionTests;
6+
7+
public class LambdaTests : ConverterTestBase
8+
{
9+
[Fact]
10+
public async Task Issue1012_MultiLineLambdaWithSingleStatement()
11+
{
12+
await TestConversionVisualBasicToCSharpAsync(@"Imports System.Collections.Generic
13+
Imports System.Linq
14+
Imports System.Threading.Tasks
15+
16+
Public Class ConversionTest3
17+
Private Class MyEntity
18+
Property EntityId As Integer
19+
Property Name As String
20+
End Class
21+
Private Sub BugRepro()
22+
23+
Dim entities As New List(Of MyEntity)
24+
25+
Parallel.For(1, 3, Sub(i As Integer)
26+
Dim result As String = (From e In entities
27+
Where e.EntityId = 123
28+
Select e.Name).Single
29+
End Sub)
30+
End Sub
31+
End Class", @"using System.Collections.Generic;
32+
using System.Linq;
33+
using System.Threading.Tasks;
34+
35+
public partial class ConversionTest3
36+
{
37+
private partial class MyEntity
38+
{
39+
public int EntityId { get; set; }
40+
public string Name { get; set; }
41+
}
42+
private void BugRepro()
43+
{
44+
45+
var entities = new List<MyEntity>();
46+
47+
Parallel.For(1, 3, (i) =>
48+
{
49+
string result = (from e in entities
50+
where e.EntityId == 123
51+
select e.Name).Single();
52+
});
53+
}
54+
}");
55+
}
56+
}

0 commit comments

Comments
 (0)