使用 roslyn 在 C# 源代码中查找类引用

问题描述 投票:0回答:1

我想找到代码中的所有类引用。我已经研究过 Roslyn 及其功能,但我对它的所有功能有点不知所措。我见过的所有示例都以正在读入的小代码片段开始,但我只想将我的代码指向一个程序集,让它发挥魔力。

因此,给定这样的类结构:

class MyClassA { }
class MyClassB 
{
   void Do()
   {
      var instance = new MyClassA();      
   }
}

我真正想要的是找到

MyClassA
MyClassB
之间的所有依赖关系(例如 Visual Studio 的“引用”功能,仅在代码中)。我可以将其指向已编译的程序集,也可以指向 proj 或 sln 文件。

更新

我查看了评论中的建议,现在已经构建了类似这样的东西:

class Program
{
    static async Task Main(string[] args)
    {
        using (var workspace = MSBuildWorkspace.Create())
        {
            var solution = await workspace.OpenSolutionAsync(
                "C:\\src\\mySolution.sln");

            foreach (var project in solution.Projects)
            {
                var compilation = await project.GetCompilationAsync();
                foreach (var document in project.Documents)
                {
                    var model = document.GetSemanticModelAsync().Result;
                }

                var symbol = compilation.ResolveType("MyClassA").FirstOrDefault();

                if (symbol != null)
                {
                    var references = await SymbolFinder.FindReferencesAsync(symbol, solution);
                }
            }
        }
    }
}

public static class Extensions
{
    public static IEnumerable<INamedTypeSymbol> ResolveType(this Compilation compilation, string classFullName)
    {
        return new IAssemblySymbol[] { compilation.Assembly }
            .Concat(compilation.References
                .Select(compilation.GetAssemblyOrModuleSymbol)
                .OfType<IAssemblySymbol>())
            .Select(asm => asm.GetTypeByMetadataName(classFullName))
            .Where(cls => cls != null);
    }

但是,我没有找到任何符号,而且没有一个项目实际上包含文档?我做错了什么。

c# reflection roslyn
1个回答
0
投票

我也在寻找这个答案。 基于我在互联网上找到的方法参考的逻辑(https://gist.github.com/vendettamit/5a1a71eba84c741b397a#file-referencefinder-cs) 我只是在尝试一些东西:

...
foreach (var project in solution.Projects)
{
    foreach (var document in project.Documents)
    {
        var model = await document.GetSemanticModelAsync();

        var methodInvocation = await document.GetSyntaxRootAsync();
        ClassDeclarationSyntax? node = null;
        try
        {
            var classesInFile = methodInvocation.DescendantNodes().OfType<ClassDeclarationSyntax>();
            node = classesInFile
             .Where(x => x.Identifier.Text == myClassname).FirstOrDefault();

            if (node == null)
                continue;
        }
        catch (Exception exception)
        {
            // Swallow the exception of type cast. 
            // Could be avoided by a better filtering on above linq.
            continue;
        }



        var symbolInfo = model.GetDeclaredSymbol(node);
        methodSymbol = symbolInfo;
        found = true;
        break;
    }
    if (found) break;
}

最后我不得不使用

 var symbolInfo = model.GetDeclaredSymbol(node);

而不是

model.GetSymbolInfo(node).Symbol;
© www.soinside.com 2019 - 2024. All rights reserved.