0

I am developing a Roslyn analyzer to detect the use of a specific method, method1. I want to allow the use of this method in for and while loops, and create an issue in all other cases in the code.

How can I do that? The code I developed detects method1 everywhere. I want now each time I find the function, to check if it's in a loop or not, and generate an error only if it is not in a loop.

ironstone13
  • 3,325
  • 18
  • 24
Samorix
  • 307
  • 4
  • 17
  • 2
    But what is the level of *nesting* that you want to allow? How far down the call stack should your analyzer go? What if you have a call chain `methodN`->`method2`->`method1` and the loop that calls this chain is in `methodN`? Also, think about the fact that the structure of your code at runtime and at compile time is not the same. What if you pass `method1` as a delegate to another method that wraps it in a loop, at runtime? Like LINQ uses `Func`, for instance. – ironstone13 Aug 14 '17 at 15:35

1 Answers1

3

The method call will be a descendant of the loop declaration if it is inside it. You can access the Ancestors property of any SyntaxNode. Start going up among the ancestors of the MethodInvocation node you detected until you hit a loop or a member declaration.

If you hit a loop (ForStatementSyntax or WhileStatementSyntax) then you are good. If you hit a MemberDeclarationSyntax node that means you have reached the start of whatever block in which your method1 is being called and should probably throw an error.

At this point, your immediate problem is mostly solved, and you have to decide how many corner cases you want to cover. What if it is called from a lambda expression? What if a method that calls method1 is called from a loop? Or from a recursive method?

You can detect all these cases but you have to decide if it is worth the effort.

Tamás Szabó
  • 1,388
  • 11
  • 23