当前位置:  开发笔记 > 编程语言 > 正文

SymbolFinder.FindReferencesAsync找不到任何内容

如何解决《SymbolFinder.FindReferencesAsync找不到任何内容》经验,为你挑选了1个好方法。

我想PropertyChangedEventHandler在我的解决方案中找到所有事件,然后找到添加到这些事件的所有侦听器.但我似乎无法获得事件列表.

这是正在分析的解决方案中的所有代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RoslynTarget
{
    public class Example : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public void DoNothing() { }
    }
}

这是我分析它的代码.references.Count == 1而且r.Locations.Count == 0,应该找到一个位置.这里发生了什么?

Program.cs中

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.MSBuild;

namespace RoslynTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const string solutionPath = @"C:\Users\\Code\RoslynTarget\RoslynTarget.sln";
            const string projectName = "RoslynTarget";

            var msWorkspace = MSBuildWorkspace.Create(new Dictionary { { "CheckForSystemRuntimeDependency", "true" } });
            var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;

            var project =
                solution.Projects
                    .Where(proj => proj.Name == projectName)
                    .First();

            var compilation = project.GetCompilationAsync().Result;
            var eventType = compilation.ResolveType("System.ComponentModel.PropertyChangedEventHandler").First();
            var references = SymbolFinder.FindReferencesAsync(eventType, solution).Result;

            foreach (var r in references)
            {
                foreach (var loc in r.Locations)
                {
                    // ...
                }
            }
        }
    }
}

Extensions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

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

vendettamit.. 5

最近我做了类似的事情,我试图在完整的解决方案中找到方法的参考.要使用FindReferenceAsync您首先创建语义模型并从那里找到符号.一旦你有了符号,你就可以使用FindReferenceAsync.

这是我使用的片段,它正在工作:

var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
foreach (var project in solution.Projects)
{
    foreach (var document in project.Documents)
    {
        var model = document.GetSemanticModelAsync().Result;

        var methodInvocation = document.GetSyntaxRootAsync().Result;
        InvocationExpressionSyntax node = null;
        try
        {
            node = methodInvocation.DescendantNodes().OfType()
             .Where(x => ((MemberAccessExpressionSyntax)x.Expression).Name.ToString() == methodName).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;
        }

        methodSymbol = model.GetSymbolInfo(node).Symbol;
        found = true;
        break;
    }

    if (found) break;
}

foreach (var item in SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result)
{
    foreach (var location in item.Locations)
    {
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("Project Assembly -> {0}", location.Document.Project.AssemblyName);
        Console.ResetColor();
    }

}

这是完整的工作代码.如果您想要可视化Roslyn树,那么您可以尝试使用Roslyn树可视化工具来查看代码结构.

更新

根据OP安装Roslyn SDK的评论中的讨论修复了该问题.假设在使用时,与Nuget dll相比,SDK中可能会有一些更新来生成符号信息GetCompilationAsync.



1> vendettamit..:

最近我做了类似的事情,我试图在完整的解决方案中找到方法的参考.要使用FindReferenceAsync您首先创建语义模型并从那里找到符号.一旦你有了符号,你就可以使用FindReferenceAsync.

这是我使用的片段,它正在工作:

var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
foreach (var project in solution.Projects)
{
    foreach (var document in project.Documents)
    {
        var model = document.GetSemanticModelAsync().Result;

        var methodInvocation = document.GetSyntaxRootAsync().Result;
        InvocationExpressionSyntax node = null;
        try
        {
            node = methodInvocation.DescendantNodes().OfType()
             .Where(x => ((MemberAccessExpressionSyntax)x.Expression).Name.ToString() == methodName).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;
        }

        methodSymbol = model.GetSymbolInfo(node).Symbol;
        found = true;
        break;
    }

    if (found) break;
}

foreach (var item in SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result)
{
    foreach (var location in item.Locations)
    {
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("Project Assembly -> {0}", location.Document.Project.AssemblyName);
        Console.ResetColor();
    }

}

这是完整的工作代码.如果您想要可视化Roslyn树,那么您可以尝试使用Roslyn树可视化工具来查看代码结构.

更新

根据OP安装Roslyn SDK的评论中的讨论修复了该问题.假设在使用时,与Nuget dll相比,SDK中可能会有一些更新来生成符号信息GetCompilationAsync.

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有