diff --git a/src/Akka.Analyzers.Tests/Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzerSpecs.cs b/src/Akka.Analyzers.Tests/Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzerSpecs.cs
deleted file mode 100644
index 2989ff5..0000000
--- a/src/Akka.Analyzers.Tests/Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzerSpecs.cs
+++ /dev/null
@@ -1,237 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (C) 2013-2024 .NET Foundation
-//
-// -----------------------------------------------------------------------
-
-using Microsoft.CodeAnalysis;
-using Verify = Akka.Analyzers.Tests.Utility.AkkaVerifier;
-
-namespace Akka.Analyzers.Tests.Analyzers.AK1000;
-
-public class MustCloseOverSenderWhenUsingPipeToAnalyzerSpecs
-{
- public static readonly TheoryData SuccessCases = new()
- {
- // ReceiveActor using PipeTo with a closure inside a Receive block
- @"using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- async Task LocalFunction(){
- await Task.Delay(10);
- return str.Length;
- }
-
- // correct use of closure
- var sender = Sender;
- LocalFunction().PipeTo(sender);
- });
- }
- }",
-
- // ReceiveActor using PipeTo calling a method from within a Receive block
- @"using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- Execute(str);
- });
- }
-
- private void Execute(string str){
- async Task LocalFunction(){
- await Task.Delay(10);
- return str.Length;
- }
-
- // correct use of closure
- var sender = Sender;
- LocalFunction().PipeTo(sender);
- }
- };",
-
- // Actor doing message handling in a Receive block without PipeTo at all
- @"using Akka.Actor;
-
- public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- Sender.Tell(str); // shouldn't flag this
- });
- }
- }",
-
- // Non-Actor class that has an IActorRef Sender property
- """
- using Akka.Actor;
- using System.Threading.Tasks;
-
- public class MyActor
- {
- public MyActor(IActorRef sender)
- {
- Sender = sender;
- }
-
- public IActorRef Sender { get; }
-
- public void Method()
- {
- async Task LocalFunction(){
- await Task.Delay(10);
- return 11;
- }
-
- // Sender is immutable on this custom non-Actor class, so shouldn't flag this
- LocalFunction().PipeTo(Sender);
- }
- }
- """,
- // Replying to Sender using Context.Sender
- @"using Akka.Actor;
-
- public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- Context.Sender.Tell(str); // shouldn't flag this
- });
- }
- }",
- };
-
- public static readonly
- TheoryData<(string testData, (int startLine, int startColumn, int endLine, int endColumn) spanData)>
- FailureCases = new()
- {
- // Receive actor using PipeTo without a closure inside a Receive block
- (@"using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- async Task LocalFunction(){
- await Task.Delay(10);
- return str.Length;
- }
-
- // incorrect use of closure
- LocalFunction().PipeTo(Sender);
- });
- }
- }", (14, 37, 14, 43)),
-
- // UntypedActor using PipeTo without a closure inside a OnReceive block
- (@"using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- // incorrect use of closure
- LocalFunction().PipeTo(Sender);
- }
- }", (13, 33, 13, 39)),
-
- // Actor is using Sender as the "sender" property on PipeTo, rather than the recipient
- (@"using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- // incorrect use of closure
- LocalFunction().PipeTo(Self, Sender);
- }
- }", (13, 33, 13, 39)),
-
- // Actor is using Sender as the "sender" property on PipeTo, rather than the recipient
- ( // Actor is using this.Sender rather than just "Sender"
- """
- using Akka.Actor;
- using System.Threading.Tasks;
-
- public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- // incorrect use of closure
- LocalFunction().PipeTo(this.Sender);
- }
- }
- """, (13, 25, 13, 31))
- };
-
- [Theory]
- [MemberData(nameof(SuccessCases))]
- public async Task SuccessCase(string testCode)
- {
- await Verify.VerifyAnalyzer(testCode).ConfigureAwait(true);
- }
-
- [Theory]
- [MemberData(nameof(FailureCases))]
- public Task FailureCase(
- (string testCode, (int startLine, int startColumn, int endLine, int endColumn) spanData) d)
- {
- var expected = Verify.Diagnostic()
- .WithSpan(d.spanData.startLine, d.spanData.startColumn, d.spanData.endLine, d.spanData.endColumn)
- .WithArguments("Sender")
- .WithSeverity(DiagnosticSeverity.Error);
-
- 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 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);
- }
-}
\ No newline at end of file
diff --git a/src/Akka.Analyzers.Tests/Fixes/AK1000/MustCloseOverSenderWhenUsingPipeToFixerSpecs.cs b/src/Akka.Analyzers.Tests/Fixes/AK1000/MustCloseOverSenderWhenUsingPipeToFixerSpecs.cs
deleted file mode 100644
index 4878f06..0000000
--- a/src/Akka.Analyzers.Tests/Fixes/AK1000/MustCloseOverSenderWhenUsingPipeToFixerSpecs.cs
+++ /dev/null
@@ -1,366 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (C) 2013-2024 .NET Foundation
-//
-// -----------------------------------------------------------------------
-
-using Akka.Analyzers.Fixes;
-using Microsoft.CodeAnalysis;
-using Verify = Akka.Analyzers.Tests.Utility.AkkaVerifier;
-
-namespace Akka.Analyzers.Tests.Fixes.AK1000;
-
-public class MustCloseOverSenderWhenUsingPipeToFixerSpecs
-{
- [Fact]
- public Task AddClosureInsideReceiveActor()
- {
- var before =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-
-public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- async Task LocalFunction(){
- await Task.Delay(10);
- return str.Length;
- }
-
- // incorrect use of closure
- LocalFunction().PipeTo(Sender);
- });
- }
-}";
-
- var after =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-
-public sealed class MyActor : ReceiveActor{
-
- public MyActor(){
- Receive(str => {
- async Task LocalFunction(){
- await Task.Delay(10);
- return str.Length;
- }
- var sender = this.Sender;
-
- // incorrect use of closure
- LocalFunction().PipeTo(sender);
- });
- }
-}";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(14, 29, 14, 35)
- .WithArguments("Sender");
-
- return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
- expectedDiagnostic);
- }
-
- [Fact]
- public Task AddClosureInsideOneLinerReceiveMethod()
- {
- var before =
-"""
-using Akka.Actor;
-using System.Threading.Tasks;
-
-public sealed class MyActor : ReceiveActor
-{
- public MyActor()
- {
- Receive(str => MessageHandler(str).PipeTo(Sender));
- }
-
- private Task MessageHandler(string str)
- {
- return Task.FromResult(str.Length);
- }
-}
-""";
-
- var after =
-"""
-using Akka.Actor;
-using System.Threading.Tasks;
-
-public sealed class MyActor : ReceiveActor
-{
- public MyActor()
- {
- Receive(str =>
- {
- var sender = this.Sender;
- MessageHandler(str).PipeTo(sender);
- });
- }
-
- private Task MessageHandler(string str)
- {
- return Task.FromResult(str.Length);
- }
-}
-""";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(8, 52, 8, 58)
- .WithArguments("Sender");
-
- return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
- expectedDiagnostic);
- }
-
- [Fact]
- public Task AddClosureInsideUntypedActor()
- {
- var before =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- // incorrect use of closure
- LocalFunction().PipeTo(Sender);
- }
-}";
-
- var after =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- var sender = this.Sender;
- // incorrect use of closure
- LocalFunction().PipeTo(sender);
- }
-}";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(15, 25, 15, 31)
- .WithArguments("Sender");
-
- return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
- expectedDiagnostic);
- }
-
- [Fact]
- public Task AddClosureWithoutErasingOtherPipeToArguments()
- {
- var before =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- // incorrect use of closure
- LocalFunction().PipeTo(Sender, success: r => 1);
- }
-}";
-
- var after =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- var sender = this.Sender;
- // incorrect use of closure
- LocalFunction().PipeTo(sender, success: r => 1);
- }
-}";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(15, 25, 15, 31)
- .WithArguments("Sender");
-
- return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
- expectedDiagnostic);
- }
-
- [Fact]
- public Task MustOnlyReplaceSenderArgumentWhenUsed()
- {
- var before =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- // incorrect use of closure
- LocalFunction().PipeTo(Self, Sender);
- }
-}";
-
- var after =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- var sender = this.Sender;
- // incorrect use of closure
- LocalFunction().PipeTo(Self, sender);
- }
-}";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(15, 25, 15, 31)
- .WithArguments("Sender");
-
- return Verify.VerifyCodeFix(before, after, MustCloseOverSenderWhenUsingPipeToFixer.Key_FixPipeToSender,
- expectedDiagnostic);
- }
-
- [Fact]
- public Task ReplaceSenderWhenUsedForBothRecipientAndSender()
- {
- var before =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- // incorrect use of closure
- LocalFunction().PipeTo(this.Sender, Sender);
- }
-}";
-
- var after =
- @"using Akka.Actor;
-using System.Threading.Tasks;
-using System;
-
-public sealed class MyActor : UntypedActor{
-
- protected override void OnReceive(object message){
- async Task LocalFunction(){
- await Task.Delay(10);
- return message.ToString().Length;
- }
-
- Console.WriteLine(Sender);
- var sender = this.Sender;
- // incorrect use of closure
- LocalFunction().PipeTo(sender, sender);
- }
-}";
-
- var expectedDiagnostic = Verify.Diagnostic()
- .WithSpan(15, 25, 15, 31)
- .WithArguments("Sender");
-
- 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 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 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);
- }
-}
\ No newline at end of file
diff --git a/src/Akka.Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzer.cs b/src/Akka.Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzer.cs
deleted file mode 100644
index c907b2f..0000000
--- a/src/Akka.Analyzers/AK1000/MustCloseOverSenderWhenUsingPipeToAnalyzer.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (C) 2013-2024 .NET Foundation
-//
-// -----------------------------------------------------------------------
-
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Diagnostics;
-
-namespace Akka.Analyzers;
-
-[DiagnosticAnalyzer(LanguageNames.CSharp)]
-public class MustCloseOverSenderWhenUsingPipeToAnalyzer()
- : AkkaDiagnosticAnalyzer(RuleDescriptors.Ak1001CloseOverSenderUsingPipeTo)
-{
- public override void AnalyzeCompilation(CompilationStartAnalysisContext context, AkkaContext akkaContext)
- {
- Guard.AssertIsNotNull(context);
- Guard.AssertIsNotNull(akkaContext);
-
- context.RegisterSyntaxNodeAction(ctx =>
- {
- var invocationExpr = (InvocationExpressionSyntax)ctx.Node;
-
- // Check if it's a PipeTo method call
- if (invocationExpr.Expression is MemberAccessExpressionSyntax
- {
- Name.Identifier.ValueText: "PipeTo"
- } memberAccessExpr)
- {
- // Check if the containing type is an Akka.NET actor
- var containingType = ctx.SemanticModel.GetEnclosingSymbol(invocationExpr.SpanStart)?.ContainingType;
- if (containingType != null && containingType.IsActorBaseSubclass(akkaContext))
- // Check if 'this.Sender' is used in the arguments
- foreach (var arg in invocationExpr.ArgumentList.Arguments)
- {
- var symbol = ctx.SemanticModel.GetSymbolInfo(arg.Expression).Symbol;
- if (IsThisSenderSymbol(symbol, akkaContext))
- {
- var diagnostic = Diagnostic.Create(RuleDescriptors.Ak1001CloseOverSenderUsingPipeTo,
- memberAccessExpr.Name.GetLocation());
- ctx.ReportDiagnostic(diagnostic);
- break; // Report only once per invocation
- }
- }
- }
- }, SyntaxKind.InvocationExpression);
- }
-
- private static bool IsThisSenderSymbol(ISymbol? symbol, AkkaContext 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));
- }
-}
\ No newline at end of file