Skip to content

Commit d11c407

Browse files
#3569: Don't move out variable declarations out of lambdas.
1 parent 995d31f commit d11c407

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,15 @@ void FindInsertionPoints(AstNode node, int nodeLevel)
290290
// track loops and function bodies as scopes, for comparison with CaptureScope.
291291
scopeTracking.Add((new InsertionPoint { level = nodeLevel, nextNode = node }, scope));
292292
}
293+
else if (node is LambdaExpression { Body: Expression expr })
294+
{
295+
// expression-bodied lambdas don't have a BlockStatement linking to the BlockContainer
296+
scope = node.Annotation<ILFunction>()?.Body as BlockContainer;
297+
if (scope != null)
298+
{
299+
scopeTracking.Add((new InsertionPoint { level = nodeLevel + 1, nextNode = expr }, scope));
300+
}
301+
}
293302
else
294303
{
295304
scope = null; // don't remove a scope if we didn't add one
@@ -455,7 +464,7 @@ void ResolveCollisions()
455464
// We can only insert variable declarations in blocks, but FindInsertionPoints() didn't
456465
// guarantee that it finds only blocks.
457466
// Fix that up now.
458-
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement))
467+
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement or LambdaExpression))
459468
{
460469
if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault() && IsMatchingAssignment(v, out _))
461470
{
@@ -673,6 +682,17 @@ void InsertVariableDeclarations(TransformContext context)
673682
}
674683
var vds = new VariableDeclarationStatement(type, v.Name, initializer);
675684
vds.Variables.Single().AddAnnotation(new ILVariableResolveResult(ilVariable));
685+
if (v.InsertionPoint.nextNode.Parent is LambdaExpression lambda)
686+
{
687+
Debug.Assert(lambda.Body is not BlockStatement);
688+
lambda.Body = new BlockStatement() {
689+
new ReturnStatement((Expression)lambda.Body.Detach())
690+
};
691+
}
692+
if (v.InsertionPoint.nextNode.Parent is ReturnStatement)
693+
{
694+
v.InsertionPoint = v.InsertionPoint.Up();
695+
}
676696
Debug.Assert(v.InsertionPoint.nextNode.Role == BlockStatement.StatementRole);
677697
if (v.DefaultInitialization == VariableInitKind.NeedsSkipInit)
678698
{

0 commit comments

Comments
 (0)