1

感谢Roslyn可以访问 .Net 编译器,在我们的项目Gcop 中,我们需要有调用方法的引用列表。

VS IDE 显示了非常适合的参考位置,如下所示:

在此处输入图像描述

实际上,我想了解哪个类/名称空间甚至程序集正在通过Roslyn C# 语法调用我的方法。

目前我可以在这里访问 MethodSymbol :

var methodSymbol = semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

我应该写什么来访问这个方法的引用?

//最近添加以进行双重检查

 var solutionPath = Utilities.DteExtensions.SolutionFullPath;
 var msWorkspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
 var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result; 

 var result = new List<ReferenceLocation>();
 var refrences = SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result;    

 foreach (var refernc in refrences)
  {
    foreach (var location in refernc.Locations)
     {
         result.Add(location);
     }
  }
///???????? why the result is empty ? 
4

3 回答 3

2

您正在寻找classFindReferencesAsync()上的方法。SymbolFinder

于 2016-02-16T16:47:01.390 回答
0

我更喜欢更改以下内容以使其工作:

 var nodes = methodInvocation.DescendantNodes().OfType<InvocationExpressionSyntax>()
   .Where(x => x.Expression.ToString().Contains(methodName));

至:

var nodes = new List<InvocationExpressionSyntax>();
foreach (var methodInvocationExpression in methodInvocation.DescendantNodes().OfType<InvocationExpressionSyntax>())
{
    if(methodInvocationExpression.DescendantNodes().OfType<MemberAccessExpressionSyntax>().Any(x => x.Name.Identifier.ValueText == methodName))
    {
        nodes.Add(methodInvocationExpression);
    }
}
于 2022-02-08T14:53:21.100 回答
0

我测试了这种方法,但速度不快,并且找不到一些语法

 protected override void Analyze(SyntaxNodeAnalysisContext context)
    {
        NodeToAnalyze = context.Node;
        Method = context.Node as MethodDeclarationSyntax;

        // only public method should be checked
        if (!IsModifiersValid) return;

        var methodSymbol = context.SemanticModel.GetDeclaredSymbol(Method) as IMethodSymbol;

        var solutionPath = Utilities.DteExtensions.SolutionFullPath;
        var msWorkspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
        var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;

        // looking in all projects inside of one solution
        var allDocumentsInEntireSolution = solution.Projects.SelectMany(it => it.Documents);

        //skip rule when in entire solution we have web form project             
        if (allDocumentsInEntireSolution.Any(x => x.Name == "Default.aspx.cs")) return;

        //Looking for all references            

        var refrencesFound = FindAllMethodReferences(Method.GetName(), solution);

        if (refrencesFound.Count() ==0)
            ReportDiagnostic(context, Method);
        else
        {
            var xyx = refrencesFound.Count();
        }

    }

    IEnumerable<ReferenceLocation> FindAllMethodReferences(string methodName, Solution solution)
    {
        IMethodSymbol methodSymbol = null;


        bool found = false;

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

                var methodInvocation = document.GetSyntaxRootAsync().Result;

                try
                {
                    var nodes = methodInvocation.DescendantNodes().OfType<InvocationExpressionSyntax>().Where(x => x.Expression.ToString().Contains(methodName));
                    foreach (var node in nodes)
                    {
                        if (node == null) continue;

                        var member = node?.Expression as MemberAccessExpressionSyntax;
                        if (member == null)
                            continue;

                        var name = member?.Name?.ToString();
                        if (name.IsEmpty()) continue;
                        if (name != methodName) continue;

                        methodSymbol = model.GetSymbolInfo(node).Symbol as IMethodSymbol;
                        found = true;
                        break;
                    }
                }
                catch (Exception exp)
                {
                    // Swallow the exception of type cast. 
                    // Could be avoided by a better filtering on above linq.
                    continue;
                }
            }

            if (found) break;
        }

        if (found == false) return Enumerable.Empty<ReferenceLocation>();
        if (methodSymbol == null) return Enumerable.Empty<ReferenceLocation>();

        var result = new List<ReferenceLocation>();
        var refrences = SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result;

        foreach (var refernc in refrences)
        {
            foreach (var location in refernc.Locations)
            {
                result.Add(location);
            }
        }
        return result;
    }
于 2016-05-04T16:14:42.727 回答