Skip to content

Commit 1a24e0d

Browse files
committed
Optimize duplicates removal in IMessengerRegisterAllGenerator
1 parent 8544995 commit 1a24e0d

File tree

2 files changed

+13
-32
lines changed

2 files changed

+13
-32
lines changed

CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,32 @@ public sealed partial class IMessengerRegisterAllGenerator : IIncrementalGenerat
2323
/// <inheritdoc/>
2424
public void Initialize(IncrementalGeneratorInitializationContext context)
2525
{
26-
// Get all class declarations
26+
// Get all class declarations. This pipeline step also needs to filter out duplicate recipient
27+
// definitions (it might happen if a recipient has partial declarations). To do this, all pairs
28+
// of class declarations and associated symbols are gathered, and then only the pair where the
29+
// class declaration is the first syntax reference for the associated symbol is kept.
2730
IncrementalValuesProvider<INamedTypeSymbol> typeSymbols =
2831
context.SyntaxProvider
2932
.CreateSyntaxProvider(
30-
static (node, _) => node is ClassDeclarationSyntax { BaseList.Types.Count: > 0 },
31-
static (context, _) => (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
33+
static (node, _) => node is ClassDeclarationSyntax,
34+
static (context, _) => (context.Node, Symbol: (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!))
35+
.Where(static item =>
36+
item.Symbol.DeclaringSyntaxReferences.Length > 0 &&
37+
item.Symbol.DeclaringSyntaxReferences[0] is SyntaxReference syntaxReference &&
38+
syntaxReference.SyntaxTree == item.Node.SyntaxTree &&
39+
syntaxReference.Span == item.Node.Span)
40+
.Select(static (item, _) => item.Symbol);
3241

3342
// Get the target IRecipient<TMessage> interfaces and filter out other types
3443
IncrementalValuesProvider<(INamedTypeSymbol Type, ImmutableArray<INamedTypeSymbol> Interfaces)> typeAndInterfaceSymbols =
3544
typeSymbols
3645
.Select(static (item, _) => (item, Interfaces: Execute.GetInterfaces(item)))
3746
.Where(static item => !item.Interfaces.IsEmpty);
3847

39-
// Get the recipient info for all target types. This pipeline step also needs to filter out
40-
// duplicate recipient definitions (it might happen if a recipient has partial declarations)
48+
// Get the recipient info for all target types
4149
IncrementalValuesProvider<RecipientInfo> recipientInfo =
4250
typeAndInterfaceSymbols
4351
.Select(static (item, _) => Execute.GetInfo(item.Type, item.Interfaces))
44-
.WithComparer(RecipientInfo.Comparer.Default)
45-
.Collect()
46-
.Select(static (item, _) => item.Distinct(RecipientInfo.EqualityComparerByFilenameHint))
47-
.SelectMany(static (item, _) => item)
4852
.WithComparer(RecipientInfo.Comparer.Default);
4953

5054
// Check whether the header file is needed

CommunityToolkit.Mvvm.SourceGenerators/Messaging/Models/RecipientInfo.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ internal sealed record RecipientInfo(
2222
string TypeName,
2323
ImmutableArray<string> MessageTypes)
2424
{
25-
/// <summary>
26-
/// Gets an <see cref="IEqualityComparer{T}"/> implementation only matching by <see cref="FilenameHint"/>.
27-
/// </summary>
28-
public static IEqualityComparer<RecipientInfo> EqualityComparerByFilenameHint { get; } = new FilenameHintComparer();
29-
3025
/// <summary>
3126
/// An <see cref="IEqualityComparer{T}"/> implementation for <see cref="RecipientInfo"/>.
3227
/// </summary>
@@ -49,22 +44,4 @@ protected override bool AreEqual(RecipientInfo x, RecipientInfo y)
4944
x.MessageTypes.SequenceEqual(y.MessageTypes);
5045
}
5146
}
52-
53-
/// <summary>
54-
/// An <see cref="IEqualityComparer{T}"/> implementation only matching by <see cref="FilenameHint"/>.
55-
/// </summary>
56-
private sealed class FilenameHintComparer : IEqualityComparer<RecipientInfo>
57-
{
58-
/// <inheritdoc/>
59-
public bool Equals(RecipientInfo x, RecipientInfo y)
60-
{
61-
return x.FilenameHint == y.FilenameHint;
62-
}
63-
64-
/// <inheritdoc/>
65-
public int GetHashCode(RecipientInfo obj)
66-
{
67-
return obj.FilenameHint.GetHashCode();
68-
}
69-
}
7047
}

0 commit comments

Comments
 (0)