Обнаружение рекурсивных вызовов в коде C#



visual-studio recursion (1)

Вы можете сделать это с Mono.Cecil .

Вот простая программа LINQPad, которая демонстрирует:

const string AssemblyFilePath = @"path\to\assembly.dll";

void Main()
{
    var assembly = ModuleDefinition.ReadModule(AssemblyFilePath);
    var calls =
        (from type in assembly.Types
         from caller in type.Methods
         where caller != null && caller.Body != null
         from instruction in caller.Body.Instructions
         where instruction.OpCode == OpCodes.Call
         let callee = instruction.Operand as MethodReference
         select new { type, caller, callee }).Distinct();

    var directRecursiveCalls =
        from call in calls
        where call.callee == call.caller
        select call.caller;

    foreach (var method in directRecursiveCalls)
        Debug.WriteLine(method.DeclaringType.Namespace + "." + method.DeclaringType.Name + "." + method.Name + " calls itself");
}

Это выведет методы, которые вызывают себя напрямую. Обратите внимание, что я только обработал инструкцию Call , я не уверен, как правильно обрабатывать другие инструкции вызова здесь, или даже если это вообще возможно.

Предостережение : обратите внимание, что это произойдет, поскольку я обработал только эту единственную инструкцию, и буду работать только со статически скомпилированными вызовами.

Виртуальные вызовы, вызовы через интерфейсы, которые просто возвращаются к одному и тому же методу, не будут обнаружены этим, для этого необходим намного более сложный код.

Я хочу найти все рекурсивные вызовы в моем коде.

Если я открываю файл в Visual Studio, в левой части редактора появляется значок «Рекурсивный вызов».

Я хочу проверить все решение для таких звонков.

Я использовал инструменты командной строки Resharper и надстройку VS Resharper - Проверка кода, но не повезло, это правило не применяется в их наборе правил.

Есть ли способ, которым я мог бы проверить все решение - я действительно не хочу открывать каждый файл и проверять синий значок "Рекурсивный вызов" :)

Изменить: я заинтересован в одноуровневой рекурсии





code-analysis