Separate html formatting passes, so we can remove the IsFormatOnType flag

This commit is contained in:
David Wengier 2024-08-22 15:12:12 +10:00
Родитель 6f1c6ef398
Коммит f74150db38
8 изменённых файлов: 89 добавлений и 121 удалений

Просмотреть файл

@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -27,16 +26,6 @@ internal sealed class CSharpFormatter(IDocumentMappingService documentMappingSer
public async Task<TextEdit[]> FormatAsync(FormattingContext context, Range rangeToFormat, CancellationToken cancellationToken)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (rangeToFormat is null)
{
throw new ArgumentNullException(nameof(rangeToFormat));
}
if (!_documentMappingService.TryMapToGeneratedDocumentRange(context.CodeDocument.GetCSharpDocument(), rangeToFormat, out var projectedRange))
{
return [];
@ -52,16 +41,6 @@ internal sealed class CSharpFormatter(IDocumentMappingService documentMappingSer
IReadOnlyCollection<int> projectedDocumentLocations,
CancellationToken cancellationToken)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (projectedDocumentLocations is null)
{
throw new ArgumentNullException(nameof(projectedDocumentLocations));
}
// Sorting ensures we count the marker offsets correctly.
// We also want to ensure there are no duplicates to avoid duplicate markers.
var filteredLocations = projectedDocumentLocations.Distinct().OrderBy(l => l).ToList();

Просмотреть файл

@ -29,14 +29,13 @@ internal sealed class FormattingContext : IDisposable
private IReadOnlyDictionary<int, IndentationContext>? _indentations;
private FormattingContext(IAdhocWorkspaceFactory workspaceFactory, Uri uri, IDocumentSnapshot originalSnapshot, RazorCodeDocument codeDocument, RazorFormattingOptions options,
bool isFormatOnType, bool automaticallyAddUsings, int hostDocumentIndex, char triggerCharacter)
bool automaticallyAddUsings, int hostDocumentIndex, char triggerCharacter)
{
_workspaceFactory = workspaceFactory;
Uri = uri;
OriginalSnapshot = originalSnapshot;
CodeDocument = codeDocument;
Options = options;
IsFormatOnType = isFormatOnType;
AutomaticallyAddUsings = automaticallyAddUsings;
HostDocumentIndex = hostDocumentIndex;
TriggerCharacter = triggerCharacter;
@ -48,7 +47,6 @@ internal sealed class FormattingContext : IDisposable
public IDocumentSnapshot OriginalSnapshot { get; }
public RazorCodeDocument CodeDocument { get; }
public RazorFormattingOptions Options { get; }
public bool IsFormatOnType { get; }
public bool AutomaticallyAddUsings { get; }
public int HostDocumentIndex { get; }
public char TriggerCharacter { get; }
@ -267,7 +265,6 @@ internal sealed class FormattingContext : IDisposable
OriginalSnapshot,
codeDocument,
Options,
IsFormatOnType,
AutomaticallyAddUsings,
HostDocumentIndex,
TriggerCharacter);
@ -303,7 +300,16 @@ internal sealed class FormattingContext : IDisposable
int hostDocumentIndex,
char triggerCharacter)
{
return CreateCore(uri, originalSnapshot, codeDocument, options, workspaceFactory, isFormatOnType: true, automaticallyAddUsings, hostDocumentIndex, triggerCharacter);
return new FormattingContext(
workspaceFactory,
uri,
originalSnapshot,
codeDocument,
options,
automaticallyAddUsings,
hostDocumentIndex,
triggerCharacter
);
}
public static FormattingContext Create(
@ -313,33 +319,15 @@ internal sealed class FormattingContext : IDisposable
RazorFormattingOptions options,
IAdhocWorkspaceFactory workspaceFactory)
{
return CreateCore(uri, originalSnapshot, codeDocument, options, workspaceFactory, isFormatOnType: false, automaticallyAddUsings: false, hostDocumentIndex: 0, triggerCharacter: '\0');
}
private static FormattingContext CreateCore(
Uri uri,
IDocumentSnapshot originalSnapshot,
RazorCodeDocument codeDocument,
RazorFormattingOptions options,
IAdhocWorkspaceFactory workspaceFactory,
bool isFormatOnType,
bool automaticallyAddUsings,
int hostDocumentIndex,
char triggerCharacter)
{
// hostDocumentIndex, triggerCharacter and automaticallyAddUsings are only supported in on type formatting
Debug.Assert(isFormatOnType || (hostDocumentIndex == 0 && triggerCharacter == '\0' && automaticallyAddUsings == false));
return new FormattingContext(
workspaceFactory,
uri,
originalSnapshot,
codeDocument,
options,
isFormatOnType,
automaticallyAddUsings,
hostDocumentIndex,
triggerCharacter
);
automaticallyAddUsings: false,
hostDocumentIndex: 0,
triggerCharacter: '\0'
);
}
}

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -20,17 +21,14 @@ namespace Microsoft.CodeAnalysis.Razor.Formatting;
internal sealed class CSharpFormattingPass(
IDocumentMappingService documentMappingService,
ILoggerFactory loggerFactory)
: CSharpFormattingPassBase(documentMappingService)
: CSharpFormattingPassBase(documentMappingService, isFormatOnType: false)
{
private readonly CSharpFormatter _csharpFormatter = new CSharpFormatter(documentMappingService);
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<CSharpFormattingPass>();
public async override Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
{
if (context.IsFormatOnType || result.Kind != RazorLanguageKind.Razor)
{
// We don't want to handle OnTypeFormatting here.
return result;
}
Debug.Assert(result.Kind == RazorLanguageKind.Razor);
// Apply previous edits if any.
var originalText = context.SourceText;
@ -91,7 +89,7 @@ internal sealed class CSharpFormattingPass(
// These should already be remapped.
var range = sourceText.GetRange(span);
var edits = await CSharpFormatter.FormatAsync(context, range, cancellationToken).ConfigureAwait(false);
var edits = await _csharpFormatter.FormatAsync(context, range, cancellationToken).ConfigureAwait(false);
csharpEdits.AddRange(edits.Where(e => range.Contains(e.Range)));
}

Просмотреть файл

@ -15,15 +15,15 @@ using Microsoft.CodeAnalysis.Razor.DocumentMapping;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using Range = Microsoft.VisualStudio.LanguageServer.Protocol.Range;
using RazorSyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode;
namespace Microsoft.CodeAnalysis.Razor.Formatting;
using SyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode;
internal abstract class CSharpFormattingPassBase(IDocumentMappingService documentMappingService) : IFormattingPass
internal abstract class CSharpFormattingPassBase(IDocumentMappingService documentMappingService, bool isFormatOnType) : IFormattingPass
{
private readonly bool _isFormatOnType = isFormatOnType;
protected IDocumentMappingService DocumentMappingService { get; } = documentMappingService;
protected CSharpFormatter CSharpFormatter { get; } = new CSharpFormatter(documentMappingService);
public abstract Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken);
@ -250,7 +250,7 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
if (indentations[i].StartsInHtmlContext)
{
// This is a non-C# line.
if (context.IsFormatOnType)
if (_isFormatOnType)
{
// HTML formatter doesn't run in the case of format on type.
// Let's stick with our syntax understanding of HTML to figure out the desired indentation.
@ -291,13 +291,13 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
protected static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, bool allowImplicitStatements)
=> ShouldFormat(context, mappingSpan, allowImplicitStatements, out _);
protected static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, bool allowImplicitStatements, out SyntaxNode? foundOwner)
protected static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, bool allowImplicitStatements, out RazorSyntaxNode? foundOwner)
=> ShouldFormat(context, mappingSpan, new ShouldFormatOptions(allowImplicitStatements, isLineRequest: false), out foundOwner);
private static bool ShouldFormatLine(FormattingContext context, TextSpan mappingSpan, bool allowImplicitStatements)
=> ShouldFormat(context, mappingSpan, new ShouldFormatOptions(allowImplicitStatements, isLineRequest: true), out _);
private static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, ShouldFormatOptions options, out SyntaxNode? foundOwner)
private static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, ShouldFormatOptions options, out RazorSyntaxNode? foundOwner)
{
// We should be called with the range of various C# SourceMappings.
@ -437,10 +437,10 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
return owner is MarkupTextLiteralSyntax
{
Parent: MarkupTagHelperAttributeSyntax { TagHelperAttributeInfo: { Bound: true } } or
MarkupTagHelperDirectiveAttributeSyntax { TagHelperAttributeInfo: { Bound: true } } or
MarkupMinimizedTagHelperAttributeSyntax { TagHelperAttributeInfo: { Bound: true } } or
MarkupMinimizedTagHelperDirectiveAttributeSyntax { TagHelperAttributeInfo: { Bound: true } }
Parent: MarkupTagHelperAttributeSyntax { TagHelperAttributeInfo.Bound: true } or
MarkupTagHelperDirectiveAttributeSyntax { TagHelperAttributeInfo.Bound: true } or
MarkupMinimizedTagHelperAttributeSyntax { TagHelperAttributeInfo.Bound: true } or
MarkupMinimizedTagHelperDirectiveAttributeSyntax { TagHelperAttributeInfo.Bound: true }
} && !options.IsLineRequest;
}

