| 1 | using Microsoft.CodeAnalysis; |
| 2 | using Microsoft.CodeAnalysis.Formatting; |
| 3 | using Microsoft.CodeAnalysis.Host; |
| 4 | using Microsoft.CodeAnalysis.Text; |
| 5 | |
| 6 | namespace CascadeIDE.Services; |
| 7 | |
| 8 | public sealed partial class CSharpLanguageService |
| 9 | { |
| 10 | /// <summary>Format entire document (Roslyn in-proc, ADR 0148).</summary> |
| 11 | public string FormatDocument(string filePath, string sourceText, CancellationToken ct = default) |
| 12 | { |
| 13 | if (string.IsNullOrEmpty(filePath)) |
| 14 | return sourceText; |
| 15 | |
| 16 | try |
| 17 | { |
| 18 | var text = SourceText.From(sourceText); |
| 19 | var (compilation, tree) = GetOrCreateCompilationAndTree(filePath, text, ct); |
| 20 | var root = tree.GetRoot(ct); |
| 21 | |
| 22 | using var workspace = new AdhocWorkspace(); |
| 23 | var projectId = ProjectId.CreateNewId(); |
| 24 | var documentId = DocumentId.CreateNewId(projectId); |
| 25 | var projectInfo = ProjectInfo.Create( |
| 26 | projectId, |
| 27 | VersionStamp.Create(), |
| 28 | "FormatTemp", |
| 29 | "FormatTemp", |
| 30 | LanguageNames.CSharp, |
| 31 | metadataReferences: compilation.References); |
| 32 | workspace.AddProject(projectInfo); |
| 33 | workspace.AddDocument(DocumentInfo.Create( |
| 34 | documentId, |
| 35 | Path.GetFileName(filePath), |
| 36 | loader: TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())), |
| 37 | filePath: filePath)); |
| 38 | |
| 39 | var formatted = Formatter.Format(root, workspace, cancellationToken: ct); |
| 40 | return formatted.ToFullString(); |
| 41 | } |
| 42 | catch |
| 43 | { |
| 44 | return sourceText; |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | |