我想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 IEnumerableResolveType(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
.
最近我做了类似的事情,我试图在完整的解决方案中找到方法的参考.要使用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
.