Roslyn: получение инструкций из базового блока

#c# #roslyn #roslyn-code-analysis #control-flow-graph

#c# #roslyn #roslyn-анализ кода #поток-график управления

Вопрос:

Граф потока управления, созданный в roslyn, содержит блоки (basicblock) в качестве узлов, каждый базовый блок содержит одну или более инструкций. для базовых блоков, содержащих более одной инструкции, я пытаюсь получить все инструкции и их типы, вот что я сделал :

 var cfg = ControlFlowGraph.Create(method);
foreach(var block in cfg.Blocks)
{
    foreach(var operation in block.Operations)
    {
        var syntax = operation.Syntax;
        Console.WriteLine(syntax.Kind());
    }
}
  

для следующего метода :

 public int method(int x, int y)
{
y = 10;
x = y;
return x   y;
}
  

я получаю результат :

 ExpressionStatement
ExpressionStatement
  

но я хочу получить точную инструкцию и ее тип, например, для инструкции, которую x = y; я хочу получить AssignmentExpressionSyntax .
Также я хочу выполнить некоторую операцию над каждой инструкцией в зависимости от ее типа.

Ответ №1:

Поскольку вы смотрите на тип синтаксиса, ExpressionStatement является правильным типом для инструкции. Вы можете определить тип выражений, посмотрев на тип выражения в ExpressionStatement.

 if (operation.Syntax is ExpressionStatement es)
{
    var kind = es.Expression.Kind();
}
  

Однако, если вы используете операции (IOperation), то, вероятно, вы можете получить более подробную информацию, пропустив синтаксис и используя OperationKind.

Комментарии:

1. Это ответ, который я искал, я просто изменил ExpressionStatement на ExpressionStatementSyntax