roslynАнализ исходного кода с Roslyn

Интроспективный анализ анализатора в C #

  1. Создание нового консольного приложения
  2. Добавить пакет NuGet Microsoft.CodeAnalysis
  3. Импортируйте пространства имен Microsoft.CodeAnalysis.MSBuild , System.Linq и Microsoft.CodeAnalysis.CSharp.Syntax
  4. Напишите следующий пример кода в методе Main :
// Declaring a variable with the current project file path.
const string projectPath = @"C:\<your path to the project\<project file name>.csproj";

// Creating a build workspace.
var workspace = MSBuildWorkspace.Create();
        
// Opening this project.
var project = workspace.OpenProjectAsync(projectPath).Result;

// Getting the compilation.
var compilation = project.GetCompilationAsync().Result;

// As this is a simple single file program, the first syntax tree will be the current file.
var syntaxTree = compilation.SyntaxTrees.First();

// Getting the root node of the file.
var rootSyntaxNode = syntaxTree.GetRootAsync().Result;

// Finding all the local variable declarations in this file and picking the first one.
var firstLocalVariablesDeclaration = rootSyntaxNode.DescendantNodesAndSelf().OfType<LocalDeclarationStatementSyntax>().First();

// Getting the first declared variable in the declaration syntax.
var firstVariable = firstLocalVariablesDeclaration.Declaration.Variables.First();

// Getting the text of the initialized value.
var variableInitializer = firstVariable.Initializer.Value.GetFirstToken().ValueText;

// This will print to screen the value assigned to the projectPath variable.
Console.WriteLine(variableInitializer);

Console.ReadKey();

При запуске проекта вы увидите переменную, объявленную сверху, напечатанную на экране. Это означает, что вы успешно проанализировали проект и нашли в нем переменную.

Проанализируйте простое приложение «Hello World» в C #

Создайте новое консольное приложение с одной строкой в ​​методе Main : Console.WriteLine("Hello World")

Запомните путь к файлу .csproj и замените его в примере.

Создайте новое консольное приложение и установите пакет Microsoft.CodeAnalysis NuGet и попробуйте следующий код:

const string projectPath = @"C:\HelloWorldApplication\HelloWorldProject.csproj";

// Creating a build workspace.
var workspace = MSBuildWorkspace.Create();
        
// Opening the Hello World project.
var project = workspace.OpenProjectAsync(projectPath).Result;

// Getting the compilation.
var compilation = project.GetCompilationAsync().Result;

foreach (var tree in compilation.SyntaxTrees)
{
    Console.WriteLine(tree.FilePath);

    var rootSyntaxNode = tree.GetRootAsync().Result;

    foreach (var node in rootSyntaxNode.DescendantNodes())
    {
        Console.WriteLine($" *** {node.Kind()}");
        Console.WriteLine($"     {node}");
    }
}

Console.ReadKey();

Это напечатает все файлы и все узлы синтаксиса в проекте Hello World .

Анализ простого приложения Hello World в VB.NET

Создайте новое консольное приложение с одной строкой в ​​методе Main : Console.WriteLine("Hello World")

Запомните путь к файлу .vbproj и замените его в примере.

Создайте новое консольное приложение и установите пакет Microsoft.CodeAnalysis NuGet и попробуйте следующий код:

Const projectPath = "C:\HelloWorldApplication\HelloWorldProject.vbproj"

' Creating a build workspace.
Dim workspace = MSBuildWorkspace.Create()

' Opening the Hello World project.
Dim project = workspace.OpenProjectAsync(projectPath).Result

' Getting the compilation.
Dim compilation = project.GetCompilationAsync().Result

For Each tree In compilation.SyntaxTrees

    Console.WriteLine(tree.FilePath)

    Dim rootSyntaxNode = tree.GetRootAsync().Result

    For Each node In rootSyntaxNode.DescendantNodes()

        Console.WriteLine($" *** {node.Kind()}")
        Console.WriteLine($"     {node}")
    Next
Next

Console.ReadKey()

Это напечатает все файлы и все узлы синтаксиса в проекте Hello World .

Исправить исходный код из текста в C #

var syntaxTree = CSharpSyntaxTree.ParseText(
@"using System;
using System.Collections;
using System.Linq;
using System.Text;

namespace HelloWorldApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello World"");
}
}
}");

var root = syntaxTree.GetRoot() as CompilationUnitSyntax;

var namespaceSyntax = root.Members.OfType<NamespaceDeclarationSyntax>().First();
        
var programClassSyntax = namespaceSyntax.Members.OfType<ClassDeclarationSyntax>().First();

var mainMethodSyntax = programClassSyntax.Members.OfType<MethodDeclarationSyntax>().First();

Console.WriteLine(mainMethodSyntax.ToString());

Console.ReadKey();

В этом примере будет напечатан Main метод из текста, анализирующего синтаксис.

Получить тип 'var'

Чтобы получить фактический тип переменной, объявленной с помощью var , вызовите GetSymbolInfo() в SemanticModel . Вы можете открыть существующее решение с помощью MSBuildWorkspace , затем перечислить его проекты и их документы. Используйте документ для получения SyntaxRoot и SemanticModel , затем найдите VariableDeclarations и SyntaxRoot символы для Type объявленной переменной следующим образом:

var workspace = MSBuildWorkspace.Create();
var solution = workspace.OpenSolutionAsync("c:\\path\\to\\solution.sln").Result;

foreach (var document in solution.Projects.SelectMany(project => project.Documents))
{
    var rootNode = document.GetSyntaxRootAsync().Result;
    var semanticModel = document.GetSemanticModelAsync().Result;

    var variableDeclarations = rootNode
            .DescendantNodes()
            .OfType<LocalDeclarationStatementSyntax>();
    foreach (var varDeclaration in variableDeclarations)
    {
        var symbolInfo = semanticModel.GetSymbolInfo(varDeclaration.Declaration.Type);
        var typeSymbol = symbolInfo.Symbol; // the type symbol for the variable..
    }
}