private static void AnalyzeTell(SyntaxNodeAnalysisContext context)
{
var invocationExpr = (InvocationExpressionSyntax)context.Node;
// technically this should be a MemberAccessExpression, since it's invoked as a method off of IActorRef / ICanTell
var memberAccessExpr = invocationExpr.Expression as MemberAccessExpressionSyntax;
if (memberAccessExpr?.Name.ToString() != TargetMethodName) return;
// need to verify that this `Tell` method is actually `ICanTell.Tell`
var memberSymbol = context.SemanticModel.GetSymbolInfo(memberAccessExpr).Symbol as IMethodSymbol;
var memberIsICanTell = (memberSymbol?.ToString().StartsWith(ICanTellMethodFQN) ?? false) || (memberSymbol?.ToString().StartsWith(IActorRefTellMethodFQN) ?? false);
var memberIsActorRefExtension = memberSymbol?.ToString().StartsWith(ActorRefImplicitSenderTellFQN) ?? false;
if (!memberIsICanTell && !memberIsActorRefExtension) return;
// need to get the first argument being passed to the `Tell` method
var argumentList = invocationExpr.ArgumentList as ArgumentListSyntax;
if ((argumentList?.Arguments.Count ?? 0) < 1) return;
// ReSharper disable once PossibleNullReferenceException //already validated as not null above
var messageArgument =
context.SemanticModel.GetSymbolInfo(memberIsICanTell ? argumentList.Arguments[0].Expression : argumentList.Arguments[1].Expression).Symbol;
var allInterfaces = ((messageArgument as INamedTypeSymbol)?.Interfaces ?? ImmutableArray<INamedTypeSymbol>.Empty).Concat(messageArgument?.ContainingType.Interfaces ?? ImmutableArray<INamedTypeSymbol>.Empty).ToImmutableArray();
if (allInterfaces.Any(y => y.ToString().StartsWith(ISystemMsgFQN)))
{
// found an ISystemMessage being passed into a Tell method
var diagnostic = Diagnostic.Create(Rule, argumentList.GetLocation(), messageArgument.ToString(), DiagnosticSeverity.Error);
context.ReportDiagnostic(diagnostic);
}
}