Skip to content

Commit

Permalink
Handle complex capture assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
aromaa committed Jan 17, 2024
1 parent 3796893 commit 9e456f7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,19 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
}
else if (modified is IdentifierNameSyntax { Parent: not MemberAccessExpressionSyntax { Expression: IdentifierNameSyntax { Identifier.Text: "__functionalInterface" } } } identifier)
{
bool captured = dataFlowAnalysis.Captured.Any(i => i.Name == identifier.Identifier.Text);
if (captured)
ISymbol? captured = dataFlowAnalysis.Captured.SingleOrDefault(i => i is ILocalSymbol && i.Name == identifier.Identifier.Text);
if (captured is not null)
{
return SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName("__functionalInterface"), identifier);
foreach (SyntaxReference reference in captured.DeclaringSyntaxReferences)
{
SyntaxNode declaration = reference.GetSyntax();
if (declaration is VariableDeclaratorSyntax)
{
return SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName("__functionalInterface"), identifier);
}
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion src/FunctionalInterfaces.TestAssembly/ActionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void CallActionWithCapturedIntReferenceOutside()
{
int param = 50;

_ = param;
Assert.Equal(50, param);

ActionTests.Invoke(() =>
{
Expand All @@ -54,6 +54,26 @@ public static void CallActionWithCapturedIntTwoTimes()
});
}

public static void CallActionWithComplexCaptureAssignment()
{
DataHolder param = new(50);
if (param.Data is not int intParam)
{
Assert.Fail("Unreachable");

return;
}

Assert.Equal(50, intParam);

ActionTests.Invoke(() =>
{
Assert.Equal(50, intParam);
});
}

private sealed record DataHolder(object Data);

public static void CallVirtualActionWithCapturedInt()
{
int param = 50;
Expand Down

0 comments on commit 9e456f7

Please sign in to comment.