Форматирование кода в Roslyn SDK Preview
В более ранней версии (Roslyn CTP) я использовал следующий код для форматирования сгенерированного кода, и он работал отлично:
SyntaxNode.Format(FormattingOptions.GetDefaultOptions()).GetFormattedRoot()
С новой версией Roslyn это больше не делает, так каков эквивалент вышеупомянутого кода в новой версии (SDK Preview)?
3 ответа
Вы можете отформатировать SyntaxNodes
с использованием Microsoft.CodeAnalysis.Formatting.Formatter
вот так (если у вас есть рабочее пространство):
using Microsoft.CodeAnalysis.Formatting;
var formattedResult = Formatter.Format(syntaxNode, workspace);
РЕДАКТИРОВАТЬ: Как писал Jeroen в комментарии, если у вас нет рабочего пространства и вам не нужны параметры форматирования, специфичные для рабочего пространства, вы можете просто создать его:
var workspace = MSBuildWorkspace.Create();
Рослин довольно сильно изменилась со времен ОСАГО.
Документация теперь здесь: https://roslyn.codeplex.com/
Перейдите по ссылке https://roslyn.codeplex.com/documentation, нажмите "Образцы и пошаговые руководства", затем откройте демонстрационное решение "FormatSolution - консольное приложение, которое форматирует все исходные файлы C# и VB в решении".
К сожалению, я не думаю, что возможно быстро начать работать с форматированием, так как вам нужно добавить код в новое решение.
Я думаю, это сработает для вас.
var syntaxTree = CSharpSyntaxTree.ParseText(finalProgramText);
var compilationRoot = syntaxTree.GetCompilationUnitRoot();
/*
MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();
var sharpTree = CSharpSyntaxTree.ParseText(programText);
var formattedNode = Formatter.Format(sharpTree.GetRoot(), workspace);
var fullText = formattedNode.ToFullString();
*/
var nameSpaces = from n in compilationRoot.DescendantNodes().OfType<UsingDirectiveSyntax>() select n;
var usings = compilationRoot.Usings.AddRange(nameSpaces);
var propertyNodes = (from field in compilationRoot.DescendantNodes().OfType<PropertyDeclarationSyntax>() select field).ToList();
var st = new SyntaxTrivia();
var withoutProperty = compilationRoot.ReplaceNodes(propertyNodes, (syntax, declarationSyntax) => null).NormalizeWhitespace();
var withoutPropText = withoutProperty.GetText().ToString();
var tree = CSharpSyntaxTree.ParseText(withoutPropText);
var root = tree.GetCompilationUnitRoot();
var commentTrivia = from t in root.DescendantTrivia()
where t.IsKind(SyntaxKind.SingleLineCommentTrivia)
|| t.IsKind(SyntaxKind.MultiLineCommentTrivia)
|| t.IsKind(SyntaxKind.EndRegionDirectiveTrivia)
|| t.IsKind(SyntaxKind.RegionDirectiveTrivia)
|| t.IsKind(SyntaxKind.PragmaChecksumDirectiveTrivia)
|| t.IsKind(SyntaxKind.PragmaWarningDirectiveTrivia)
|| t.IsKind(SyntaxKind.PragmaKeyword)
|| t.IsKind(SyntaxKind.EmptyStatement)
|| t.IsKind(SyntaxKind.XmlComment)
|| t.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)
|| t.IsKind(SyntaxKind.AttributeList)
select t;
var newRoot = root.ReplaceTrivia(commentTrivia, (t1, t2) => st).NormalizeWhitespace();
var text = newRoot.GetText().ToString();
var attrTree = CSharpSyntaxTree.ParseText(text);
var attrRoot = attrTree.GetCompilationUnitRoot();
var attrList = from a in attrRoot.DescendantNodes().OfType<AttributeListSyntax>() select a;
var methodList = (from m in attrRoot.DescendantNodes().OfType<MethodDeclarationSyntax>()
where m.ExpressionBody != null
select m).ToList();
var normalMethods = (from m in attrRoot.DescendantNodes().OfType<MethodDeclarationSyntax>()
where m.ExpressionBody == null
select m).ToList();
Console.WriteLine(normalMethods.Count);
var withoutAttrList = attrRoot.ReplaceNodes(attrList, (syntax, listSyntax) => null).NormalizeWhitespace()
.GetText().ToString();
var fieldTree = CSharpSyntaxTree.ParseText(withoutAttrList);
var fieldRoot = fieldTree.GetCompilationUnitRoot();
var fieldsList = (from field in fieldRoot.DescendantNodes().OfType<FieldDeclarationSyntax>() select field).ToList();
var withoutFields = fieldRoot.ReplaceNodes(fieldsList, (syntax, declarationSyntax) => null);
var plainTextLines = withoutFields.NormalizeWhitespace().GetText().ToString().Split('\n')
.Where(d => !usings.Any(u => d.Trim('\r', ' ').Equals(u.ToString())) && !string.IsNullOrEmpty(d.Trim('\r', ' '))
&& !Regex.IsMatch(d.Trim('\r', ' '), @"^([;()\[\]]+)$")
).Select(s => Regex.Replace(s.TrimEnd('\r', '\n', ' '), "\\s+", " ")).ToList();
Console.WriteLine(plainTextLines);