Подтвердить что ты не робот

Поиск всех ссылок на метод с Roslyn

Я ищу сканирование группы файлов .cs, чтобы узнать, какие из них называют Value свойством Nullable<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? */
}
4b9b3361

Ответ 1

Вероятно, вы ищете класс SymbolFinder и, в частности, метод FindAllReferences.

Похоже, у вас проблемы с знакомством с Рослином. У меня есть серия сообщений в блогах, чтобы помочь людям познакомиться с Roslyn под названием Узнать Roslyn Now.

Поскольку @SLaks упоминает, что вам понадобится доступ к семантической модели, которую я расскажу в Часть 7: Введение в семантическую модель

Вот пример, который показывает вам, как использовать 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;

Ответ 2

Журнал проблем и возможных исправлений, я заставил Рослин работать с VS2017:

Причина пустых проектов VS2017 становится очевидной, когда подключено событие MSBuildWorkspace WorkspaceFailed.

Первый раунд неудач был:

MSB0001: Внутренняя ошибка MSBuild: сведения о типе для Microsoft.Build.Utilities.ToolLocationHelper присутствовали в кэше белого списка как Microsoft.Build.Utilities.ToolLocationHelper, Microsoft.Build.Utilities.Core, Версия = 15.1.0.0, Culture = нейтральный, PublicKeyToken = b03f5f7f11d50a3a, но тип не может быть загружен. неожиданно ноль])

Это было исправлено путем установки пакетов NuGet Microsoft.Build.Locator 1.1.2 и Microsoft.Build.Utilities.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: (1491, 5): не удалось загрузить задачу "Microsoft.Build.Tasks.AssignProjectConfiguration" из сборки Microsoft.Build.Tasks.Core, версия = 15.1.0.0, культура = нейтральная, PublicKeyToken = b03f5f7f11d50a3a. Не удалось загрузить файл или сборку "Microsoft.Build.Tasks.Core, версия = 15.1.0.0, Culture = нейтральный, PublicKeyToken = b03f5f7f11d50a3a" или одну из ее зависимостей. Система не может найти указанный файл. Убедитесь, что объявление правильное, что сборка и все ее зависимости доступны и что задача содержит открытый класс, реализующий Microsoft.Build.Framework.ITask.])

Это было исправлено добавлением 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): не удалось создать задачу "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 введите описание ссылки здесь. Теперь я могу загружать проекты из решений 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 -->