Skip to content

Commit 8256663

Browse files
authored
Merge pull request #261 from CommunityToolkit/dev/fix-build-errors-generic-generation-targets
Fix build errors with generic generation target types
2 parents 83d4ee2 + db831fc commit 8256663

File tree

5 files changed

+113
-4
lines changed

5 files changed

+113
-4
lines changed

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2828
.CreateSyntaxProvider(
2929
static (node, _) => node is ClassDeclarationSyntax,
3030
static (context, _) => (context.Node, Symbol: (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!))
31-
.Where(static item => !item.Symbol.IsAbstract && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
31+
.Where(static item => item.Symbol is { IsAbstract: false, IsGenericType: false } && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
3232
.Select(static (item, _) => item.Symbol);
3333

3434
// Get the types that inherit from ObservableValidator and gather their info

CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3131
.CreateSyntaxProvider(
3232
static (node, _) => node is ClassDeclarationSyntax,
3333
static (context, _) => (context.Node, Symbol: (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!))
34-
.Where(static item => !item.Symbol.IsAbstract && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
34+
.Where(static item => item.Symbol is { IsAbstract: false, IsGenericType: false } && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
3535
.Select(static (item, _) => item.Symbol);
3636

3737
// Get the target IRecipient<TMessage> interfaces and filter out other types

CommunityToolkit.Mvvm/ComponentModel/ObservableValidator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,8 @@ where getMethod is not null
606606
from property in validatableProperties
607607
select Expression.Call(inst0, validateMethod, new Expression[]
608608
{
609-
Expression.Convert(Expression.Call(inst0, property.GetMethod), typeof(object)),
610-
Expression.Constant(property.Name)
609+
Expression.Convert(Expression.Call(inst0, property.GetMethod), typeof(object)),
610+
Expression.Constant(property.Name)
611611
}));
612612

613613
return Expression.Lambda<Action<object>>(body, arg0).Compile();

tests/CommunityToolkit.Mvvm.UnitTests/Test_Messenger.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
67
using System.Linq;
78
using System.Reflection;
89
using System.Threading;
910
using System.Threading.Tasks;
1011
using CommunityToolkit.Mvvm.Messaging;
12+
using CommunityToolkit.Mvvm.Messaging.Messages;
1113
using Microsoft.VisualStudio.TestTools.UnitTesting;
1214

1315
namespace CommunityToolkit.Mvvm.UnitTests;
@@ -372,6 +374,40 @@ public void Test_Messenger_IRecipient_SomeMessages_NoToken(Type type)
372374
Assert.IsFalse(messenger.IsRegistered<MessageB>(recipient));
373375
}
374376

377+
// See https://github.com/CommunityToolkit/dotnet/issues/198
378+
[TestMethod]
379+
[DataRow(typeof(StrongReferenceMessenger))]
380+
[DataRow(typeof(WeakReferenceMessenger))]
381+
public void Test_Messenger_IRecipient_SomeMessages_WithGenericTypeParameters(Type type)
382+
{
383+
IMessenger? messenger = (IMessenger)Activator.CreateInstance(type)!;
384+
GenericRecipient<string> recipient = new();
385+
386+
messenger.RegisterAll(recipient);
387+
388+
Assert.IsTrue(messenger.IsRegistered<GenericRecipient<string>.Message>(recipient));
389+
Assert.IsTrue(messenger.IsRegistered<ValueChangedMessage<string>>(recipient));
390+
Assert.IsTrue(messenger.IsRegistered<MessageA>(recipient));
391+
392+
Assert.IsNull(recipient.ReceivedMessage1);
393+
Assert.IsNull(recipient.ReceivedMessage2);
394+
Assert.IsNull(recipient.ReceivedMessage3);
395+
396+
GenericRecipient<string>.Message message1 = messenger.Send(new GenericRecipient<string>.Message(new List<string> { "Hello world!" }));
397+
ValueChangedMessage<string> message2 = messenger.Send(new ValueChangedMessage<string>("Hello"));
398+
MessageA message3 = messenger.Send<MessageA>();
399+
400+
Assert.AreSame(recipient.ReceivedMessage1, message1);
401+
Assert.AreSame(recipient.ReceivedMessage2, message2);
402+
Assert.AreSame(recipient.ReceivedMessage3, message3);
403+
404+
messenger.UnregisterAll(recipient);
405+
406+
Assert.IsFalse(messenger.IsRegistered<GenericRecipient<string>.Message>(recipient));
407+
Assert.IsFalse(messenger.IsRegistered<ValueChangedMessage<string>>(recipient));
408+
Assert.IsFalse(messenger.IsRegistered<MessageA>(recipient));
409+
}
410+
375411
[TestMethod]
376412
[DataRow(typeof(StrongReferenceMessenger))]
377413
[DataRow(typeof(WeakReferenceMessenger))]
@@ -1059,4 +1095,36 @@ public sealed class MessageA
10591095
public sealed class MessageB
10601096
{
10611097
}
1098+
1099+
public partial class GenericRecipient<T> : IRecipient<GenericRecipient<T>.Message>, IRecipient<ValueChangedMessage<T>>, IRecipient<MessageA>
1100+
{
1101+
public Message? ReceivedMessage1 { get; private set; }
1102+
1103+
public ValueChangedMessage<T>? ReceivedMessage2 { get; private set; }
1104+
1105+
public MessageA? ReceivedMessage3 { get; private set; }
1106+
1107+
public void Receive(Message message)
1108+
{
1109+
ReceivedMessage1 = message;
1110+
}
1111+
1112+
public void Receive(ValueChangedMessage<T> message)
1113+
{
1114+
ReceivedMessage2 = message;
1115+
}
1116+
1117+
public void Receive(MessageA message)
1118+
{
1119+
ReceivedMessage3 = message;
1120+
}
1121+
1122+
public sealed class Message : ValueChangedMessage<List<T>>
1123+
{
1124+
public Message(List<T> list)
1125+
: base(list)
1126+
{
1127+
}
1128+
}
1129+
}
10621130
}

tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservableValidator.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,32 @@ public void Test_ObservableRecipient_AbstractTypesDoNotTriggerCodeGeneration()
539539
Assert.IsNull(createAllPropertiesValidatorMethod);
540540
}
541541

542+
// See https://github.com/CommunityToolkit/dotnet/issues/246
543+
[TestMethod]
544+
public void Test_ObservableValidator_WithGenericTypeParameters()
545+
{
546+
GenericPerson<string> model = new();
547+
548+
model.Name = "Bob";
549+
550+
model.ValidateAllProperties();
551+
552+
Assert.IsTrue(model.HasErrors);
553+
554+
ValidationResult[] errors = model.GetErrors(nameof(model.Value)).ToArray();
555+
556+
Assert.IsNotNull(errors);
557+
Assert.AreEqual(errors.Length, 1);
558+
559+
CollectionAssert.AreEqual(errors[0].MemberNames.ToArray(), new[] { nameof(model.Value) });
560+
561+
model.Value = "Ross";
562+
563+
model.ValidateAllProperties();
564+
565+
Assert.IsFalse(model.HasErrors);
566+
}
567+
542568
public class Person : ObservableValidator
543569
{
544570
private string? name;
@@ -797,4 +823,19 @@ public abstract class AbstractModelWithValidatableProperty : ObservableValidator
797823
[MinLength(2)]
798824
public string? Name { get; set; }
799825
}
826+
827+
public class GenericPerson<T> : ObservableValidator
828+
{
829+
[Required]
830+
[MinLength(1)]
831+
public string? Name { get; set; }
832+
833+
[Required]
834+
public T? Value { get; set; }
835+
836+
public new void ValidateAllProperties()
837+
{
838+
base.ValidateAllProperties();
839+
}
840+
}
800841
}

0 commit comments

Comments
 (0)