Skip to content

Commit 820a55e

Browse files
authored
Merge pull request #469 from CommunityToolkit/dev/equatable-array
Add and use new EquatableArray<T> type in source generators
2 parents 39290dc + d033938 commit 820a55e

22 files changed

+264
-1139
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\INotifyPropertyChangedInfo.cs" />
3939
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\ObservableRecipientInfo.cs" />
4040
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\PropertyInfo.cs" />
41-
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\TypedConstantInfo.Comparer.cs" />
4241
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\TypedConstantInfo.cs" />
4342
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\TypedConstantInfo.Factory.cs" />
4443
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Models\ValidationInfo.cs" />
@@ -58,8 +57,6 @@
5857
<Compile Include="$(MSBuildThisFileDirectory)Extensions\AttributeDataExtensions.cs" />
5958
<Compile Include="$(MSBuildThisFileDirectory)Extensions\CompilationExtensions.cs" />
6059
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DiagnosticsExtensions.cs" />
61-
<Compile Include="$(MSBuildThisFileDirectory)Extensions\HashCodeExtensions.cs" />
62-
<Compile Include="$(MSBuildThisFileDirectory)Extensions\IEqualityComparerExtensions.cs" />
6360
<Compile Include="$(MSBuildThisFileDirectory)Extensions\INamedTypeSymbolExtensions.cs" />
6461
<Compile Include="$(MSBuildThisFileDirectory)Extensions\IncrementalGeneratorInitializationContextExtensions.cs" />
6562
<Compile Include="$(MSBuildThisFileDirectory)Extensions\IncrementalValuesProviderExtensions.cs" />
@@ -68,7 +65,7 @@
6865
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.cs" />
6966
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.cs" />
7067
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeDeclarationSyntaxExtensions.cs" />
71-
<Compile Include="$(MSBuildThisFileDirectory)Helpers\Comparer{T,TSelf}.cs" />
68+
<Compile Include="$(MSBuildThisFileDirectory)Helpers\EquatableArray{T}.cs" />
7269
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HashCode.cs" />
7370
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ImmutableArrayBuilder{T}.cs" />
7471
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObjectPool{T}.cs" />

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/Models/AttributeInfo.cs

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models;
2020
/// </summary>
2121
internal sealed record AttributeInfo(
2222
string TypeName,
23-
ImmutableArray<TypedConstantInfo> ConstructorArgumentInfo,
24-
ImmutableArray<(string Name, TypedConstantInfo Value)> NamedArgumentInfo)
23+
EquatableArray<TypedConstantInfo> ConstructorArgumentInfo,
24+
EquatableArray<(string Name, TypedConstantInfo Value)> NamedArgumentInfo)
2525
{
2626
/// <summary>
2727
/// Creates a new <see cref="AttributeInfo"/> instance from a given <see cref="AttributeData"/> value.
@@ -114,50 +114,5 @@ public AttributeSyntax GetSyntax()
114114
.WithNameEquals(NameEquals(IdentifierName(arg.Name))));
115115

