拥有 IMethodSymbol 是否有可能在 Roslyn 中从该方法中找出所有方法和字段 used/called?

Having IMethodSymbol is it possible in Roslyn to figure out all the methods and fields used/called from within that method?

我有 IMethodSymbol 对象,我想从该方法中找出所有方法和字段 used/called。

我已经用 Mono.Cecil 做了。然而,这还不够好,因为任何涉及动态类型的代码都只是反射。因此,检查二进制代码在这里没有用 - 我们必须检查源代码。

因此,我知道使用动态参数的方法的 IMethodSymbol(它调用 Binder.InvokeMember)。我知道源代码分析可以告诉我正在调用什么方法。

我熟悉 SymbolFinder class 并且能够使用它的 FindReferencesAsync 方法。但是我不知道如何将它用于我的目的,即给定方法找到它使用的所有符号。

我错过了什么?

编辑 1

所以我想出了如何获得顶级操作:

var op = model.GetOperation(method.DeclaringSyntaxReferences[0].GetSyntax());

其中 model 是各自的 SemanticModel 实例,method 是我的 IMethodSymbol。但是确实有无数种 IOperation。我需要一种方便的方式来导航它们。我想 OperationWalker 是我需要的。会继续探索。

我找到了路 - OperationWalker

就我而言,我有以下“助行器”(进行中):

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
using System;
using System.Collections.Generic;

namespace CSTool
{
    public class DynamicOperationWalker : OperationWalker
    {
        public readonly List<IMethodSymbol> Result = new();
        public readonly List<(SyntaxNode,string)> Unresolved = new();

        public override void VisitDynamicIndexerAccess(IDynamicIndexerAccessOperation operation)
        {
            throw new NotImplementedException();
        }

        public override void VisitDynamicInvocation(IDynamicInvocationOperation operation)
        {
            var memberReferenceOp = (IDynamicMemberReferenceOperation)operation.Operation;
            switch (memberReferenceOp.Instance.Type)
            {
                case INamedTypeSymbol type:
                    {
                        var memberName = memberReferenceOp.MemberName;
                        var members = type.GetMembers(memberName);
                        if (members.Length > 1)
                        {
                            throw new NotImplementedException();
                        }
                        Result.Add((IMethodSymbol)members[0]);
                        break;
                    }

                case IDynamicTypeSymbol dynamicType:
                    Unresolved.Add((operation.Syntax, memberReferenceOp.MemberName));
                    break;
            }
        }

        public override void VisitDynamicMemberReference(IDynamicMemberReferenceOperation operation)
        {
            throw new NotImplementedException();
        }

        public override void VisitDynamicObjectCreation(IDynamicObjectCreationOperation operation)
        {
            throw new NotImplementedException();
        }
    }
}

我这样调用它是为了检查 methodSymbol:

给出的方法的主体
var op = model.GetOperation(methodSymbol.DeclaringSyntaxReferences[0].GetSyntax());
var walker = new DynamicOperationWalker();
walker.Visit(op);

我只对动态调用感兴趣,因为非动态调用是 Mono.Cecil 给我的。