Создание хорошо отформатированного синтаксиса с 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.