Skip to content

Commit 8dd1387

Browse files
committed
Add pooled ImmutableArrayBuilder<T> type
1 parent 1f2d63c commit 8dd1387

File tree

4 files changed

+127
-1
lines changed

4 files changed

+127
-1
lines changed

CommunityToolkit.Mvvm.SourceGenerators/CommunityToolkit.Mvvm.SourceGenerators.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeDeclarationSyntaxExtensions.cs" />
7171
<Compile Include="$(MSBuildThisFileDirectory)Helpers\Comparer{T,TSelf}.cs" />
7272
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HashCode.cs" />
73+
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ImmutableArrayBuilder{T}.cs" />
7374
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObjectPool{T}.cs" />
7475
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CanExecuteExpressionType.cs" />
7576
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CommandInfo.cs" />

CommunityToolkit.Mvvm.SourceGenerators/Extensions/DiagnosticsExtensions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// more info in ThirdPartyNotices.txt in the root of the project.
77

88
using System.Collections.Immutable;
9+
using CommunityToolkit.Mvvm.SourceGenerators.Helpers;
910
using CommunityToolkit.Mvvm.SourceGenerators.Models;
1011
using Microsoft.CodeAnalysis;
1112

@@ -32,6 +33,22 @@ public static void Add(
3233
diagnostics.Add(DiagnosticInfo.Create(descriptor, symbol, args));
3334
}
3435

36+
/// <summary>
37+
/// Adds a new diagnostics to the target builder.
38+
/// </summary>
39+
/// <param name="diagnostics">The collection of produced <see cref="DiagnosticInfo"/> instances.</param>
40+
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
41+
/// <param name="symbol">The source <see cref="ISymbol"/> to attach the diagnostics to.</param>
42+
/// <param name="args">The optional arguments for the formatted message to include.</param>
43+
public static void Add(
44+
this in ImmutableArrayBuilder<DiagnosticInfo>.Lease diagnostics,
45+
DiagnosticDescriptor descriptor,
46+
ISymbol symbol,
47+
params object[] args)
48+
{
49+
diagnostics.Add(DiagnosticInfo.Create(descriptor, symbol, args));
50+
}
51+
3552
/// <summary>
3653
/// Adds a new diagnostics to the target builder.
3754
/// </summary>
@@ -48,6 +65,22 @@ public static void Add(
4865
diagnostics.Add(DiagnosticInfo.Create(descriptor, node, args));
4966
}
5067

68+
/// <summary>
69+
/// Adds a new diagnostics to the target builder.
70+
/// </summary>
71+
/// <param name="diagnostics">The collection of produced <see cref="DiagnosticInfo"/> instances.</param>
72+
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
73+
/// <param name="node">The source <see cref="SyntaxNode"/> to attach the diagnostics to.</param>
74+
/// <param name="args">The optional arguments for the formatted message to include.</param>
75+
public static void Add(
76+
this in ImmutableArrayBuilder<DiagnosticInfo>.Lease diagnostics,
77+
DiagnosticDescriptor descriptor,
78+
SyntaxNode node,
79+
params object[] args)
80+
{
81+
diagnostics.Add(DiagnosticInfo.Create(descriptor, node, args));
82+
}
83+
5184
/// <summary>
5285
/// Registers an output node into an <see cref="IncrementalGeneratorInitializationContext"/> to output diagnostics.
5386
/// </summary>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Immutable;
7+
8+
#pragma warning disable CS0618
9+
10+
namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
11+
12+
/// <summary>
13+
/// A helper class to build <see cref="ImmutableArray{T}"/> instances with pooled buffers.
14+
/// </summary>
15+
/// <typeparam name="T">The type of items to create arrays for.</typeparam>
16+
internal static class ImmutableArrayBuilder<T>
17+
{
18+
/// <summary>
19+
/// The shared <see cref="ObjectPool{T}"/> instance to share <see cref="ImmutableArray{T}.Builder"/> objects.
20+
/// </summary>
21+
private static readonly ObjectPool<ImmutableArray<T>.Builder> objectPool = new(ImmutableArray.CreateBuilder<T>);
22+
23+
/// <summary>
24+
/// Rents a new pooled <see cref="ImmutableArray{T}.Builder"/> instance through a <see cref="Lease"/> value.
25+
/// </summary>
26+
/// <returns>A <see cref="Lease"/> to interact with the underlying <see cref="ImmutableArray{T}.Builder"/> instance.</returns>
27+
public static Lease Rent()
28+
{
29+
return new(objectPool, objectPool.Allocate());
30+
}
31+
32+
/// <summary>
33+
/// A wrapper for a pooled <see cref="ImmutableArray{T}.Builder"/> instance.
34+
/// </summary>
35+
public ref struct Lease
36+
{
37+
/// <summary>
38+
/// The owner <see cref="ObjectPool{T}"/> instance.
39+
/// </summary>
40+
private readonly ObjectPool<ImmutableArray<T>.Builder> objectPool;
41+
42+
/// <summary>
43+
/// The rented <see cref="ImmutableArray{T}.Builder"/> instance to use.
44+
/// </summary>
45+
private ImmutableArray<T>.Builder? builder;
46+
47+
/// <summary>
48+
/// Creates a new <see cref="Lease"/> object with the specified parameters.
49+
/// </summary>
50+
/// <param name="objectPool"></param>
51+
/// <param name="builder"></param>
52+
[Obsolete("Don't create instances of this type manually, use ImmutableArrayBuilder<T>.Rent() instead.")]
53+
public Lease(ObjectPool<ImmutableArray<T>.Builder> objectPool, ImmutableArray<T>.Builder builder)
54+
{
55+
this.objectPool = objectPool;
56+
this.builder = builder;
57+
}
58+
59+
/// <inheritdoc cref="ImmutableArray{T}.Builder.Count"/>
60+
public readonly int Count
61+
{
62+
get => this.builder!.Count;
63+
}
64+
65+
/// <inheritdoc cref="ImmutableArray{T}.Builder.Add(T)"/>
66+
public readonly void Add(T item)
67+
{
68+
this.builder!.Add(item);
69+
}
70+
71+
/// <inheritdoc cref="ImmutableArray{T}.Builder.ToImmutable"/>
72+
public readonly ImmutableArray<T> ToImmutable()
73+
{
74+
return this.builder!.ToImmutable();
75+
}
76+
77+
/// <inheritdoc cref="IDisposable.Dispose"/>
78+
public void Dispose()
79+
{
80+
ImmutableArray<T>.Builder? builder = this.builder;
81+
82+
this.builder = null;
83+
84+
if (builder is not null)
85+
{
86+
builder.Clear();
87+
88+
this.objectPool.Free(builder);
89+
}
90+
}
91+
}
92+
}

CommunityToolkit.Mvvm.SourceGenerators/Helpers/ObjectPool{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using System.Runtime.CompilerServices;
99
using System.Threading;
1010

11-
namespace Microsoft.CodeAnalysis.PooledObjects;
11+
namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
1212

1313
/// <summary>
1414
/// <para>

0 commit comments

Comments
 (0)