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

问题描述 投票:18回答:2

我正在寻找扫描一组.cs文件,看看哪些调用ValueNullable<T>属性(查找所有引用)。例如,这将匹配:

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

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

解析语法树后我陷入困境。这是我到目前为止:

public static void Analyze(string sourceCode)
{
    var tree = CSharpSyntaxTree.ParseText(sourceCode);

    tree./* ??? What goes here? */
}
c# code-analysis roslyn findall
2个回答
43
投票

你可能正在寻找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;

0
投票

关于问题和最终修复的期刊,我让Roslyn与VS2017合作:

当MSBuildWorkspace WorkspaceFailed事件被挂钩时,空VS2017项目的原因变得可见。

第一轮失败是:

MSB0001:内部MSBuild错误:Microsoft.Build.Uoolities的类型信息.ToolLocationHelper在白名单缓存中显示为Microsoft.Build.Utilities.ToolLocationHelper,Microsoft.Build.Utilities.Core,Version = 15.1.0.0,Culture = neutral,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,Version = 15.1.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a加载“Microsoft.Build.Tasks.AssignProjectConfiguration”任务。无法加载文件或程序集'Microsoft.Build.Tasks.Core,Version = 15.1.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'或其依赖项之一。该系统找不到指定的文件。确认声明是否正确,程序集及其所有依赖项是否可用,以及该任务是否包含实现Microsoft.Build.Framework.ITask的公共类。])

This was fixed by adding NuGet Microsoft.Build.Tasks.Core 15.9.20

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

Note that the project's Microsoft.Build.Framework.dll = 15.1.0.0 but the message mentions "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 -->
© www.soinside.com 2019 - 2024. All rights reserved.