Создание хорошо отформатированного синтаксиса с Roslyn

Я использую Roslyn для изменения синтаксиса файлов C#. Используя CSharpSyntaxRewriter, очень легко найти и заменить узлы в дереве синтаксиса. Однако сгенерированный код очень уродлив и даже не будет анализироваться во всех случаях, потому что синтаксическим узлам, которые я создаю (используя SyntaxFactory), не хватает даже минимального количества пустых пробелов. Предоставляет ли Roslyn некоторые базовые функции форматирования, чтобы избежать этого, или мне нужно вручную добавлять мелочи для каждого создаваемого мной узла?

3 ответа

Да, это возможно с помощью Microsoft.CodeAnalysis.Formatting.Formatter

var formattedResult = Formatter.Format(syntaxNode, workspace);

Вы можете увидеть использование различных форматеров Roslyn здесь, в исходном коде Roslyn:http://sourceroslyn.io/#Microsoft.CodeAnalysis.Workspaces/CodeActions/CodeAction.cs,267

internal static async Task<Document> CleanupDocumentAsync(
        Document document, CancellationToken cancellationToken)
{
    if (document.SupportsSyntaxTree)
    {
        document = await ImportAdder.AddImportsFromSymbolAnnotationAsync(
        document, Simplifier.AddImportsAnnotation, cancellationToken: cancellationToken).ConfigureAwait(false);

        document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);

        // format any node with explicit formatter annotation
        document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);

        // format any elastic whitespace
        document = await Formatter.FormatAsync(document, SyntaxAnnotation.ElasticAnnotation, cancellationToken: cancellationToken).ConfigureAwait(false);

        document = await CaseCorrector.CaseCorrectAsync(document, CaseCorrector.Annotation, cancellationToken).ConfigureAwait(false);
     }

     return document;
}

Если у вас нет «рабочей области», вы можете использовать это:

      public static string FormatCode(string code, CancellationToken cancelToken = default)
{
    return CSharpSyntaxTree.ParseText(code, cancellationToken: cancelToken)
        .GetRoot(cancelToken)
        .NormalizeWhitespace()
        .SyntaxTree
        .GetText(cancelToken)
        .ToString();
}

Если компилятор не может найтиCSharpSyntaxTree, добавьте пакет Microsoft.CodeAnalysis.CSharp NuGet.

Другие вопросы по тегам