Skip to content
This repository was archived by the owner on Jul 12, 2022. It is now read-only.

Commit d1dc15e

Browse files
author
Lakshmi Priya Sekar
committed
Improve formatting of preprocessor regions
This uses a different way to format code in #if false, that is, by enabling and disabling preprocessor names.
1 parent cb69e25 commit d1dc15e

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

src/Microsoft.DotNet.CodeFormatting/Rules/IsFormattedFormattingRule.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.CodeAnalysis.Formatting;
1010
using Microsoft.CodeAnalysis.CSharp;
1111
using System.Linq;
12+
using Microsoft.CodeAnalysis.CSharp.Syntax;
1213

1314
namespace Microsoft.DotNet.CodeFormatting.Rules
1415
{
@@ -17,20 +18,21 @@ internal sealed class IsFormattedFormattingRule : IFormattingRule
1718
{
1819
public async Task<Document> ProcessAsync(Document document, CancellationToken cancellationToken)
1920
{
21+
var newDocument = await Formatter.FormatAsync(document, cancellationToken: cancellationToken);
2022
// Roslyn formatter doesn't format code in #if false as it's considered as DisabledTextTrivia. Will be removed after the bug is fixed.
2123
// Doing that manually here
22-
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken) as CSharpSyntaxNode;
23-
var oldTrivia = syntaxRoot.DescendantTrivia().Where(trivia => trivia.CSharpKind() == SyntaxKind.DisabledTextTrivia);
24-
Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia> replacementTrivia = (trivia, dummy) =>
25-
{
26-
var levelToIndent = trivia.Token.Parent.Ancestors().Count();
27-
var compilation = SyntaxFactory.ParseCompilationUnit(trivia.ToString());
28-
var formattedTrivia = Formatter.Format(compilation.SyntaxTree.GetRoot(), document.Project.Solution.Workspace).GetText().ToString();
29-
return SyntaxFactory.DisabledText(formattedTrivia);
30-
};
24+
var syntaxRoot = await newDocument.GetSyntaxRootAsync(cancellationToken) as CSharpSyntaxNode;
25+
var preprocessorNamesDefined = newDocument.Project.ParseOptions.PreprocessorSymbolNames;
26+
var preprocessorNamesToAdd = syntaxRoot.DescendantTrivia().Where(trivia => trivia.CSharpKind() == SyntaxKind.IfDirectiveTrivia)
27+
.SelectMany(trivia => trivia.GetStructure().DescendantNodes().OfType<IdentifierNameSyntax>())
28+
.Select(identifier => identifier.Identifier.Text).Distinct().Where((name) => !preprocessorNamesDefined.Contains(name));
29+
30+
var newParseOptions = new CSharpParseOptions().WithPreprocessorSymbols(preprocessorNamesToAdd);
3131

32-
var newDocument = document.WithSyntaxRoot(syntaxRoot.ReplaceTrivia(oldTrivia, replacementTrivia));
33-
return await Formatter.FormatAsync(newDocument, cancellationToken: cancellationToken);
32+
var documentToProcess = newDocument.Project.WithParseOptions(newParseOptions).GetDocument(newDocument.Id);
33+
documentToProcess = await Formatter.FormatAsync(documentToProcess, cancellationToken: cancellationToken);
34+
35+
return documentToProcess.Project.WithParseOptions(new CSharpParseOptions().WithPreprocessorSymbols(preprocessorNamesDefined)).GetDocument(documentToProcess.Id);
3436
}
3537
}
3638
}

0 commit comments

Comments
 (0)