Use pooled collections in a few more spots

This commit is contained in:
David Wengier 2024-09-08 22:23:31 +10:00
Родитель f89e7f6ee9
Коммит 4e9bf4dc12
5 изменённых файлов: 23 добавлений и 21 удалений

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

@ -38,12 +38,12 @@ internal sealed class CSharpFormatter(IDocumentMappingService documentMappingSer
public static async Task<IReadOnlyDictionary<int, int>> GetCSharpIndentationAsync(
FormattingContext context,
IReadOnlyCollection<int> projectedDocumentLocations,
HashSet<int> projectedDocumentLocations,
CancellationToken cancellationToken)
{
// 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();
var filteredLocations = projectedDocumentLocations.OrderAsArray();
var indentations = await GetCSharpIndentationCoreAsync(context, filteredLocations, cancellationToken).ConfigureAwait(false);
return indentations;
@ -67,10 +67,10 @@ internal sealed class CSharpFormatter(IDocumentMappingService documentMappingSer
return changes.ToImmutableArray();
}
private static async Task<Dictionary<int, int>> GetCSharpIndentationCoreAsync(FormattingContext context, List<int> projectedDocumentLocations, CancellationToken cancellationToken)
private static async Task<Dictionary<int, int>> GetCSharpIndentationCoreAsync(FormattingContext context, ImmutableArray<int> projectedDocumentLocations, CancellationToken cancellationToken)
{
// No point calling the C# formatting if we won't be interested in any of its work anyway
if (projectedDocumentLocations.Count == 0)
if (projectedDocumentLocations.Length == 0)
{
return [];
}

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

@ -54,7 +54,7 @@ internal sealed class CSharpFormattingPass(
cancellationToken.ThrowIfCancellationRequested();
var indentationChanges = await AdjustIndentationAsync(changedContext, cancellationToken).ConfigureAwait(false);
if (indentationChanges.Count > 0)
if (indentationChanges.Length > 0)
{
// Apply the edits that modify indentation.
changedText = changedText.WithChanges(indentationChanges);

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

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Components;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Syntax;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServer.Protocol;
@ -28,7 +29,7 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
public abstract Task<ImmutableArray<TextChange>> ExecuteAsync(FormattingContext context, ImmutableArray<TextChange> changes, CancellationToken cancellationToken);
protected async Task<List<TextChange>> AdjustIndentationAsync(FormattingContext context, CancellationToken cancellationToken, Range? range = null)
protected async Task<ImmutableArray<TextChange>> AdjustIndentationAsync(FormattingContext context, CancellationToken cancellationToken, Range? range = null)
{
// In this method, the goal is to make final adjustments to the indentation of each line.
// We will take into account the following,
@ -46,7 +47,7 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
// Due to perf concerns, we only want to invoke the real C# formatter once.
// So, let's collect all the significant locations that we want to obtain the CSharpDesiredIndentations for.
var significantLocations = new HashSet<int>();
using var _1 = HashSetPool<int>.GetPooledObject(out var significantLocations);
// First, collect all the locations at the beginning and end of each source mapping.
var sourceMappingMap = new Dictionary<int, int>();
@ -276,7 +277,7 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
}
// Now that we have collected all the indentations for each line, let's convert them to text edits.
var changes = new List<TextChange>();
using var changes = new PooledArrayBuilder<TextChange>(capacity: newIndentations.Count);
foreach (var item in newIndentations)
{
var line = item.Key;
@ -289,7 +290,7 @@ internal abstract class CSharpFormattingPassBase(IDocumentMappingService documen
changes.Add(new TextChange(spanToReplace, effectiveDesiredIndentation));
}
return changes;
return changes.DrainToImmutable();
}
protected static bool ShouldFormat(FormattingContext context, TextSpan mappingSpan, bool allowImplicitStatements)

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

@ -181,7 +181,7 @@ internal sealed class CSharpOnTypeFormattingPass(
Debug.Assert(cleanedText.IsValidPosition(rangeToAdjust.End), "Invalid range. This is unexpected.");
var indentationChanges = await AdjustIndentationAsync(changedContext, cancellationToken, rangeToAdjust).ConfigureAwait(false);
if (indentationChanges.Count > 0)
if (indentationChanges.Length > 0)
{
// Apply the edits that modify indentation.
cleanedText = cleanedText.WithChanges(indentationChanges);
@ -277,13 +277,13 @@ internal sealed class CSharpOnTypeFormattingPass(
return delta;
}
private static List<TextChange> CleanupDocument(FormattingContext context, Range? range = null)
private static ImmutableArray<TextChange> CleanupDocument(FormattingContext context, Range? range = null)
{
var text = context.SourceText;
range ??= text.GetRange(TextSpan.FromBounds(0, text.Length));
var csharpDocument = context.CodeDocument.GetCSharpDocument();
var changes = new List<TextChange>();
using var changes = new PooledArrayBuilder<TextChange>();
foreach (var mapping in csharpDocument.SourceMappings)
{
var mappingSpan = new TextSpan(mapping.OriginalSpan.AbsoluteIndex, mapping.OriginalSpan.Length);
@ -294,15 +294,15 @@ internal sealed class CSharpOnTypeFormattingPass(
continue;
}
CleanupSourceMappingStart(context, mappingRange, changes, out var newLineAdded);
CleanupSourceMappingStart(context, mappingRange, ref changes.AsRef(), out var newLineAdded);
CleanupSourceMappingEnd(context, mappingRange, changes, newLineAdded);
CleanupSourceMappingEnd(context, mappingRange, ref changes.AsRef(), newLineAdded);
}
return changes;
return changes.ToImmutable();
}
private static void CleanupSourceMappingStart(FormattingContext context, Range sourceMappingRange, List<TextChange> changes, out bool newLineAdded)
private static void CleanupSourceMappingStart(FormattingContext context, Range sourceMappingRange, ref PooledArrayBuilder<TextChange> changes, out bool newLineAdded)
{
newLineAdded = false;
@ -425,7 +425,7 @@ internal sealed class CSharpOnTypeFormattingPass(
return builder.ToString();
}
private static void CleanupSourceMappingEnd(FormattingContext context, Range sourceMappingRange, List<TextChange> changes, bool newLineWasAddedAtStart)
private static void CleanupSourceMappingEnd(FormattingContext context, Range sourceMappingRange, ref PooledArrayBuilder<TextChange> changes, bool newLineWasAddedAtStart)
{
//
// We look through every source mapping that intersects with the affected range and

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

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Syntax;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.Razor.Logging;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServer.Protocol;
@ -37,7 +38,7 @@ internal abstract class HtmlFormattingPassBase(ILogger logger) : IFormattingPass
}
var indentationChanges = AdjustRazorIndentation(changedContext);
if (indentationChanges.Count > 0)
if (indentationChanges.Length > 0)
{
// Apply the edits that adjust indentation.
changedText = changedText.WithChanges(indentationChanges);
@ -49,15 +50,15 @@ internal abstract class HtmlFormattingPassBase(ILogger logger) : IFormattingPass
return finalChanges.ToImmutableArray();
}
private static List<TextChange> AdjustRazorIndentation(FormattingContext context)
private static ImmutableArray<TextChange> AdjustRazorIndentation(FormattingContext context)
{
// Assume HTML formatter has already run at this point and HTML is relatively indented correctly.
// But HTML doesn't know about Razor blocks.
// Our goal here is to indent each line according to the surrounding Razor blocks.
var sourceText = context.SourceText;
var editsToApply = new List<TextChange>();
var indentations = context.GetIndentations();
using var editsToApply = new PooledArrayBuilder<TextChange>(capacity: sourceText.Lines.Count);
for (var i = 0; i < sourceText.Lines.Count; i++)
{
var line = sourceText.Lines[i];
@ -163,7 +164,7 @@ internal abstract class HtmlFormattingPassBase(ILogger logger) : IFormattingPass
}
}
return editsToApply;
return editsToApply.DrainToImmutable();
}
private static bool IsPartOfHtmlTag(FormattingContext context, int position)