Skip to content

Commit e019d19

Browse files
Add PooledArrayBuilder<T>.Sort(...) methods
@ToddGrun pointed out that we could add some basic `Sort(...)` methods to `PooledArrayBuilder<T>` that call into the underlying `ImmutableArray<T>.Builder`'s `Sort(...)` methods. We can use this to avoid realizing an `ImmutableArray<T>` in some cases. However, these methods don't go the extra step of trying to sort inline elements directly. Instead, they always move the inline elements to a builder.
1 parent e312417 commit e019d19

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/FunctionsDirectivePass.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Collections.Generic;
45
using Microsoft.AspNetCore.Razor.Language.Components;
56
using Microsoft.AspNetCore.Razor.Language.Intermediate;
67
using Microsoft.AspNetCore.Razor.PooledObjects;
@@ -9,6 +10,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions;
910

1011
public sealed class FunctionsDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
1112
{
13+
private static readonly Comparer<int?> s_nullableIntComparer = Comparer<int?>.Default;
14+
1215
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
1316
{
1417
var @class = documentNode.FindPrimaryClass();
@@ -27,19 +30,22 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
2730
}
2831

2932
// Now we have all the directive nodes, we want to add them to the end of the class node in document order.
30-
var orderedDirectives = directiveNodes.ToImmutableOrderedByAndClear(n => n.Node.Source?.AbsoluteIndex);
33+
// So, we sort them by their absolute index.
34+
directiveNodes.Sort(CompareAbsoluteIndices);
3135

32-
foreach (var directiveReference in orderedDirectives)
36+
foreach (var directiveReference in directiveNodes)
3337
{
3438
var node = directiveReference.Node;
35-
for (var i = 0; i < node.Children.Count; i++)
36-
{
37-
@class.Children.Add(node.Children[i]);
38-
}
39+
@class.Children.AddRange(node.Children);
3940

4041
// We don't want to keep the original directive node around anymore.
4142
// Otherwise this can cause unintended side effects in the subsequent passes.
4243
directiveReference.Remove();
4344
}
45+
46+
static int CompareAbsoluteIndices(IntermediateNodeReference n1, IntermediateNodeReference n2)
47+
{
48+
return s_nullableIntComparer.Compare(n1.Node.Source?.AbsoluteIndex, n2.Node.Source?.AbsoluteIndex);
49+
}
4450
}
4551
}

src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,20 @@ public void Dispose()
9191
}
9292
}
9393

94+
/// <summary>
95+
/// Retrieves the inner <see cref="_builder"/>, moving any inline elements to it if necessary.
96+
/// </summary>
97+
private ImmutableArray<T>.Builder GetBuilder()
98+
{
99+
if (!TryGetBuilder(out var builder))
100+
{
101+
MoveInlineItemsToBuilder();
102+
builder = _builder;
103+
}
104+
105+
return builder;
106+
}
107+
94108
/// <summary>
95109
/// Retrieves the inner <see cref="_builder"/>.
96110
/// </summary>
@@ -1611,6 +1625,33 @@ private void ShiftInlineItemsByOffset(int index, int offset)
16111625
}
16121626
}
16131627

1628+
/// <summary>
1629+
/// Sorts the contents of this builder.
1630+
/// </summary>
1631+
public void Sort()
1632+
{
1633+
var builder = GetBuilder();
1634+
builder.Sort();
1635+
}
1636+
1637+
/// <summary>
1638+
/// Sorts the contents of this builder using the provided <see cref="IComparer{T}"/>.
1639+
/// </summary>
1640+
public void Sort(IComparer<T> comparer)
1641+
{
1642+
var builder = GetBuilder();
1643+
builder.Sort(comparer);
1644+
}
1645+
1646+
/// <summary>
1647+
/// Sorts the contents of this builder using the provided <see cref="Comparison{T}"/>.
1648+
/// </summary>
1649+
public void Sort(Comparison<T> comparison)
1650+
{
1651+
var builder = GetBuilder();
1652+
builder.Sort(comparison);
1653+
}
1654+
16141655
public readonly ImmutableArray<T> ToImmutableOrdered()
16151656
{
16161657
var result = ToImmutable();

0 commit comments

Comments
 (0)