I have written a small custom Rosyln Analyzer that checks for certain method invocations, and if they were executed within a loop context or expression. An example of the code I am wanting to warn on can be found below:
IMessageHandlerContext context = default;
foreach (var item in dataItems)
{
await context.Send<IProcessItem>(m =>
{
m.Item = "my-item-id";
});
}
I perform a two-stage analysis by first checking the method invocation is one I am specifically interested in, by looking at the method name. The second change is to look at the wider context, and test if the Invocation happens inside a loop context or expression. The Analyzer works for For and ForEach constructs, but fails to highlight for the While loop expression. I am satisified the first stage, which looks at Method names, is working fine.
private void CheckForMethodInvocationInLoop(SyntaxNodeAnalysisContext context)
{
var invocation = (InvocationExpressionSyntax)context.Node;
var containsMethod = false;
// Removed stage one code for brevity
if (!containsMethod)
return;
var loopFound = invocation.FirstAncestorOrSelf<StatementSyntax>(ss =>
ss.IsKind(SyntaxKind.ForStatement) ||
ss.IsKind(SyntaxKind.ForEachStatement) ||
ss.IsKind(SyntaxKind.WhileStatement));
if (loopFound != null)
{
context.ReportDiagnostic(Diagnostic.Create(Rule, invocation.GetLocation()));
}
}
The Analyzer correctly highlights method invocations within For and ForEach expressions, however does not identify the same invocations in While expressions.
Invocation inside ForEach expression, syntax hightlighting
Invocation inside While expression, no syntax highlighting
I have tried a couple of techniques to check the invocation context. Firstly, by recursively checking each parent, and it's parent, on the invocation statement. I have also attempted to utilise the method FirstAncestorOrSelf
on the invocation itself to test for a kind of Statement. By inspecting the Syntax Visualizer I cannot determine why the analyzer cannot identify the invocation inside the While expression.
CodePudding user response: