Skip to content

Commit

Permalink
Ak1001 Context.Sender fix (#54)
Browse files Browse the repository at this point in the history
* AK2001: harden so rule only runs for Akka.NET v1.5.15 and later

* fixed package warning

* added failure cases for #52

* added fix to Analyzer

* Fix bad expected value

---------

Co-authored-by: Aaron Stannard <aaron@petabridge.com>
  • Loading branch information
Arkatufus and Aaronontheweb authored Jan 16, 2024
1 parent 6118cae commit e601f33
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,18 @@ async Task<int> LocalFunction(){
LocalFunction().PipeTo(Sender);
}
}
"""
""",
// Replying to Sender using Context.Sender
@"using Akka.Actor;
public sealed class MyActor : ReceiveActor{
public MyActor(){
Receive<string>(str => {
Context.Sender.Tell(str); // shouldn't flag this
});
}
}",
};

public static readonly
Expand Down Expand Up @@ -194,4 +205,33 @@ public Task FailureCase(

return Verify.VerifyAnalyzer(d.testCode, expected);
}

[Fact(DisplayName = "Should detect missing closure when using Context.Sender instead of this.Sender")]
public Task FailureCaseWithContextSender()
{
var code = """
using Akka.Actor;
using System.Threading.Tasks;
public sealed class MyActor : UntypedActor{
protected override void OnReceive(object message){
async Task<int> LocalFunction(){
await Task.Delay(10);
return message.ToString().Length;
}
// incorrect use of closures
LocalFunction().PipeTo(Context.Sender);
}
}
""";

var expected = Verify.Diagnostic()
.WithSpan(13, 25, 13, 31)
.WithArguments("Context.Sender")
.WithSeverity(DiagnosticSeverity.Error);

return Verify.VerifyAnalyzer(code, expected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using Akka.Analyzers.Fixes;
using Microsoft.CodeAnalysis;
using Verify = Akka.Analyzers.Tests.Utility.AkkaVerifier<Akka.Analyzers.MustCloseOverSenderWhenUsingPipeToAnalyzer>;

namespace Akka.Analyzers.Tests.Fixes.AK1000;
Expand Down Expand Up @@ -260,4 +261,53 @@ async Task<int> LocalFunction(){
return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
expectedDiagnostic);
}

[Fact(DisplayName = "Should fix missing closure when using Context.Sender instead of this.Sender")]
public Task FailureCaseWithContextSender()
{
var before = """
using Akka.Actor;
using System.Threading.Tasks;
public sealed class MyActor : UntypedActor{
protected override void OnReceive(object message){
async Task<int> LocalFunction(){
await Task.Delay(10);
return message.ToString().Length;
}
// incorrect use of closures
LocalFunction().PipeTo(Context.Sender);
}
}
""";

var after = """
using Akka.Actor;
using System.Threading.Tasks;
public sealed class MyActor : UntypedActor{
protected override void OnReceive(object message){
async Task<int> LocalFunction(){
await Task.Delay(10);
return message.ToString().Length;
}
var sender = this.Sender;
// incorrect use of closures
LocalFunction().PipeTo(sender);
}
}
""";

var expected = Verify.Diagnostic()
.WithSpan(13, 25, 13, 31)
.WithArguments("Context.Sender")
.WithSeverity(DiagnosticSeverity.Error);

return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
expected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ public override void AnalyzeCompilation(CompilationStartAnalysisContext context,

private static bool IsThisSenderSymbol(ISymbol? symbol, AkkaContext akkaContext)
{
// Check if the symbol is 'this.Sender'
return symbol is { Name: "Sender", ContainingType.BaseType: not null } &&
symbol.ContainingType.IsActorBaseSubclass(akkaContext);
// Check if the symbol is 'this.Sender' or 'Context.Sender'
return (symbol is { Name: "Sender", ContainingType.BaseType: not null } &&
symbol.ContainingType.IsActorBaseSubclass(akkaContext)) ||
(symbol is IPropertySymbol propertySymbol &&
propertySymbol.Name == "Sender" &&
SymbolEqualityComparer.Default.Equals(propertySymbol.ContainingType, akkaContext.AkkaCore.ActorContextType));
}
}

0 comments on commit e601f33

Please sign in to comment.