116116
return Attribute(IdentifierName(TypeName), AttributeArgumentList(SeparatedList(arguments.Concat(namedArguments))));
117-
118-
}
119-
120-
/// <summary>
121-
/// An <see cref="IEqualityComparer{T}"/> implementation for <see cref="AttributeInfo"/>.
122-
/// </summary>
123-
public sealed class Comparer : Comparer<AttributeInfo, Comparer>
124-
{
125-
/// <inheritdoc/>
126-
protected override void AddToHashCode(ref HashCode hashCode, AttributeInfo obj)
127-
{
128-
hashCode.Add(obj.TypeName);
129-
hashCode.AddRange(obj.ConstructorArgumentInfo, TypedConstantInfo.Comparer.Default);
130-
131-
foreach ((string key, TypedConstantInfo value) in obj.NamedArgumentInfo)
132-
{
133-
hashCode.Add(key);
134-
hashCode.Add(value, TypedConstantInfo.Comparer.Default);
135-
}
136-
}
137-
138-
/// <inheritdoc/>
139-
protected override bool AreEqual(AttributeInfo x, AttributeInfo y)
140-
{
141-
if (x.TypeName != y.TypeName ||
142-
!x.ConstructorArgumentInfo.SequenceEqual(y.ConstructorArgumentInfo, TypedConstantInfo.Comparer.Default) ||
143-
x.NamedArgumentInfo.Length != y.NamedArgumentInfo.Length)
144-
{
145-
return false;
146-
}
147-
148-
for (int i = 0; i < x.NamedArgumentInfo.Length; i++)
149-
{
150-
(string Name, TypedConstantInfo Value) left = x.NamedArgumentInfo[i];
151-
(string Name, TypedConstantInfo Value) right = y.NamedArgumentInfo[i];
152-
153-
if (left.Name != right.Name ||
154-
!TypedConstantInfo.Comparer.Default.Equals(left.Value, right.Value))
155-
{
156-
return false;
157-
}
158-
}
159-
160-
return true;
161-
}
162117
}
163118
}

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/Models/PropertyInfo.cs

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,45 +27,9 @@ internal sealed record PropertyInfo(
2727
string TypeNameWithNullabilityAnnotations,
2828
string FieldName,
2929
string PropertyName,
30-
ImmutableArray<string> PropertyChangingNames,
31-
ImmutableArray<string> PropertyChangedNames,
32-
ImmutableArray<string> NotifiedCommandNames,
30+
EquatableArray<string> PropertyChangingNames,
31+
EquatableArray<string> PropertyChangedNames,
32+
EquatableArray<string> NotifiedCommandNames,
3333
bool NotifyPropertyChangedRecipients,
3434
bool NotifyDataErrorInfo,
35-
ImmutableArray<AttributeInfo> ForwardedAttributes)
36-
{
37-
/// <summary>
38-
/// An <see cref="IEqualityComparer{T}"/> implementation for <see cref="PropertyInfo"/>.
39-
/// </summary>
40-
public sealed class Comparer : Comparer<PropertyInfo, Comparer>
41-
{
42-
/// <inheritdoc/>
43-
protected override void AddToHashCode(ref HashCode hashCode, PropertyInfo obj)
44-
{
45-
hashCode.Add(obj.TypeNameWithNullabilityAnnotations);
46-
hashCode.Add(obj.FieldName);
47-
hashCode.Add(obj.PropertyName);
48-
hashCode.AddRange(obj.PropertyChangingNames);
49-
hashCode.AddRange(obj.PropertyChangedNames);
50-
hashCode.AddRange(obj.NotifiedCommandNames);
51-
hashCode.Add(obj.NotifyPropertyChangedRecipients);
52-
hashCode.Add(obj.NotifyDataErrorInfo);
53-
hashCode.AddRange(obj.ForwardedAttributes, AttributeInfo.Comparer.Default);
54-
}
55-
56-
/// <inheritdoc/>
57-
protected override bool AreEqual(PropertyInfo x, PropertyInfo y)
58-
{
59-
return
60-
x.TypeNameWithNullabilityAnnotations == y.TypeNameWithNullabilityAnnotations &&
61-
x.FieldName == y.FieldName &&
62-
x.PropertyName == y.PropertyName &&
63-
x.PropertyChangingNames.SequenceEqual(y.PropertyChangingNames) &&
64-
x.PropertyChangedNames.SequenceEqual(y.PropertyChangedNames) &&
65-
x.NotifiedCommandNames.SequenceEqual(y.NotifiedCommandNames) &&
66-
x.NotifyPropertyChangedRecipients == y.NotifyPropertyChangedRecipients &&
67-
x.NotifyDataErrorInfo == y.NotifyDataErrorInfo &&
68-
x.ForwardedAttributes.SequenceEqual(y.ForwardedAttributes, AttributeInfo.Comparer.Default);
69-
}
70-
}
71-
}
35+
EquatableArray<AttributeInfo> ForwardedAttributes);

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/Models/TypedConstantInfo.Comparer.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/Models/TypedConstantInfo.cs

Lines changed: 2 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Immutable;
77
using System.Linq;
8+
using CommunityToolkit.Mvvm.SourceGenerators.Helpers;
89
using Microsoft.CodeAnalysis;
910
using Microsoft.CodeAnalysis.CSharp;
1011
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -24,26 +25,12 @@ internal abstract partial record TypedConstantInfo
2425
/// <returns>The <see cref="ExpressionSyntax"/> instance representing the current constant.</returns>
2526
public abstract ExpressionSyntax GetSyntax();
2627

27-
/// <summary>
28-
/// Checks whether the current instance is the same as an input one.
29-
/// </summary>
30-
/// <param name="other">The <see cref="TypedConstantInfo"/> instance to compare to.</param>
31-
/// <returns>Whether or not the two instances are the same.</returns>
32-
/// <remarks>This method differs from <see cref="Equals(TypedConstantInfo?)"/> in that it checks for deep equality.</remarks>
33-
protected abstract bool IsEqualTo(TypedConstantInfo other);
34-
35-
/// <summary>
36-
/// Adds the current instance to an incremental <see cref="HashCode"/> value.
37-
/// </summary>
38-
/// <param name="hashCode">The target <see cref="HashCode"/> value.</param>
39-
protected abstract void AddToHashCode(ref HashCode hashCode);
40-
4128
/// <summary>
4229
/// A <see cref="TypedConstantInfo"/> type representing an array.
4330
/// </summary>
4431
/// <param name="ElementTypeName">The type name for array elements.</param>
4532
/// <param name="Items">The sequence of contained elements.</param>
46-
public sealed record Array(string ElementTypeName, ImmutableArray<TypedConstantInfo> Items) : TypedConstantInfo
33+
public sealed record Array(string ElementTypeName, EquatableArray<TypedConstantInfo> Items) : TypedConstantInfo
4734
{
4835
/// <inheritdoc/>
4936
public override ExpressionSyntax GetSyntax()
@@ -55,38 +42,6 @@ public override ExpressionSyntax GetSyntax()
5542
.WithInitializer(InitializerExpression(SyntaxKind.ArrayInitializerExpression)
5643
.AddExpressions(Items.Select(static c => c.GetSyntax()).ToArray()));
5744
}
58-
59-
/// <inheritdoc/>
60-
protected override bool IsEqualTo(TypedConstantInfo other)
61-
{
62-
if (other is Array array &&
63-
ElementTypeName == array.ElementTypeName &&
64-
Items.Length == array.Items.Length)
65-
{
66-
for (int i = 0; i < Items.Length; i++)
67-
{
68-
if (!Items[i].IsEqualTo(array.Items[i]))
69-
{
70-
return false;
71-
}
72-
}
73-
74-
return true;
75-
}
76-
77-
return false;
78-
}
79-
80-
/// <inheritdoc/>
81-
protected override void AddToHashCode(ref HashCode hashCode)
82-
{
83-
hashCode.Add(ElementTypeName);
84-
85-
foreach (TypedConstantInfo item in Items)
86-
{
87-
item.AddToHashCode(ref hashCode);
88-
}
89-
}
9045
}
9146

