使用Roslyn查找对方法的所有引用

时间:2015-08-06 17:06:48

标签: c# code-analysis roslyn findall

我希望扫描一组.cs文件以查看哪些文件调用Value的{​​{1}}属性(查找所有引用)。例如,这将匹配:

Nullable<T>

我发现了Roslyn并查看了一些样本,但其中许多都已过时且API非常庞大。我该怎么做呢?

解析语法树后我被困了。这就是我到目前为止所做的:

class Program
{
    static void Main()
    {
        int? nullable = 123;
        int value = nullable.Value;
    }
}

2 个答案:

答案 0 :(得分:42)

您可能正在寻找SymbolFinder课程,特别是FindAllReferences方法。

听起来你在熟悉Roslyn时遇到了一些麻烦。我有一系列的博客文章,以帮助人们介绍罗斯林,名为Learn Roslyn Now

正如@SLaks所提到的,你需要访问我在Part 7: Introduction to the Semantic Model

中涵盖的语义模型

这是一个示例,向您展示如何使用API​​。如果你能够,我会使用MSBuildWorkspace并从磁盘加载项目,而不是像AdHocWorkspace那样创建项目。

var mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var ws = new AdhocWorkspace();
//Create new solution
var solId = SolutionId.CreateNewId();
var solutionInfo = SolutionInfo.Create(solId, VersionStamp.Create());
//Create new project
var project = ws.AddProject("Sample", "C#");
project = project.AddMetadataReference(mscorlib);
//Add project to workspace
ws.TryApplyChanges(project.Solution);
string text = @"
class C
{
    void M()
    {
        M();
        M();
    }
}";
var sourceText = SourceText.From(text);
//Create new document
var doc = ws.AddDocument(project.Id, "NewDoc", sourceText);
//Get the semantic model
var model = doc.GetSemanticModelAsync().Result;
//Get the syntax node for the first invocation to M()
var methodInvocation = doc.GetSyntaxRootAsync().Result.DescendantNodes().OfType<InvocationExpressionSyntax>().First();
var methodSymbol = model.GetSymbolInfo(methodInvocation).Symbol;
//Finds all references to M()
var referencesToM = SymbolFinder.FindReferencesAsync(methodSymbol,  doc.Project.Solution).Result;

答案 1 :(得分:0)

关于问题和最终修复的杂志,我让罗斯林使用VS2017:

挂接到MSBuildWorkspace WorkspaceFailed事件时,可见VS2017项目为空的原因。

第一轮失败是:

MSB0001:内部MSBuild错误:Microsoft.Build.Utilities.ToolLocationHelper的类型信息以Microsoft.Build.Utilities.ToolLocationHelper,Microsoft.Build.Utilities.Core,Version = 15.1.0.0,Culture =中性,PublicKeyToken = b03f5f7f11d50a3a,但无法加载类型。意外为空])

此问题已通过安装NuGet软件包Microsoft.Build.Locator 1.1.2和Microsoft.Build.Utilities.Core 15.9.20

得以解决。

第二轮失败是:

在处理带有消息的文件“ C:\ Users ... vbproj”时,Msbuild失败: C:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ Microsoft.Common.CurrentVersion.targets:(1491,5): 无法从程序集Microsoft.Build.Tasks.Core,版本= 15.1.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a中加载“ Microsoft.Build.Tasks.AssignProjectConfiguration”任务。 无法加载文件或程序集“ Microsoft.Build.Tasks.Core,版本= 15.1.0.0,文化=中性,PublicKeyToken = b03f5f7f11d50a3a”或其依赖项之一。 该系统找不到指定的文件。确认声明正确无误,并保证程序集及其所有依赖项都可用,并且任务包含实现Microsoft.Build.Framework.ITask的公共类。]

此问题已通过添加NuGet Microsoft.Build.Tasks.Core 15.9.20

修复。

第三轮失败是: ===处理带有消息的文件“ C:\ Users ... vbproj”时,Msbuild失败: C:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ Microsoft.Common.CurrentVersion.targets:(1657,5): 无法从程序集中实例化“ GetReferenceNearestTargetFrameworkTask”任务 “ C:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ Enterprise \ Common7 \ IDE \ CommonExtensions \ Microsoft \ NuGet \ NuGet.Build.Tasks.dll”。 请验证该任务程序集是使用与计算机上安装的版本相同的Microsoft.Build.Framework程序集构建的。 并且您的主机应用程序没有缺少Microsoft.Build.Framework的绑定重定向。 无法将类型为“ NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask”的对象转换为类型为“ Microsoft.Build.Framework.ITask”的对象。])

请注意,该项目的Microsoft.Build.Framework.dll = 15.1.0.0,但消息中提到“ MSBuild \ 15.0 \ Bin”

添加到app.config-已修复! cf enter link description here现在,我可以从VS2017解决方案中加载项目了

  <!-- vvv Roslyn manual fixup https://github.com/Microsoft/msbuild/issues/2369 -->
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build.Utilities.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build.Tasks.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>
  <!-- ^^^ Roslyn manual fixup https://github.com/Microsoft/msbuild/issues/2369 -->