Просмотреть файл

@ -26,17 +26,13 @@ namespace Microsoft.CodeAnalysis.Razor.Formatting;
internal sealed class CSharpOnTypeFormattingPass(
IDocumentMappingService documentMappingService,
ILoggerFactory loggerFactory)
: CSharpFormattingPassBase(documentMappingService)
: CSharpFormattingPassBase(documentMappingService, isFormatOnType: true)
{
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<CSharpOnTypeFormattingPass>();
public async override Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
{
if (!context.IsFormatOnType || result.Kind != RazorLanguageKind.CSharp)
{
// We don't want to handle regular formatting or non-C# on type formatting here.
return result;
}
Debug.Assert(result.Kind == RazorLanguageKind.CSharp);
// Normalize and re-map the C# edits.
var codeDocument = context.CodeDocument;

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the MIT license. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -14,20 +15,34 @@ using Microsoft.VisualStudio.LanguageServer.Protocol;
namespace Microsoft.CodeAnalysis.Razor.Formatting;
internal sealed class HtmlFormattingPass(ILoggerFactory loggerFactory) : IFormattingPass
internal sealed class HtmlFormattingPass(ILoggerFactory loggerFactory) : HtmlFormattingPassBase(loggerFactory.GetOrCreateLogger<HtmlFormattingPass>())
{
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<HtmlFormattingPass>();
}
public async Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
internal sealed class HtmlOnTypeFormattingPass(ILoggerFactory loggerFactory) : HtmlFormattingPassBase(loggerFactory.GetOrCreateLogger<HtmlOnTypeFormattingPass>())
{
public override Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
{
Debug.Assert(result.Kind == RazorLanguageKind.Html);
if (result.Edits.Length == 0)
{
// There are no HTML edits for us to apply. No op.
return Task.FromResult(new FormattingResult([]));
}
return base.ExecuteAsync(context, result, cancellationToken);
}
}
internal abstract class HtmlFormattingPassBase(ILogger logger) : IFormattingPass
{
private readonly ILogger _logger = logger;
public virtual async Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
{
var originalText = context.SourceText;
if (context.IsFormatOnType && result.Kind != RazorLanguageKind.Html)
{
// We don't want to handle on type formatting requests for other languages
return result;
}
var htmlEdits = result.Edits;
var changedText = originalText;
@ -44,11 +59,6 @@ internal sealed class HtmlFormattingPass(ILoggerFactory loggerFactory) : IFormat
_logger.LogTestOnly($"After normalizedEdits:\r\n{changedText}");
}
else if (context.IsFormatOnType)
{
// There are no HTML edits for us to apply. No op.
return new FormattingResult(htmlEdits);
}
var indentationChanges = AdjustRazorIndentation(changedContext);
if (indentationChanges.Count > 0)

Просмотреть файл

@ -13,24 +13,16 @@ using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Syntax;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using RazorRazorSyntaxNodeList = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxList<Microsoft.AspNetCore.Razor.Language.Syntax.RazorSyntaxNode>;
using RazorSyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode;
using RazorSyntaxNodeList = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxList<Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode>;
namespace Microsoft.CodeAnalysis.Razor.Formatting;
using SyntaxNode = AspNetCore.Razor.Language.Syntax.SyntaxNode;
internal sealed class RazorFormattingPass : IFormattingPass
{
public async Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
{
if (context.IsFormatOnType)
{
// We don't want to handle OnTypeFormatting here.
return result;
}
// Apply previous edits if any.
var originalText = context.SourceText;
var changedText = originalText;
@ -58,7 +50,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return new FormattingResult(finalEdits);
}
private IEnumerable<TextEdit> FormatRazor(FormattingContext context, RazorSyntaxTree syntaxTree)
private static IEnumerable<TextEdit> FormatRazor(FormattingContext context, RazorSyntaxTree syntaxTree)
{
var edits = new List<TextEdit>();
var source = syntaxTree.Source;
@ -75,7 +67,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return edits;
}
private static void TryFormatBlocks(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static void TryFormatBlocks(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// We only want to run one of these
_ = TryFormatFunctionsBlock(context, edits, source, node) ||
@ -85,7 +77,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
TryFormatSectionBlock(context, edits, source, node);
}
private static bool TryFormatSectionBlock(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static bool TryFormatSectionBlock(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// @section Goo {
// }
@ -142,7 +134,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
}
}
private static bool TryFormatFunctionsBlock(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static bool TryFormatFunctionsBlock(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// @functions
// {
@ -180,7 +172,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return false;
}
private static bool TryFormatCSharpExplicitTransition(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static bool TryFormatCSharpExplicitTransition(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// We're looking for a code block like this:
//
@ -201,7 +193,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return false;
}
private static bool TryFormatComplexCSharpBlock(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static bool TryFormatComplexCSharpBlock(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// complex situations like
// @{
@ -223,7 +215,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return false;
}
private static bool TryFormatHtmlInCSharp(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static bool TryFormatHtmlInCSharp(FormattingContext context, IList<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// void Method()
// {
@ -241,7 +233,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return false;
}
private static void TryFormatCSharpBlockStructure(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static void TryFormatCSharpBlockStructure(FormattingContext context, List<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// We're looking for a code block like this:
//
@ -301,7 +293,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
}
}
private static void TryFormatSingleLineDirective(List<TextEdit> edits, RazorSourceDocument source, SyntaxNode node)
private static void TryFormatSingleLineDirective(List<TextEdit> edits, RazorSourceDocument source, RazorSyntaxNode node)
{
// Looking for single line directives like
//
@ -322,7 +314,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
}
}
static bool IsSingleLineDirective(SyntaxNode node, out RazorSyntaxNodeList children)
static bool IsSingleLineDirective(RazorSyntaxNode node, out RazorSyntaxNodeList children)
{
if (node is CSharpCodeBlockSyntax content &&
node.Parent?.Parent is RazorDirectiveSyntax directive &&
@ -337,7 +329,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
}
}
private static void FormatWhitespaceBetweenDirectiveAndBrace(SyntaxNode node, RazorDirectiveSyntax directive, List<TextEdit> edits, RazorSourceDocument source, FormattingContext context, bool forceNewLine)
private static void FormatWhitespaceBetweenDirectiveAndBrace(RazorSyntaxNode node, RazorDirectiveSyntax directive, List<TextEdit> edits, RazorSourceDocument source, FormattingContext context, bool forceNewLine)
{
if (node.ContainsOnlyWhitespace(includingNewLines: false) && !forceNewLine)
{
@ -356,7 +348,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
}
}
private static void ShrinkToSingleSpace(SyntaxNode node, List<TextEdit> edits, RazorSourceDocument source)
private static void ShrinkToSingleSpace(RazorSyntaxNode node, List<TextEdit> edits, RazorSourceDocument source)
{
// If there is anything other than one single space then we replace with one space between directive and brace.
//
@ -365,7 +357,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
edits.Add(edit);
}
private static bool FormatBlock(FormattingContext context, RazorSourceDocument source, SyntaxNode? directiveNode, SyntaxNode openBraceNode, SyntaxNode codeNode, SyntaxNode closeBraceNode, IList<TextEdit> edits)
private static bool FormatBlock(FormattingContext context, RazorSourceDocument source, RazorSyntaxNode? directiveNode, RazorSyntaxNode openBraceNode, RazorSyntaxNode codeNode, RazorSyntaxNode closeBraceNode, IList<TextEdit> edits)
{
var didFormat = false;
@ -426,7 +418,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return hasBeenModified;
}
static int GetAdditionalIndentationLevel(FormattingContext context, Range range, SyntaxNode openBraceNode, SyntaxNode codeNode)
static int GetAdditionalIndentationLevel(FormattingContext context, Range range, RazorSyntaxNode openBraceNode, RazorSyntaxNode codeNode)
{
if (!context.TryGetIndentationLevel(codeNode.Position, out var desiredIndentationLevel))
{
@ -441,7 +433,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return desiredIndentationOffset - currentIndentationOffset;
static int GetLeadingWhitespaceLength(SyntaxNode node, FormattingContext context)
static int GetLeadingWhitespaceLength(RazorSyntaxNode node, FormattingContext context)
{
var tokens = node.GetTokens();
var whitespaceLength = 0;
@ -473,7 +465,7 @@ internal sealed class RazorFormattingPass : IFormattingPass
return whitespaceLength;
}
static int GetTrailingWhitespaceLength(SyntaxNode node, FormattingContext context)
static int GetTrailingWhitespaceLength(RazorSyntaxNode node, FormattingContext context)
{
var tokens = node.GetTokens();
var whitespaceLength = 0;

Просмотреть файл

@ -26,7 +26,7 @@ internal class RazorFormattingService : IRazorFormattingService
private readonly ImmutableArray<IFormattingPass> _documentFormattingPasses;
private readonly ImmutableArray<IFormattingPass> _validationPasses;
private readonly CSharpOnTypeFormattingPass _csharpOnTypeFormattingPass;
private readonly HtmlFormattingPass _htmlFormattingPass;
private readonly HtmlOnTypeFormattingPass _htmlOnTypeFormattingPass;
public RazorFormattingService(
IDocumentMappingService documentMappingService,
@ -35,15 +35,20 @@ internal class RazorFormattingService : IRazorFormattingService
{
_workspaceFactory = workspaceFactory;
var cSharpFormattingPass = new CSharpFormattingPass(documentMappingService, loggerFactory);
var razorFormattingPass = new RazorFormattingPass();
var diagnosticValidationPass = new FormattingDiagnosticValidationPass(loggerFactory);
var contentValidationPass = new FormattingContentValidationPass(loggerFactory);
_htmlFormattingPass = new HtmlFormattingPass(loggerFactory);
_htmlOnTypeFormattingPass = new HtmlOnTypeFormattingPass(loggerFactory);
_csharpOnTypeFormattingPass = new CSharpOnTypeFormattingPass(documentMappingService, loggerFactory);
_validationPasses = [diagnosticValidationPass, contentValidationPass];
_documentFormattingPasses = [_htmlFormattingPass, razorFormattingPass, cSharpFormattingPass, .. _validationPasses];
_validationPasses =
[
new FormattingDiagnosticValidationPass(loggerFactory),
new FormattingContentValidationPass(loggerFactory)
];
_documentFormattingPasses =
[
new HtmlFormattingPass(loggerFactory),
new RazorFormattingPass(),
new CSharpFormattingPass(documentMappingService, loggerFactory),
.. _validationPasses
];
}
public async Task<TextEdit[]> GetDocumentFormattingEditsAsync(
@ -120,7 +125,7 @@ internal class RazorFormattingService : IRazorFormattingService
options,
hostDocumentIndex,
triggerCharacter,
[_htmlFormattingPass, .. _validationPasses],
[_htmlOnTypeFormattingPass, .. _validationPasses],
collapseEdits: false,
automaticallyAddUsings: false,
cancellationToken: cancellationToken);