9247
/// <summary>
@@ -105,20 +60,6 @@ public override ExpressionSyntax GetSyntax()
10560
{
10661
return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(Value));
10762
}
108-
109-
/// <inheritdoc/>
110-
protected override bool IsEqualTo(TypedConstantInfo other)
111-
{
112-
return
113-
other is String @string &&
114-
Value == @string.Value;
115-
}
116-
117-
/// <inheritdoc/>
118-
protected override void AddToHashCode(ref HashCode hashCode)
119-
{
120-
hashCode.Add(Value);
121-
}
12263
}
12364

12465
/// <summary>
@@ -132,20 +73,6 @@ public override ExpressionSyntax GetSyntax()
13273
{
13374
return LiteralExpression(Value ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression);
13475
}
135-
136-
/// <inheritdoc/>
137-
protected override bool IsEqualTo(TypedConstantInfo other)
138-
{
139-
return
140-
other is Boolean @bool &&
141-
Value == @bool.Value;
142-
}
143-
144-
/// <inheritdoc/>
145-
protected override void AddToHashCode(ref HashCode hashCode)
146-
{
147-
hashCode.Add(Value);
148-
}
14976
}
15077

15178
/// <summary>
@@ -175,20 +102,6 @@ public override ExpressionSyntax GetSyntax()
175102
_ => throw new ArgumentException("Invalid primitive type")
176103
});
177104
}
178-
179-
/// <inheritdoc/>
180-
protected override bool IsEqualTo(TypedConstantInfo other)
181-
{
182-
return
183-
other is Of<T> box &&
184-
Value.Equals(box.Value);
185-
}
186-
187-
/// <inheritdoc/>
188-
protected override void AddToHashCode(ref HashCode hashCode)
189-
{
190-
hashCode.Add(Value);
191-
}
192105
}
193106
}
194107

@@ -203,20 +116,6 @@ public override ExpressionSyntax GetSyntax()
203116
{
204117
return TypeOfExpression(IdentifierName(TypeName));
205118
}
206-
207-
/// <inheritdoc/>
208-
protected override bool IsEqualTo(TypedConstantInfo other)
209-
{
210-
return
211-
other is Type type &&
212-
TypeName == type.TypeName;
213-
}
214-
215-
/// <inheritdoc/>
216-
protected override void AddToHashCode(ref HashCode hashCode)
217-
{
218-
hashCode.Add(TypeName);
219-
}
220119
}
221120

222121
/// <summary>
@@ -234,22 +133,6 @@ public override ExpressionSyntax GetSyntax()
234133
IdentifierName(TypeName),
235134
LiteralExpression(SyntaxKind.NumericLiteralExpression, ParseToken(Value.ToString())));
236135
}
237-
238-
/// <inheritdoc/>
239-
protected override bool IsEqualTo(TypedConstantInfo other)
240-
{
241-
return
242-
other is Enum @enum &&
243-
TypeName == @enum.TypeName &&
244-
Value.Equals(@enum.Value);
245-
}
246-
247-
/// <inheritdoc/>
248-
protected override void AddToHashCode(ref HashCode hashCode)
249-
{
250-
hashCode.Add(TypeName);
251-
hashCode.Add(Value);
252-
}
253136
}
254137

255138
/// <summary>
@@ -262,17 +145,5 @@ public override ExpressionSyntax GetSyntax()
262145
{
263146
return LiteralExpression(SyntaxKind.NullLiteralExpression);
264147
}
265-
266-
/// <inheritdoc/>
267-
protected override bool IsEqualTo(TypedConstantInfo other)
268-
{
269-
return other is Null;
270-
}
271-
272-
/// <inheritdoc/>
273-
protected override void AddToHashCode(ref HashCode hashCode)
274-
{
275-
hashCode.Add((object?)null);
276-
}
277148
}
278149
}

0 commit comments

Comments
 (0)