C# 有了IMethodSymbol,在Roslyn中是否可以计算出该方法中使用/调用的所有方法和字段?
我有C# 有了IMethodSymbol,在Roslyn中是否可以计算出该方法中使用/调用的所有方法和字段?,c#,roslyn,C#,Roslyn,我有IMethodSymbol对象,我想找出该方法使用/调用的所有方法和字段 我已经用Mono.Cecil做过了。然而,这还不够好,因为任何涉及动态类型的代码都只是反射。因此,检查二进制代码在这里是无用的-我们必须检查源代码 因此,我知道该方法的IMethodSymbol使用动态参数(它调用Binder.InvokeMember)。我知道源代码分析可以告诉我调用了什么方法 我熟悉SymbolFinder类,并且能够使用它的FindReferencesAsync方法。但我看不出如何将其用于我的目的
IMethodSymbol
对象,我想找出该方法使用/调用的所有方法和字段
我已经用Mono.Cecil做过了。然而,这还不够好,因为任何涉及动态类型的代码都只是反射。因此,检查二进制代码在这里是无用的-我们必须检查源代码
因此,我知道该方法的IMethodSymbol
使用动态参数(它调用Binder.InvokeMember
)。我知道源代码分析可以告诉我调用了什么方法
我熟悉SymbolFinder
类,并且能够使用它的FindReferencesAsync
方法。但我看不出如何将其用于我的目的,即,给定该方法,找到它使用的所有符号
我错过了什么
编辑1
因此,我想出了如何获得顶级操作:
var op = model.GetOperation(method.DeclaringSyntaxReferences[0].GetSyntax());
其中,
model
是相应的SemanticModel
实例,method
是我的IMethodSymbol
。但实际上有无数种操作。我需要一种方便的方法来导航它们。我想我需要的是OperationWalker
。将继续探索。我找到了方法-OperationWalker
就我而言,我有以下“walker”(正在进行的工作):
我只对动态调用感兴趣,因为非动态调用是由Mono.Cecil
提供给我的
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();
}
}
}
var op = model.GetOperation(methodSymbol.DeclaringSyntaxReferences[0].GetSyntax());
var walker = new DynamicOperationWalker();
walker.Visit(op);